ActivityManagerService.java revision 9c6e8ced9b6913657f48c38c208b1b594500c0e1
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.ProcessStats;
30import com.android.internal.app.SystemUserHomeActivity;
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.server.AppOpsService;
44import com.android.server.AttributeCache;
45import com.android.server.DeviceIdleController;
46import com.android.server.IntentResolver;
47import com.android.server.LocalServices;
48import com.android.server.LockGuard;
49import com.android.server.ServiceThread;
50import com.android.server.SystemService;
51import com.android.server.SystemServiceManager;
52import com.android.server.Watchdog;
53import com.android.server.am.ActivityStack.ActivityState;
54import com.android.server.firewall.IntentFirewall;
55import com.android.server.pm.Installer;
56import com.android.server.statusbar.StatusBarManagerInternal;
57import com.android.server.vr.VrManagerInternal;
58import com.android.server.wm.AppTransition;
59import com.android.server.wm.WindowManagerService;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
65import android.Manifest;
66import android.annotation.UserIdInt;
67import android.app.Activity;
68import android.app.ActivityManager;
69import android.app.ActivityManager.RunningTaskInfo;
70import android.app.ActivityManager.StackId;
71import android.app.ActivityManager.StackInfo;
72import android.app.ActivityManager.TaskThumbnailInfo;
73import android.app.ActivityManagerInternal;
74import android.app.ActivityManagerInternal.SleepToken;
75import android.app.ActivityManagerNative;
76import android.app.ActivityOptions;
77import android.app.ActivityThread;
78import android.app.AlertDialog;
79import android.app.AppGlobals;
80import android.app.AppOpsManager;
81import android.app.ApplicationErrorReport;
82import android.app.ApplicationThreadNative;
83import android.app.BroadcastOptions;
84import android.app.Dialog;
85import android.app.IActivityContainer;
86import android.app.IActivityContainerCallback;
87import android.app.IActivityController;
88import android.app.IAppTask;
89import android.app.IApplicationThread;
90import android.app.IInstrumentationWatcher;
91import android.app.INotificationManager;
92import android.app.IProcessObserver;
93import android.app.IServiceConnection;
94import android.app.IStopUserCallback;
95import android.app.ITaskStackListener;
96import android.app.IUiAutomationConnection;
97import android.app.IUidObserver;
98import android.app.IUserSwitchObserver;
99import android.app.Instrumentation;
100import android.app.Notification;
101import android.app.NotificationManager;
102import android.app.PendingIntent;
103import android.app.ProfilerInfo;
104import android.app.admin.DevicePolicyManager;
105import android.app.admin.DevicePolicyManagerInternal;
106import android.app.admin.IDevicePolicyManager;
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.Looper;
171import android.os.Message;
172import android.os.Parcel;
173import android.os.ParcelFileDescriptor;
174import android.os.PersistableBundle;
175import android.os.PowerManager;
176import android.os.PowerManagerInternal;
177import android.os.Process;
178import android.os.RemoteCallbackList;
179import android.os.RemoteException;
180import android.os.ResultReceiver;
181import android.os.ServiceManager;
182import android.os.StrictMode;
183import android.os.SystemClock;
184import android.os.SystemProperties;
185import android.os.Trace;
186import android.os.TransactionTooLargeException;
187import android.os.UpdateLock;
188import android.os.UserHandle;
189import android.os.UserManager;
190import android.os.WorkSource;
191import android.os.storage.IMountService;
192import android.os.storage.MountServiceInternal;
193import android.os.storage.StorageManager;
194import android.provider.Settings;
195import android.service.voice.IVoiceInteractionSession;
196import android.service.voice.VoiceInteractionManagerInternal;
197import android.service.voice.VoiceInteractionSession;
198import android.text.format.DateUtils;
199import android.text.format.Time;
200import android.util.ArrayMap;
201import android.util.ArraySet;
202import android.util.AtomicFile;
203import android.util.DebugUtils;
204import android.util.EventLog;
205import android.util.LocaleList;
206import android.util.Log;
207import android.util.Pair;
208import android.util.PrintWriterPrinter;
209import android.util.Slog;
210import android.util.SparseArray;
211import android.util.TimeUtils;
212import android.util.Xml;
213import android.view.Display;
214import android.view.Gravity;
215import android.view.LayoutInflater;
216import android.view.View;
217import android.view.WindowManager;
218
219import java.io.BufferedInputStream;
220import java.io.BufferedOutputStream;
221import java.io.DataInputStream;
222import java.io.DataOutputStream;
223import java.io.File;
224import java.io.FileDescriptor;
225import java.io.FileInputStream;
226import java.io.FileNotFoundException;
227import java.io.FileOutputStream;
228import java.io.IOException;
229import java.io.InputStreamReader;
230import java.io.PrintWriter;
231import java.io.StringWriter;
232import java.lang.ref.WeakReference;
233import java.nio.charset.StandardCharsets;
234import java.util.ArrayList;
235import java.util.Arrays;
236import java.util.Collections;
237import java.util.Comparator;
238import java.util.HashMap;
239import java.util.HashSet;
240import java.util.Iterator;
241import java.util.List;
242import java.util.Locale;
243import java.util.Map;
244import java.util.Set;
245import java.util.concurrent.atomic.AtomicBoolean;
246import java.util.concurrent.atomic.AtomicLong;
247
248import dalvik.system.VMRuntime;
249
250import libcore.io.IoUtils;
251import libcore.util.EmptyArray;
252
253import static android.Manifest.permission.INTERACT_ACROSS_USERS;
254import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
255import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
256import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
257import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
258import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
259import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
260import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
261import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
262import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
263import static android.app.ActivityManager.StackId.HOME_STACK_ID;
264import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
265import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
266import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
267import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
268import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
269import static android.content.pm.PackageManager.GET_PROVIDERS;
270import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
271import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
272import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
273import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
274import static android.content.pm.PackageManager.PERMISSION_GRANTED;
275import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
276import static android.provider.Settings.Global.DEBUG_APP;
277import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
278import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
279import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
280import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
281import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
282import static android.provider.Settings.System.FONT_SCALE;
283import static com.android.internal.util.XmlUtils.readBooleanAttribute;
284import static com.android.internal.util.XmlUtils.readIntAttribute;
285import static com.android.internal.util.XmlUtils.readLongAttribute;
286import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
287import static com.android.internal.util.XmlUtils.writeIntAttribute;
288import static com.android.internal.util.XmlUtils.writeLongAttribute;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
345import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
346import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
347import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
348import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
349import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
350import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
351import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
352import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
353import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
354import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
355import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
356import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
357import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
358import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
359import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
360import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
361import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
362import static org.xmlpull.v1.XmlPullParser.START_TAG;
363
364public final class ActivityManagerService extends ActivityManagerNative
365        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
366
367    // File that stores last updated system version and called preboot receivers
368    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
369
370    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
371    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
372    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
373    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
374    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
375    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
376    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
377    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
378    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
379    private static final String TAG_LRU = TAG + POSTFIX_LRU;
380    private static final String TAG_MU = TAG + POSTFIX_MU;
381    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
382    private static final String TAG_POWER = TAG + POSTFIX_POWER;
383    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
384    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
385    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
386    private static final String TAG_PSS = TAG + POSTFIX_PSS;
387    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
388    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
389    private static final String TAG_STACK = TAG + POSTFIX_STACK;
390    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
391    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
392    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
393    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
394    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
395
396    /** Control over CPU and battery monitoring */
397    // write battery stats every 30 minutes.
398    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
399    static final boolean MONITOR_CPU_USAGE = true;
400    // don't sample cpu less than every 5 seconds.
401    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
402    // wait possibly forever for next cpu sample.
403    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
404    static final boolean MONITOR_THREAD_CPU_USAGE = false;
405
406    // The flags that are set for all calls we make to the package manager.
407    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
408
409    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
410
411    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
412
413    // Amount of time after a call to stopAppSwitches() during which we will
414    // prevent further untrusted switches from happening.
415    static final long APP_SWITCH_DELAY_TIME = 5*1000;
416
417    // How long we wait for a launched process to attach to the activity manager
418    // before we decide it's never going to come up for real.
419    static final int PROC_START_TIMEOUT = 10*1000;
420    // How long we wait for an attached process to publish its content providers
421    // before we decide it must be hung.
422    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
423
424    // How long we will retain processes hosting content providers in the "last activity"
425    // state before allowing them to drop down to the regular cached LRU list.  This is
426    // to avoid thrashing of provider processes under low memory situations.
427    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
428
429    // How long we wait for a launched process to attach to the activity manager
430    // before we decide it's never going to come up for real, when the process was
431    // started with a wrapper for instrumentation (such as Valgrind) because it
432    // could take much longer than usual.
433    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
434
435    // How long to wait after going idle before forcing apps to GC.
436    static final int GC_TIMEOUT = 5*1000;
437
438    // The minimum amount of time between successive GC requests for a process.
439    static final int GC_MIN_INTERVAL = 60*1000;
440
441    // The minimum amount of time between successive PSS requests for a process.
442    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
443
444    // The minimum amount of time between successive PSS requests for a process
445    // when the request is due to the memory state being lowered.
446    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
447
448    // The rate at which we check for apps using excessive power -- 15 mins.
449    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
450
451    // The minimum sample duration we will allow before deciding we have
452    // enough data on wake locks to start killing things.
453    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
454
455    // The minimum sample duration we will allow before deciding we have
456    // enough data on CPU usage to start killing things.
457    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
458
459    // How long we allow a receiver to run before giving up on it.
460    static final int BROADCAST_FG_TIMEOUT = 10*1000;
461    static final int BROADCAST_BG_TIMEOUT = 60*1000;
462
463    // How long we wait until we timeout on key dispatching.
464    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
465
466    // How long we wait until we timeout on key dispatching during instrumentation.
467    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
468
469    // This is the amount of time an app needs to be running a foreground service before
470    // we will consider it to be doing interaction for usage stats.
471    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
472
473    // Maximum amount of time we will allow to elapse before re-reporting usage stats
474    // interaction with foreground processes.
475    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
476
477    // This is the amount of time we allow an app to settle after it goes into the background,
478    // before we start restricting what it can do.
479    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
480
481    // How long to wait in getAssistContextExtras for the activity and foreground services
482    // to respond with the result.
483    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
484
485    // How long top wait when going through the modern assist (which doesn't need to block
486    // on getting this result before starting to launch its UI).
487    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
488
489    // Maximum number of persisted Uri grants a package is allowed
490    static final int MAX_PERSISTED_URI_GRANTS = 128;
491
492    static final int MY_PID = Process.myPid();
493
494    static final String[] EMPTY_STRING_ARRAY = new String[0];
495
496    // How many bytes to write into the dropbox log before truncating
497    static final int DROPBOX_MAX_SIZE = 256 * 1024;
498
499    // Access modes for handleIncomingUser.
500    static final int ALLOW_NON_FULL = 0;
501    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
502    static final int ALLOW_FULL_ONLY = 2;
503
504    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
505
506    // Delay in notifying task stack change listeners (in millis)
507    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
508
509    // Necessary ApplicationInfo flags to mark an app as persistent
510    private static final int PERSISTENT_MASK =
511            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
512
513    // Intent sent when remote bugreport collection has been completed
514    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
515            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
516
517    // Delay to disable app launch boost
518    static final int APP_BOOST_MESSAGE_DELAY = 3000;
519    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
520    static final int APP_BOOST_TIMEOUT = 2500;
521
522    // Used to indicate that a task is removed it should also be removed from recents.
523    private static final boolean REMOVE_FROM_RECENTS = true;
524    // Used to indicate that an app transition should be animated.
525    static final boolean ANIMATE = true;
526
527    // Determines whether to take full screen screenshots
528    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
529
530    private static native int nativeMigrateToBoost();
531    private static native int nativeMigrateFromBoost();
532    private boolean mIsBoosted = false;
533    private long mBoostStartTime = 0;
534
535    /** All system services */
536    SystemServiceManager mSystemServiceManager;
537
538    private Installer mInstaller;
539
540    /** Run all ActivityStacks through this */
541    final ActivityStackSupervisor mStackSupervisor;
542
543    final ActivityStarter mActivityStarter;
544
545    /** Task stack change listeners. */
546    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
547            new RemoteCallbackList<ITaskStackListener>();
548
549    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
550
551    public IntentFirewall mIntentFirewall;
552
553    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
554    // default actuion automatically.  Important for devices without direct input
555    // devices.
556    private boolean mShowDialogs = true;
557    private boolean mInVrMode = false;
558
559    BroadcastQueue mFgBroadcastQueue;
560    BroadcastQueue mBgBroadcastQueue;
561    // Convenient for easy iteration over the queues. Foreground is first
562    // so that dispatch of foreground broadcasts gets precedence.
563    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
564
565    BroadcastQueue broadcastQueueForIntent(Intent intent) {
566        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
567        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
568                "Broadcast intent " + intent + " on "
569                + (isFg ? "foreground" : "background") + " queue");
570        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
571    }
572
573    /**
574     * Activity we have told the window manager to have key focus.
575     */
576    ActivityRecord mFocusedActivity = null;
577
578    /**
579     * User id of the last activity mFocusedActivity was set to.
580     */
581    private int mLastFocusedUserId;
582
583    /**
584     * If non-null, we are tracking the time the user spends in the currently focused app.
585     */
586    private AppTimeTracker mCurAppTimeTracker;
587
588    /**
589     * List of intents that were used to start the most recent tasks.
590     */
591    final RecentTasks mRecentTasks;
592
593    /**
594     * For addAppTask: cached of the last activity component that was added.
595     */
596    ComponentName mLastAddedTaskComponent;
597
598    /**
599     * For addAppTask: cached of the last activity uid that was added.
600     */
601    int mLastAddedTaskUid;
602
603    /**
604     * For addAppTask: cached of the last ActivityInfo that was added.
605     */
606    ActivityInfo mLastAddedTaskActivity;
607
608    /**
609     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
610     */
611    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
612
613    /**
614     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
615     */
616    String mDeviceOwnerName;
617
618    final UserController mUserController;
619
620    final AppErrors mAppErrors;
621
622    boolean mDoingSetFocusedActivity;
623
624    public boolean canShowErrorDialogs() {
625        return mShowDialogs && !mSleeping && !mShuttingDown;
626    }
627
628    public class PendingAssistExtras extends Binder implements Runnable {
629        public final ActivityRecord activity;
630        public final Bundle extras;
631        public final Intent intent;
632        public final String hint;
633        public final IResultReceiver receiver;
634        public final int userHandle;
635        public boolean haveResult = false;
636        public Bundle result = null;
637        public AssistStructure structure = null;
638        public AssistContent content = null;
639        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
640                String _hint, IResultReceiver _receiver, int _userHandle) {
641            activity = _activity;
642            extras = _extras;
643            intent = _intent;
644            hint = _hint;
645            receiver = _receiver;
646            userHandle = _userHandle;
647        }
648        @Override
649        public void run() {
650            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
651            synchronized (this) {
652                haveResult = true;
653                notifyAll();
654            }
655            pendingAssistExtrasTimedOut(this);
656        }
657    }
658
659    final ArrayList<PendingAssistExtras> mPendingAssistExtras
660            = new ArrayList<PendingAssistExtras>();
661
662    /**
663     * Process management.
664     */
665    final ProcessList mProcessList = new ProcessList();
666
667    /**
668     * All of the applications we currently have running organized by name.
669     * The keys are strings of the application package name (as
670     * returned by the package manager), and the keys are ApplicationRecord
671     * objects.
672     */
673    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
674
675    /**
676     * Tracking long-term execution of processes to look for abuse and other
677     * bad app behavior.
678     */
679    final ProcessStatsService mProcessStats;
680
681    /**
682     * The currently running isolated processes.
683     */
684    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
685
686    /**
687     * Counter for assigning isolated process uids, to avoid frequently reusing the
688     * same ones.
689     */
690    int mNextIsolatedProcessUid = 0;
691
692    /**
693     * The currently running heavy-weight process, if any.
694     */
695    ProcessRecord mHeavyWeightProcess = null;
696
697    /**
698     * All of the processes we currently have running organized by pid.
699     * The keys are the pid running the application.
700     *
701     * <p>NOTE: This object is protected by its own lock, NOT the global
702     * activity manager lock!
703     */
704    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
705
706    /**
707     * All of the processes that have been forced to be foreground.  The key
708     * is the pid of the caller who requested it (we hold a death
709     * link on it).
710     */
711    abstract class ForegroundToken implements IBinder.DeathRecipient {
712        int pid;
713        IBinder token;
714    }
715    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
716
717    /**
718     * List of records for processes that someone had tried to start before the
719     * system was ready.  We don't start them at that point, but ensure they
720     * are started by the time booting is complete.
721     */
722    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
723
724    /**
725     * List of persistent applications that are in the process
726     * of being started.
727     */
728    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
729
730    /**
731     * Processes that are being forcibly torn down.
732     */
733    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
734
735    /**
736     * List of running applications, sorted by recent usage.
737     * The first entry in the list is the least recently used.
738     */
739    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
740
741    /**
742     * Where in mLruProcesses that the processes hosting activities start.
743     */
744    int mLruProcessActivityStart = 0;
745
746    /**
747     * Where in mLruProcesses that the processes hosting services start.
748     * This is after (lower index) than mLruProcessesActivityStart.
749     */
750    int mLruProcessServiceStart = 0;
751
752    /**
753     * List of processes that should gc as soon as things are idle.
754     */
755    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
756
757    /**
758     * Processes we want to collect PSS data from.
759     */
760    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
761
762    private boolean mBinderTransactionTrackingEnabled = false;
763
764    /**
765     * Last time we requested PSS data of all processes.
766     */
767    long mLastFullPssTime = SystemClock.uptimeMillis();
768
769    /**
770     * If set, the next time we collect PSS data we should do a full collection
771     * with data from native processes and the kernel.
772     */
773    boolean mFullPssPending = false;
774
775    /**
776     * This is the process holding what we currently consider to be
777     * the "home" activity.
778     */
779    ProcessRecord mHomeProcess;
780
781    /**
782     * This is the process holding the activity the user last visited that
783     * is in a different process from the one they are currently in.
784     */
785    ProcessRecord mPreviousProcess;
786
787    /**
788     * The time at which the previous process was last visible.
789     */
790    long mPreviousProcessVisibleTime;
791
792    /**
793     * Track all uids that have actively running processes.
794     */
795    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
796
797    /**
798     * This is for verifying the UID report flow.
799     */
800    static final boolean VALIDATE_UID_STATES = true;
801    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
802
803    /**
804     * Packages that the user has asked to have run in screen size
805     * compatibility mode instead of filling the screen.
806     */
807    final CompatModePackages mCompatModePackages;
808
809    /**
810     * Set of IntentSenderRecord objects that are currently active.
811     */
812    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
813            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
814
815    /**
816     * Fingerprints (hashCode()) of stack traces that we've
817     * already logged DropBox entries for.  Guarded by itself.  If
818     * something (rogue user app) forces this over
819     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
820     */
821    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
822    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
823
824    /**
825     * Strict Mode background batched logging state.
826     *
827     * The string buffer is guarded by itself, and its lock is also
828     * used to determine if another batched write is already
829     * in-flight.
830     */
831    private final StringBuilder mStrictModeBuffer = new StringBuilder();
832
833    /**
834     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
835     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
836     */
837    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
838
839    /**
840     * Resolver for broadcast intents to registered receivers.
841     * Holds BroadcastFilter (subclass of IntentFilter).
842     */
843    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
844            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
845        @Override
846        protected boolean allowFilterResult(
847                BroadcastFilter filter, List<BroadcastFilter> dest) {
848            IBinder target = filter.receiverList.receiver.asBinder();
849            for (int i = dest.size() - 1; i >= 0; i--) {
850                if (dest.get(i).receiverList.receiver.asBinder() == target) {
851                    return false;
852                }
853            }
854            return true;
855        }
856
857        @Override
858        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
859            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
860                    || userId == filter.owningUserId) {
861                return super.newResult(filter, match, userId);
862            }
863            return null;
864        }
865
866        @Override
867        protected BroadcastFilter[] newArray(int size) {
868            return new BroadcastFilter[size];
869        }
870
871        @Override
872        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
873            return packageName.equals(filter.packageName);
874        }
875    };
876
877    /**
878     * State of all active sticky broadcasts per user.  Keys are the action of the
879     * sticky Intent, values are an ArrayList of all broadcasted intents with
880     * that action (which should usually be one).  The SparseArray is keyed
881     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
882     * for stickies that are sent to all users.
883     */
884    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
885            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
886
887    final ActiveServices mServices;
888
889    final static class Association {
890        final int mSourceUid;
891        final String mSourceProcess;
892        final int mTargetUid;
893        final ComponentName mTargetComponent;
894        final String mTargetProcess;
895
896        int mCount;
897        long mTime;
898
899        int mNesting;
900        long mStartTime;
901
902        Association(int sourceUid, String sourceProcess, int targetUid,
903                ComponentName targetComponent, String targetProcess) {
904            mSourceUid = sourceUid;
905            mSourceProcess = sourceProcess;
906            mTargetUid = targetUid;
907            mTargetComponent = targetComponent;
908            mTargetProcess = targetProcess;
909        }
910    }
911
912    /**
913     * When service association tracking is enabled, this is all of the associations we
914     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
915     * -> association data.
916     */
917    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
918            mAssociations = new SparseArray<>();
919    boolean mTrackingAssociations;
920
921    /**
922     * Backup/restore process management
923     */
924    String mBackupAppName = null;
925    BackupRecord mBackupTarget = null;
926
927    final ProviderMap mProviderMap;
928
929    /**
930     * List of content providers who have clients waiting for them.  The
931     * application is currently being launched and the provider will be
932     * removed from this list once it is published.
933     */
934    final ArrayList<ContentProviderRecord> mLaunchingProviders
935            = new ArrayList<ContentProviderRecord>();
936
937    /**
938     * File storing persisted {@link #mGrantedUriPermissions}.
939     */
940    private final AtomicFile mGrantFile;
941
942    /** XML constants used in {@link #mGrantFile} */
943    private static final String TAG_URI_GRANTS = "uri-grants";
944    private static final String TAG_URI_GRANT = "uri-grant";
945    private static final String ATTR_USER_HANDLE = "userHandle";
946    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
947    private static final String ATTR_TARGET_USER_ID = "targetUserId";
948    private static final String ATTR_SOURCE_PKG = "sourcePkg";
949    private static final String ATTR_TARGET_PKG = "targetPkg";
950    private static final String ATTR_URI = "uri";
951    private static final String ATTR_MODE_FLAGS = "modeFlags";
952    private static final String ATTR_CREATED_TIME = "createdTime";
953    private static final String ATTR_PREFIX = "prefix";
954
955    /**
956     * Global set of specific {@link Uri} permissions that have been granted.
957     * This optimized lookup structure maps from {@link UriPermission#targetUid}
958     * to {@link UriPermission#uri} to {@link UriPermission}.
959     */
960    @GuardedBy("this")
961    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
962            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
963
964    public static class GrantUri {
965        public final int sourceUserId;
966        public final Uri uri;
967        public boolean prefix;
968
969        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
970            this.sourceUserId = sourceUserId;
971            this.uri = uri;
972            this.prefix = prefix;
973        }
974
975        @Override
976        public int hashCode() {
977            int hashCode = 1;
978            hashCode = 31 * hashCode + sourceUserId;
979            hashCode = 31 * hashCode + uri.hashCode();
980            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
981            return hashCode;
982        }
983
984        @Override
985        public boolean equals(Object o) {
986            if (o instanceof GrantUri) {
987                GrantUri other = (GrantUri) o;
988                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
989                        && prefix == other.prefix;
990            }
991            return false;
992        }
993
994        @Override
995        public String toString() {
996            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
997            if (prefix) result += " [prefix]";
998            return result;
999        }
1000
1001        public String toSafeString() {
1002            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1003            if (prefix) result += " [prefix]";
1004            return result;
1005        }
1006
1007        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1008            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1009                    ContentProvider.getUriWithoutUserId(uri), false);
1010        }
1011    }
1012
1013    CoreSettingsObserver mCoreSettingsObserver;
1014
1015    FontScaleSettingObserver mFontScaleSettingObserver;
1016
1017    private final class FontScaleSettingObserver extends ContentObserver {
1018        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1019
1020        public FontScaleSettingObserver() {
1021            super(mHandler);
1022            ContentResolver resolver = mContext.getContentResolver();
1023            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1024        }
1025
1026        @Override
1027        public void onChange(boolean selfChange, Uri uri) {
1028            if (mFontScaleUri.equals(uri)) {
1029                updateFontScaleIfNeeded();
1030            }
1031        }
1032    }
1033
1034    /**
1035     * Thread-local storage used to carry caller permissions over through
1036     * indirect content-provider access.
1037     */
1038    private class Identity {
1039        public final IBinder token;
1040        public final int pid;
1041        public final int uid;
1042
1043        Identity(IBinder _token, int _pid, int _uid) {
1044            token = _token;
1045            pid = _pid;
1046            uid = _uid;
1047        }
1048    }
1049
1050    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1051
1052    /**
1053     * All information we have collected about the runtime performance of
1054     * any user id that can impact battery performance.
1055     */
1056    final BatteryStatsService mBatteryStatsService;
1057
1058    /**
1059     * Information about component usage
1060     */
1061    UsageStatsManagerInternal mUsageStatsService;
1062
1063    /**
1064     * Access to DeviceIdleController service.
1065     */
1066    DeviceIdleController.LocalService mLocalDeviceIdleController;
1067
1068    /**
1069     * Information about and control over application operations
1070     */
1071    final AppOpsService mAppOpsService;
1072
1073    /**
1074     * Current configuration information.  HistoryRecord objects are given
1075     * a reference to this object to indicate which configuration they are
1076     * currently running in, so this object must be kept immutable.
1077     */
1078    Configuration mConfiguration = new Configuration();
1079
1080    /**
1081     * Current sequencing integer of the configuration, for skipping old
1082     * configurations.
1083     */
1084    int mConfigurationSeq = 0;
1085
1086    boolean mSuppressResizeConfigChanges = false;
1087
1088    /**
1089     * Hardware-reported OpenGLES version.
1090     */
1091    final int GL_ES_VERSION;
1092
1093    /**
1094     * List of initialization arguments to pass to all processes when binding applications to them.
1095     * For example, references to the commonly used services.
1096     */
1097    HashMap<String, IBinder> mAppBindArgs;
1098
1099    /**
1100     * Temporary to avoid allocations.  Protected by main lock.
1101     */
1102    final StringBuilder mStringBuilder = new StringBuilder(256);
1103
1104    /**
1105     * Used to control how we initialize the service.
1106     */
1107    ComponentName mTopComponent;
1108    String mTopAction = Intent.ACTION_MAIN;
1109    String mTopData;
1110    boolean mProcessesReady = false;
1111    boolean mSystemReady = false;
1112    boolean mBooting = false;
1113    boolean mCallFinishBooting = false;
1114    boolean mBootAnimationComplete = false;
1115    boolean mWaitingUpdate = false;
1116    boolean mDidUpdate = false;
1117    boolean mOnBattery = false;
1118    boolean mLaunchWarningShown = false;
1119
1120    Context mContext;
1121
1122    int mFactoryTest;
1123
1124    boolean mCheckedForSetup;
1125
1126    /**
1127     * The time at which we will allow normal application switches again,
1128     * after a call to {@link #stopAppSwitches()}.
1129     */
1130    long mAppSwitchesAllowedTime;
1131
1132    /**
1133     * This is set to true after the first switch after mAppSwitchesAllowedTime
1134     * is set; any switches after that will clear the time.
1135     */
1136    boolean mDidAppSwitch;
1137
1138    /**
1139     * Last time (in realtime) at which we checked for power usage.
1140     */
1141    long mLastPowerCheckRealtime;
1142
1143    /**
1144     * Last time (in uptime) at which we checked for power usage.
1145     */
1146    long mLastPowerCheckUptime;
1147
1148    /**
1149     * Set while we are wanting to sleep, to prevent any
1150     * activities from being started/resumed.
1151     */
1152    private boolean mSleeping = false;
1153
1154    /**
1155     * The process state used for processes that are running the top activities.
1156     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1157     */
1158    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1159
1160    /**
1161     * Set while we are running a voice interaction.  This overrides
1162     * sleeping while it is active.
1163     */
1164    private IVoiceInteractionSession mRunningVoice;
1165
1166    /**
1167     * For some direct access we need to power manager.
1168     */
1169    PowerManagerInternal mLocalPowerManager;
1170
1171    /**
1172     * We want to hold a wake lock while running a voice interaction session, since
1173     * this may happen with the screen off and we need to keep the CPU running to
1174     * be able to continue to interact with the user.
1175     */
1176    PowerManager.WakeLock mVoiceWakeLock;
1177
1178    /**
1179     * State of external calls telling us if the device is awake or asleep.
1180     */
1181    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1182
1183    /**
1184     * A list of tokens that cause the top activity to be put to sleep.
1185     * They are used by components that may hide and block interaction with underlying
1186     * activities.
1187     */
1188    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1189
1190    static final int LOCK_SCREEN_HIDDEN = 0;
1191    static final int LOCK_SCREEN_LEAVING = 1;
1192    static final int LOCK_SCREEN_SHOWN = 2;
1193    /**
1194     * State of external call telling us if the lock screen is shown.
1195     */
1196    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1197
1198    /**
1199     * Set if we are shutting down the system, similar to sleeping.
1200     */
1201    boolean mShuttingDown = false;
1202
1203    /**
1204     * Current sequence id for oom_adj computation traversal.
1205     */
1206    int mAdjSeq = 0;
1207
1208    /**
1209     * Current sequence id for process LRU updating.
1210     */
1211    int mLruSeq = 0;
1212
1213    /**
1214     * Keep track of the non-cached/empty process we last found, to help
1215     * determine how to distribute cached/empty processes next time.
1216     */
1217    int mNumNonCachedProcs = 0;
1218
1219    /**
1220     * Keep track of the number of cached hidden procs, to balance oom adj
1221     * distribution between those and empty procs.
1222     */
1223    int mNumCachedHiddenProcs = 0;
1224
1225    /**
1226     * Keep track of the number of service processes we last found, to
1227     * determine on the next iteration which should be B services.
1228     */
1229    int mNumServiceProcs = 0;
1230    int mNewNumAServiceProcs = 0;
1231    int mNewNumServiceProcs = 0;
1232
1233    /**
1234     * Allow the current computed overall memory level of the system to go down?
1235     * This is set to false when we are killing processes for reasons other than
1236     * memory management, so that the now smaller process list will not be taken as
1237     * an indication that memory is tighter.
1238     */
1239    boolean mAllowLowerMemLevel = false;
1240
1241    /**
1242     * The last computed memory level, for holding when we are in a state that
1243     * processes are going away for other reasons.
1244     */
1245    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1246
1247    /**
1248     * The last total number of process we have, to determine if changes actually look
1249     * like a shrinking number of process due to lower RAM.
1250     */
1251    int mLastNumProcesses;
1252
1253    /**
1254     * The uptime of the last time we performed idle maintenance.
1255     */
1256    long mLastIdleTime = SystemClock.uptimeMillis();
1257
1258    /**
1259     * Total time spent with RAM that has been added in the past since the last idle time.
1260     */
1261    long mLowRamTimeSinceLastIdle = 0;
1262
1263    /**
1264     * If RAM is currently low, when that horrible situation started.
1265     */
1266    long mLowRamStartTime = 0;
1267
1268    /**
1269     * For reporting to battery stats the current top application.
1270     */
1271    private String mCurResumedPackage = null;
1272    private int mCurResumedUid = -1;
1273
1274    /**
1275     * For reporting to battery stats the apps currently running foreground
1276     * service.  The ProcessMap is package/uid tuples; each of these contain
1277     * an array of the currently foreground processes.
1278     */
1279    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1280            = new ProcessMap<ArrayList<ProcessRecord>>();
1281
1282    /**
1283     * This is set if we had to do a delayed dexopt of an app before launching
1284     * it, to increase the ANR timeouts in that case.
1285     */
1286    boolean mDidDexOpt;
1287
1288    /**
1289     * Set if the systemServer made a call to enterSafeMode.
1290     */
1291    boolean mSafeMode;
1292
1293    /**
1294     * If true, we are running under a test environment so will sample PSS from processes
1295     * much more rapidly to try to collect better data when the tests are rapidly
1296     * running through apps.
1297     */
1298    boolean mTestPssMode = false;
1299
1300    String mDebugApp = null;
1301    boolean mWaitForDebugger = false;
1302    boolean mDebugTransient = false;
1303    String mOrigDebugApp = null;
1304    boolean mOrigWaitForDebugger = false;
1305    boolean mAlwaysFinishActivities = false;
1306    boolean mLenientBackgroundCheck = false;
1307    boolean mForceResizableActivities;
1308    boolean mSupportsMultiWindow;
1309    boolean mSupportsFreeformWindowManagement;
1310    boolean mSupportsPictureInPicture;
1311    Rect mDefaultPinnedStackBounds;
1312    IActivityController mController = null;
1313    boolean mControllerIsAMonkey = false;
1314    String mProfileApp = null;
1315    ProcessRecord mProfileProc = null;
1316    String mProfileFile;
1317    ParcelFileDescriptor mProfileFd;
1318    int mSamplingInterval = 0;
1319    boolean mAutoStopProfiler = false;
1320    int mProfileType = 0;
1321    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1322    String mMemWatchDumpProcName;
1323    String mMemWatchDumpFile;
1324    int mMemWatchDumpPid;
1325    int mMemWatchDumpUid;
1326    String mTrackAllocationApp = null;
1327    String mNativeDebuggingApp = null;
1328
1329    final long[] mTmpLong = new long[2];
1330
1331    static final class ProcessChangeItem {
1332        static final int CHANGE_ACTIVITIES = 1<<0;
1333        static final int CHANGE_PROCESS_STATE = 1<<1;
1334        int changes;
1335        int uid;
1336        int pid;
1337        int processState;
1338        boolean foregroundActivities;
1339    }
1340
1341    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1342    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1343
1344    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1345    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1346
1347    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1348    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1349
1350    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1351    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1352
1353    /**
1354     * Runtime CPU use collection thread.  This object's lock is used to
1355     * perform synchronization with the thread (notifying it to run).
1356     */
1357    final Thread mProcessCpuThread;
1358
1359    /**
1360     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1361     * Must acquire this object's lock when accessing it.
1362     * NOTE: this lock will be held while doing long operations (trawling
1363     * through all processes in /proc), so it should never be acquired by
1364     * any critical paths such as when holding the main activity manager lock.
1365     */
1366    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1367            MONITOR_THREAD_CPU_USAGE);
1368    final AtomicLong mLastCpuTime = new AtomicLong(0);
1369    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1370
1371    long mLastWriteTime = 0;
1372
1373    /**
1374     * Used to retain an update lock when the foreground activity is in
1375     * immersive mode.
1376     */
1377    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1378
1379    /**
1380     * Set to true after the system has finished booting.
1381     */
1382    boolean mBooted = false;
1383
1384    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1385    int mProcessLimitOverride = -1;
1386
1387    WindowManagerService mWindowManager;
1388    final ActivityThread mSystemThread;
1389
1390    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1391        final ProcessRecord mApp;
1392        final int mPid;
1393        final IApplicationThread mAppThread;
1394
1395        AppDeathRecipient(ProcessRecord app, int pid,
1396                IApplicationThread thread) {
1397            if (DEBUG_ALL) Slog.v(
1398                TAG, "New death recipient " + this
1399                + " for thread " + thread.asBinder());
1400            mApp = app;
1401            mPid = pid;
1402            mAppThread = thread;
1403        }
1404
1405        @Override
1406        public void binderDied() {
1407            if (DEBUG_ALL) Slog.v(
1408                TAG, "Death received in " + this
1409                + " for thread " + mAppThread.asBinder());
1410            synchronized(ActivityManagerService.this) {
1411                appDiedLocked(mApp, mPid, mAppThread, true);
1412            }
1413        }
1414    }
1415
1416    static final int SHOW_ERROR_UI_MSG = 1;
1417    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1418    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1419    static final int UPDATE_CONFIGURATION_MSG = 4;
1420    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1421    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1422    static final int SERVICE_TIMEOUT_MSG = 12;
1423    static final int UPDATE_TIME_ZONE = 13;
1424    static final int SHOW_UID_ERROR_UI_MSG = 14;
1425    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1426    static final int PROC_START_TIMEOUT_MSG = 20;
1427    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1428    static final int KILL_APPLICATION_MSG = 22;
1429    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1430    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1431    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1432    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1433    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1434    static final int CLEAR_DNS_CACHE_MSG = 28;
1435    static final int UPDATE_HTTP_PROXY_MSG = 29;
1436    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1437    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1438    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1439    static final int REPORT_MEM_USAGE_MSG = 33;
1440    static final int REPORT_USER_SWITCH_MSG = 34;
1441    static final int CONTINUE_USER_SWITCH_MSG = 35;
1442    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1443    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1444    static final int PERSIST_URI_GRANTS_MSG = 38;
1445    static final int REQUEST_ALL_PSS_MSG = 39;
1446    static final int START_PROFILES_MSG = 40;
1447    static final int UPDATE_TIME = 41;
1448    static final int SYSTEM_USER_START_MSG = 42;
1449    static final int SYSTEM_USER_CURRENT_MSG = 43;
1450    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1451    static final int FINISH_BOOTING_MSG = 45;
1452    static final int START_USER_SWITCH_UI_MSG = 46;
1453    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1454    static final int DISMISS_DIALOG_UI_MSG = 48;
1455    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1456    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1457    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1458    static final int DELETE_DUMPHEAP_MSG = 52;
1459    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1460    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1461    static final int REPORT_TIME_TRACKER_MSG = 55;
1462    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1463    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1464    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1465    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1466    static final int IDLE_UIDS_MSG = 60;
1467    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1468    static final int LOG_STACK_STATE = 62;
1469    static final int VR_MODE_CHANGE_MSG = 63;
1470    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1471    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1472    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1473
1474    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1475    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1476    static final int FIRST_COMPAT_MODE_MSG = 300;
1477    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1478
1479    CompatModeDialog mCompatModeDialog;
1480    long mLastMemUsageReportTime = 0;
1481
1482    /**
1483     * Flag whether the current user is a "monkey", i.e. whether
1484     * the UI is driven by a UI automation tool.
1485     */
1486    private boolean mUserIsMonkey;
1487
1488    /** Flag whether the device has a Recents UI */
1489    boolean mHasRecents;
1490
1491    /** The dimensions of the thumbnails in the Recents UI. */
1492    int mThumbnailWidth;
1493    int mThumbnailHeight;
1494
1495    final ServiceThread mHandlerThread;
1496    final MainHandler mHandler;
1497    final UiHandler mUiHandler;
1498    final ProcessStartLogger mProcessStartLogger;
1499
1500    PackageManagerInternal mPackageManagerInt;
1501
1502    final class UiHandler extends Handler {
1503        public UiHandler() {
1504            super(com.android.server.UiThread.get().getLooper(), null, true);
1505        }
1506
1507        @Override
1508        public void handleMessage(Message msg) {
1509            switch (msg.what) {
1510            case SHOW_ERROR_UI_MSG: {
1511                mAppErrors.handleShowAppErrorUi(msg);
1512                ensureBootCompleted();
1513            } break;
1514            case SHOW_NOT_RESPONDING_UI_MSG: {
1515                mAppErrors.handleShowAnrUi(msg);
1516                ensureBootCompleted();
1517            } break;
1518            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1519                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1520                synchronized (ActivityManagerService.this) {
1521                    ProcessRecord proc = (ProcessRecord) data.get("app");
1522                    if (proc == null) {
1523                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1524                        break;
1525                    }
1526                    if (proc.crashDialog != null) {
1527                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1528                        return;
1529                    }
1530                    AppErrorResult res = (AppErrorResult) data.get("result");
1531                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1532                        Dialog d = new StrictModeViolationDialog(mContext,
1533                                ActivityManagerService.this, res, proc);
1534                        d.show();
1535                        proc.crashDialog = d;
1536                    } else {
1537                        // The device is asleep, so just pretend that the user
1538                        // saw a crash dialog and hit "force quit".
1539                        res.set(0);
1540                    }
1541                }
1542                ensureBootCompleted();
1543            } break;
1544            case SHOW_FACTORY_ERROR_UI_MSG: {
1545                Dialog d = new FactoryErrorDialog(
1546                    mContext, msg.getData().getCharSequence("msg"));
1547                d.show();
1548                ensureBootCompleted();
1549            } break;
1550            case WAIT_FOR_DEBUGGER_UI_MSG: {
1551                synchronized (ActivityManagerService.this) {
1552                    ProcessRecord app = (ProcessRecord)msg.obj;
1553                    if (msg.arg1 != 0) {
1554                        if (!app.waitedForDebugger) {
1555                            Dialog d = new AppWaitingForDebuggerDialog(
1556                                    ActivityManagerService.this,
1557                                    mContext, app);
1558                            app.waitDialog = d;
1559                            app.waitedForDebugger = true;
1560                            d.show();
1561                        }
1562                    } else {
1563                        if (app.waitDialog != null) {
1564                            app.waitDialog.dismiss();
1565                            app.waitDialog = null;
1566                        }
1567                    }
1568                }
1569            } break;
1570            case SHOW_UID_ERROR_UI_MSG: {
1571                if (mShowDialogs) {
1572                    AlertDialog d = new BaseErrorDialog(mContext);
1573                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1574                    d.setCancelable(false);
1575                    d.setTitle(mContext.getText(R.string.android_system_label));
1576                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1577                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1578                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1579                    d.show();
1580                }
1581            } break;
1582            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1583                if (mShowDialogs) {
1584                    AlertDialog d = new BaseErrorDialog(mContext);
1585                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1586                    d.setCancelable(false);
1587                    d.setTitle(mContext.getText(R.string.android_system_label));
1588                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1589                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1590                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1591                    d.show();
1592                }
1593            } break;
1594            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1595                synchronized (ActivityManagerService.this) {
1596                    ActivityRecord ar = (ActivityRecord) msg.obj;
1597                    if (mCompatModeDialog != null) {
1598                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1599                                ar.info.applicationInfo.packageName)) {
1600                            return;
1601                        }
1602                        mCompatModeDialog.dismiss();
1603                        mCompatModeDialog = null;
1604                    }
1605                    if (ar != null && false) {
1606                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1607                                ar.packageName)) {
1608                            int mode = mCompatModePackages.computeCompatModeLocked(
1609                                    ar.info.applicationInfo);
1610                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1611                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1612                                mCompatModeDialog = new CompatModeDialog(
1613                                        ActivityManagerService.this, mContext,
1614                                        ar.info.applicationInfo);
1615                                mCompatModeDialog.show();
1616                            }
1617                        }
1618                    }
1619                }
1620                break;
1621            }
1622            case START_USER_SWITCH_UI_MSG: {
1623                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1624                break;
1625            }
1626            case DISMISS_DIALOG_UI_MSG: {
1627                final Dialog d = (Dialog) msg.obj;
1628                d.dismiss();
1629                break;
1630            }
1631            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1632                dispatchProcessesChanged();
1633                break;
1634            }
1635            case DISPATCH_PROCESS_DIED_UI_MSG: {
1636                final int pid = msg.arg1;
1637                final int uid = msg.arg2;
1638                dispatchProcessDied(pid, uid);
1639                break;
1640            }
1641            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1642                dispatchUidsChanged();
1643            } break;
1644            }
1645        }
1646    }
1647
1648    final class MainHandler extends Handler {
1649        public MainHandler(Looper looper) {
1650            super(looper, null, true);
1651        }
1652
1653        @Override
1654        public void handleMessage(Message msg) {
1655            switch (msg.what) {
1656            case UPDATE_CONFIGURATION_MSG: {
1657                final ContentResolver resolver = mContext.getContentResolver();
1658                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1659                        msg.arg1);
1660            } break;
1661            case GC_BACKGROUND_PROCESSES_MSG: {
1662                synchronized (ActivityManagerService.this) {
1663                    performAppGcsIfAppropriateLocked();
1664                }
1665            } break;
1666            case SERVICE_TIMEOUT_MSG: {
1667                if (mDidDexOpt) {
1668                    mDidDexOpt = false;
1669                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1670                    nmsg.obj = msg.obj;
1671                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1672                    return;
1673                }
1674                mServices.serviceTimeout((ProcessRecord)msg.obj);
1675            } break;
1676            case UPDATE_TIME_ZONE: {
1677                synchronized (ActivityManagerService.this) {
1678                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1679                        ProcessRecord r = mLruProcesses.get(i);
1680                        if (r.thread != null) {
1681                            try {
1682                                r.thread.updateTimeZone();
1683                            } catch (RemoteException ex) {
1684                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1685                            }
1686                        }
1687                    }
1688                }
1689            } break;
1690            case CLEAR_DNS_CACHE_MSG: {
1691                synchronized (ActivityManagerService.this) {
1692                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1693                        ProcessRecord r = mLruProcesses.get(i);
1694                        if (r.thread != null) {
1695                            try {
1696                                r.thread.clearDnsCache();
1697                            } catch (RemoteException ex) {
1698                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1699                            }
1700                        }
1701                    }
1702                }
1703            } break;
1704            case UPDATE_HTTP_PROXY_MSG: {
1705                ProxyInfo proxy = (ProxyInfo)msg.obj;
1706                String host = "";
1707                String port = "";
1708                String exclList = "";
1709                Uri pacFileUrl = Uri.EMPTY;
1710                if (proxy != null) {
1711                    host = proxy.getHost();
1712                    port = Integer.toString(proxy.getPort());
1713                    exclList = proxy.getExclusionListAsString();
1714                    pacFileUrl = proxy.getPacFileUrl();
1715                }
1716                synchronized (ActivityManagerService.this) {
1717                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1718                        ProcessRecord r = mLruProcesses.get(i);
1719                        if (r.thread != null) {
1720                            try {
1721                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1722                            } catch (RemoteException ex) {
1723                                Slog.w(TAG, "Failed to update http proxy for: " +
1724                                        r.info.processName);
1725                            }
1726                        }
1727                    }
1728                }
1729            } break;
1730            case PROC_START_TIMEOUT_MSG: {
1731                if (mDidDexOpt) {
1732                    mDidDexOpt = false;
1733                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1734                    nmsg.obj = msg.obj;
1735                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1736                    return;
1737                }
1738                ProcessRecord app = (ProcessRecord)msg.obj;
1739                synchronized (ActivityManagerService.this) {
1740                    processStartTimedOutLocked(app);
1741                }
1742            } break;
1743            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1744                ProcessRecord app = (ProcessRecord)msg.obj;
1745                synchronized (ActivityManagerService.this) {
1746                    processContentProviderPublishTimedOutLocked(app);
1747                }
1748            } break;
1749            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1750                synchronized (ActivityManagerService.this) {
1751                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1752                }
1753            } break;
1754            case KILL_APPLICATION_MSG: {
1755                synchronized (ActivityManagerService.this) {
1756                    int appid = msg.arg1;
1757                    boolean restart = (msg.arg2 == 1);
1758                    Bundle bundle = (Bundle)msg.obj;
1759                    String pkg = bundle.getString("pkg");
1760                    String reason = bundle.getString("reason");
1761                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1762                            false, UserHandle.USER_ALL, reason);
1763                }
1764            } break;
1765            case FINALIZE_PENDING_INTENT_MSG: {
1766                ((PendingIntentRecord)msg.obj).completeFinalize();
1767            } break;
1768            case POST_HEAVY_NOTIFICATION_MSG: {
1769                INotificationManager inm = NotificationManager.getService();
1770                if (inm == null) {
1771                    return;
1772                }
1773
1774                ActivityRecord root = (ActivityRecord)msg.obj;
1775                ProcessRecord process = root.app;
1776                if (process == null) {
1777                    return;
1778                }
1779
1780                try {
1781                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1782                    String text = mContext.getString(R.string.heavy_weight_notification,
1783                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1784                    Notification notification = new Notification.Builder(context)
1785                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1786                            .setWhen(0)
1787                            .setOngoing(true)
1788                            .setTicker(text)
1789                            .setColor(mContext.getColor(
1790                                    com.android.internal.R.color.system_notification_accent_color))
1791                            .setContentTitle(text)
1792                            .setContentText(
1793                                    mContext.getText(R.string.heavy_weight_notification_detail))
1794                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1795                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1796                                    new UserHandle(root.userId)))
1797                            .build();
1798                    try {
1799                        int[] outId = new int[1];
1800                        inm.enqueueNotificationWithTag("android", "android", null,
1801                                R.string.heavy_weight_notification,
1802                                notification, outId, root.userId);
1803                    } catch (RuntimeException e) {
1804                        Slog.w(ActivityManagerService.TAG,
1805                                "Error showing notification for heavy-weight app", e);
1806                    } catch (RemoteException e) {
1807                    }
1808                } catch (NameNotFoundException e) {
1809                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1810                }
1811            } break;
1812            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1813                INotificationManager inm = NotificationManager.getService();
1814                if (inm == null) {
1815                    return;
1816                }
1817                try {
1818                    inm.cancelNotificationWithTag("android", null,
1819                            R.string.heavy_weight_notification,  msg.arg1);
1820                } catch (RuntimeException e) {
1821                    Slog.w(ActivityManagerService.TAG,
1822                            "Error canceling notification for service", e);
1823                } catch (RemoteException e) {
1824                }
1825            } break;
1826            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1827                synchronized (ActivityManagerService.this) {
1828                    checkExcessivePowerUsageLocked(true);
1829                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1830                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1831                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1832                }
1833            } break;
1834            case REPORT_MEM_USAGE_MSG: {
1835                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1836                Thread thread = new Thread() {
1837                    @Override public void run() {
1838                        reportMemUsage(memInfos);
1839                    }
1840                };
1841                thread.start();
1842                break;
1843            }
1844            case REPORT_USER_SWITCH_MSG: {
1845                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1846                break;
1847            }
1848            case CONTINUE_USER_SWITCH_MSG: {
1849                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1850                break;
1851            }
1852            case USER_SWITCH_TIMEOUT_MSG: {
1853                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1854                break;
1855            }
1856            case IMMERSIVE_MODE_LOCK_MSG: {
1857                final boolean nextState = (msg.arg1 != 0);
1858                if (mUpdateLock.isHeld() != nextState) {
1859                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1860                            "Applying new update lock state '" + nextState
1861                            + "' for " + (ActivityRecord)msg.obj);
1862                    if (nextState) {
1863                        mUpdateLock.acquire();
1864                    } else {
1865                        mUpdateLock.release();
1866                    }
1867                }
1868                break;
1869            }
1870            case PERSIST_URI_GRANTS_MSG: {
1871                writeGrantedUriPermissions();
1872                break;
1873            }
1874            case REQUEST_ALL_PSS_MSG: {
1875                synchronized (ActivityManagerService.this) {
1876                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1877                }
1878                break;
1879            }
1880            case START_PROFILES_MSG: {
1881                synchronized (ActivityManagerService.this) {
1882                    mUserController.startProfilesLocked();
1883                }
1884                break;
1885            }
1886            case UPDATE_TIME: {
1887                synchronized (ActivityManagerService.this) {
1888                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1889                        ProcessRecord r = mLruProcesses.get(i);
1890                        if (r.thread != null) {
1891                            try {
1892                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1893                            } catch (RemoteException ex) {
1894                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1895                            }
1896                        }
1897                    }
1898                }
1899                break;
1900            }
1901            case SYSTEM_USER_START_MSG: {
1902                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1903                        Integer.toString(msg.arg1), msg.arg1);
1904                mSystemServiceManager.startUser(msg.arg1);
1905                break;
1906            }
1907            case SYSTEM_USER_UNLOCK_MSG: {
1908                final int userId = msg.arg1;
1909                mSystemServiceManager.unlockUser(userId);
1910                synchronized (ActivityManagerService.this) {
1911                    mRecentTasks.loadUserRecentsLocked(userId);
1912                }
1913                if (userId == UserHandle.USER_SYSTEM) {
1914                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1915                }
1916                installEncryptionUnawareProviders(userId);
1917                break;
1918            }
1919            case SYSTEM_USER_CURRENT_MSG: {
1920                mBatteryStatsService.noteEvent(
1921                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1922                        Integer.toString(msg.arg2), msg.arg2);
1923                mBatteryStatsService.noteEvent(
1924                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1925                        Integer.toString(msg.arg1), msg.arg1);
1926                mSystemServiceManager.switchUser(msg.arg1);
1927                break;
1928            }
1929            case ENTER_ANIMATION_COMPLETE_MSG: {
1930                synchronized (ActivityManagerService.this) {
1931                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1932                    if (r != null && r.app != null && r.app.thread != null) {
1933                        try {
1934                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1935                        } catch (RemoteException e) {
1936                        }
1937                    }
1938                }
1939                break;
1940            }
1941            case FINISH_BOOTING_MSG: {
1942                if (msg.arg1 != 0) {
1943                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1944                    finishBooting();
1945                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1946                }
1947                if (msg.arg2 != 0) {
1948                    enableScreenAfterBoot();
1949                }
1950                break;
1951            }
1952            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1953                try {
1954                    Locale l = (Locale) msg.obj;
1955                    IBinder service = ServiceManager.getService("mount");
1956                    IMountService mountService = IMountService.Stub.asInterface(service);
1957                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1958                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1959                } catch (RemoteException e) {
1960                    Log.e(TAG, "Error storing locale for decryption UI", e);
1961                }
1962                break;
1963            }
1964            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1965                synchronized (ActivityManagerService.this) {
1966                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1967                        try {
1968                            // Make a one-way callback to the listener
1969                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1970                        } catch (RemoteException e){
1971                            // Handled by the RemoteCallbackList
1972                        }
1973                    }
1974                    mTaskStackListeners.finishBroadcast();
1975                }
1976                break;
1977            }
1978            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
1979                synchronized (ActivityManagerService.this) {
1980                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1981                        try {
1982                            // Make a one-way callback to the listener
1983                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
1984                        } catch (RemoteException e){
1985                            // Handled by the RemoteCallbackList
1986                        }
1987                    }
1988                    mTaskStackListeners.finishBroadcast();
1989                }
1990                break;
1991            }
1992            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
1993                synchronized (ActivityManagerService.this) {
1994                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1995                        try {
1996                            // Make a one-way callback to the listener
1997                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
1998                        } catch (RemoteException e){
1999                            // Handled by the RemoteCallbackList
2000                        }
2001                    }
2002                    mTaskStackListeners.finishBroadcast();
2003                }
2004                break;
2005            }
2006            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2007                synchronized (ActivityManagerService.this) {
2008                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2009                        try {
2010                            // Make a one-way callback to the listener
2011                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2012                        } catch (RemoteException e){
2013                            // Handled by the RemoteCallbackList
2014                        }
2015                    }
2016                    mTaskStackListeners.finishBroadcast();
2017                }
2018                break;
2019            }
2020            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2021                final int uid = msg.arg1;
2022                final byte[] firstPacket = (byte[]) msg.obj;
2023
2024                synchronized (mPidsSelfLocked) {
2025                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2026                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2027                        if (p.uid == uid) {
2028                            try {
2029                                p.thread.notifyCleartextNetwork(firstPacket);
2030                            } catch (RemoteException ignored) {
2031                            }
2032                        }
2033                    }
2034                }
2035                break;
2036            }
2037            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2038                final String procName;
2039                final int uid;
2040                final long memLimit;
2041                final String reportPackage;
2042                synchronized (ActivityManagerService.this) {
2043                    procName = mMemWatchDumpProcName;
2044                    uid = mMemWatchDumpUid;
2045                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2046                    if (val == null) {
2047                        val = mMemWatchProcesses.get(procName, 0);
2048                    }
2049                    if (val != null) {
2050                        memLimit = val.first;
2051                        reportPackage = val.second;
2052                    } else {
2053                        memLimit = 0;
2054                        reportPackage = null;
2055                    }
2056                }
2057                if (procName == null) {
2058                    return;
2059                }
2060
2061                if (DEBUG_PSS) Slog.d(TAG_PSS,
2062                        "Showing dump heap notification from " + procName + "/" + uid);
2063
2064                INotificationManager inm = NotificationManager.getService();
2065                if (inm == null) {
2066                    return;
2067                }
2068
2069                String text = mContext.getString(R.string.dump_heap_notification, procName);
2070
2071
2072                Intent deleteIntent = new Intent();
2073                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2074                Intent intent = new Intent();
2075                intent.setClassName("android", DumpHeapActivity.class.getName());
2076                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2077                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2078                if (reportPackage != null) {
2079                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2080                }
2081                int userId = UserHandle.getUserId(uid);
2082                Notification notification = new Notification.Builder(mContext)
2083                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2084                        .setWhen(0)
2085                        .setOngoing(true)
2086                        .setAutoCancel(true)
2087                        .setTicker(text)
2088                        .setColor(mContext.getColor(
2089                                com.android.internal.R.color.system_notification_accent_color))
2090                        .setContentTitle(text)
2091                        .setContentText(
2092                                mContext.getText(R.string.dump_heap_notification_detail))
2093                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2094                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2095                                new UserHandle(userId)))
2096                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2097                                deleteIntent, 0, UserHandle.SYSTEM))
2098                        .build();
2099
2100                try {
2101                    int[] outId = new int[1];
2102                    inm.enqueueNotificationWithTag("android", "android", null,
2103                            R.string.dump_heap_notification,
2104                            notification, outId, userId);
2105                } catch (RuntimeException e) {
2106                    Slog.w(ActivityManagerService.TAG,
2107                            "Error showing notification for dump heap", e);
2108                } catch (RemoteException e) {
2109                }
2110            } break;
2111            case DELETE_DUMPHEAP_MSG: {
2112                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2113                        DumpHeapActivity.JAVA_URI,
2114                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2115                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2116                        UserHandle.myUserId());
2117                synchronized (ActivityManagerService.this) {
2118                    mMemWatchDumpFile = null;
2119                    mMemWatchDumpProcName = null;
2120                    mMemWatchDumpPid = -1;
2121                    mMemWatchDumpUid = -1;
2122                }
2123            } break;
2124            case FOREGROUND_PROFILE_CHANGED_MSG: {
2125                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2126            } break;
2127            case REPORT_TIME_TRACKER_MSG: {
2128                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2129                tracker.deliverResult(mContext);
2130            } break;
2131            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2132                mUserController.dispatchUserSwitchComplete(msg.arg1);
2133            } break;
2134            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2135                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2136                try {
2137                    connection.shutdown();
2138                } catch (RemoteException e) {
2139                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2140                }
2141                // Only a UiAutomation can set this flag and now that
2142                // it is finished we make sure it is reset to its default.
2143                mUserIsMonkey = false;
2144            } break;
2145            case APP_BOOST_DEACTIVATE_MSG: {
2146                synchronized(ActivityManagerService.this) {
2147                    if (mIsBoosted) {
2148                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2149                            nativeMigrateFromBoost();
2150                            mIsBoosted = false;
2151                            mBoostStartTime = 0;
2152                        } else {
2153                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2154                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2155                        }
2156                    }
2157                }
2158            } break;
2159            case IDLE_UIDS_MSG: {
2160                idleUids();
2161            } break;
2162            case LOG_STACK_STATE: {
2163                synchronized (ActivityManagerService.this) {
2164                    mStackSupervisor.logStackState();
2165                }
2166            } break;
2167            case VR_MODE_CHANGE_MSG: {
2168                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2169                final ActivityRecord r = (ActivityRecord) msg.obj;
2170                boolean vrMode;
2171                ComponentName requestedPackage;
2172                int userId;
2173                synchronized (ActivityManagerService.this) {
2174                    vrMode = r.requestedVrComponent != null;
2175                    requestedPackage = r.requestedVrComponent;
2176                    userId = r.userId;
2177                    if (mInVrMode != vrMode) {
2178                        mInVrMode = vrMode;
2179                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2180                    }
2181                }
2182                vrService.setVrMode(vrMode, requestedPackage, userId);
2183            } break;
2184            }
2185        }
2186    };
2187
2188    static final int COLLECT_PSS_BG_MSG = 1;
2189
2190    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2191        @Override
2192        public void handleMessage(Message msg) {
2193            switch (msg.what) {
2194            case COLLECT_PSS_BG_MSG: {
2195                long start = SystemClock.uptimeMillis();
2196                MemInfoReader memInfo = null;
2197                synchronized (ActivityManagerService.this) {
2198                    if (mFullPssPending) {
2199                        mFullPssPending = false;
2200                        memInfo = new MemInfoReader();
2201                    }
2202                }
2203                if (memInfo != null) {
2204                    updateCpuStatsNow();
2205                    long nativeTotalPss = 0;
2206                    synchronized (mProcessCpuTracker) {
2207                        final int N = mProcessCpuTracker.countStats();
2208                        for (int j=0; j<N; j++) {
2209                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2210                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2211                                // This is definitely an application process; skip it.
2212                                continue;
2213                            }
2214                            synchronized (mPidsSelfLocked) {
2215                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2216                                    // This is one of our own processes; skip it.
2217                                    continue;
2218                                }
2219                            }
2220                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2221                        }
2222                    }
2223                    memInfo.readMemInfo();
2224                    synchronized (ActivityManagerService.this) {
2225                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2226                                + (SystemClock.uptimeMillis()-start) + "ms");
2227                        final long cachedKb = memInfo.getCachedSizeKb();
2228                        final long freeKb = memInfo.getFreeSizeKb();
2229                        final long zramKb = memInfo.getZramTotalSizeKb();
2230                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2231                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2232                                kernelKb*1024, nativeTotalPss*1024);
2233                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2234                                nativeTotalPss);
2235                    }
2236                }
2237
2238                int num = 0;
2239                long[] tmp = new long[2];
2240                do {
2241                    ProcessRecord proc;
2242                    int procState;
2243                    int pid;
2244                    long lastPssTime;
2245                    synchronized (ActivityManagerService.this) {
2246                        if (mPendingPssProcesses.size() <= 0) {
2247                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2248                                    "Collected PSS of " + num + " processes in "
2249                                    + (SystemClock.uptimeMillis() - start) + "ms");
2250                            mPendingPssProcesses.clear();
2251                            return;
2252                        }
2253                        proc = mPendingPssProcesses.remove(0);
2254                        procState = proc.pssProcState;
2255                        lastPssTime = proc.lastPssTime;
2256                        if (proc.thread != null && procState == proc.setProcState
2257                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2258                                        < SystemClock.uptimeMillis()) {
2259                            pid = proc.pid;
2260                        } else {
2261                            proc = null;
2262                            pid = 0;
2263                        }
2264                    }
2265                    if (proc != null) {
2266                        long pss = Debug.getPss(pid, tmp, null);
2267                        synchronized (ActivityManagerService.this) {
2268                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2269                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2270                                num++;
2271                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2272                                        SystemClock.uptimeMillis());
2273                            }
2274                        }
2275                    }
2276                } while (true);
2277            }
2278            }
2279        }
2280    };
2281
2282    public void setSystemProcess() {
2283        try {
2284            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2285            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2286            ServiceManager.addService("meminfo", new MemBinder(this));
2287            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2288            ServiceManager.addService("dbinfo", new DbBinder(this));
2289            if (MONITOR_CPU_USAGE) {
2290                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2291            }
2292            ServiceManager.addService("permission", new PermissionController(this));
2293            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2294
2295            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2296                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2297            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2298
2299            synchronized (this) {
2300                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2301                app.persistent = true;
2302                app.pid = MY_PID;
2303                app.maxAdj = ProcessList.SYSTEM_ADJ;
2304                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2305                synchronized (mPidsSelfLocked) {
2306                    mPidsSelfLocked.put(app.pid, app);
2307                }
2308                updateLruProcessLocked(app, false, null);
2309                updateOomAdjLocked();
2310            }
2311        } catch (PackageManager.NameNotFoundException e) {
2312            throw new RuntimeException(
2313                    "Unable to find android system package", e);
2314        }
2315    }
2316
2317    public void setWindowManager(WindowManagerService wm) {
2318        mWindowManager = wm;
2319        mStackSupervisor.setWindowManager(wm);
2320        mActivityStarter.setWindowManager(wm);
2321    }
2322
2323    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2324        mUsageStatsService = usageStatsManager;
2325    }
2326
2327    public void startObservingNativeCrashes() {
2328        final NativeCrashListener ncl = new NativeCrashListener(this);
2329        ncl.start();
2330    }
2331
2332    public IAppOpsService getAppOpsService() {
2333        return mAppOpsService;
2334    }
2335
2336    static class MemBinder extends Binder {
2337        ActivityManagerService mActivityManagerService;
2338        MemBinder(ActivityManagerService activityManagerService) {
2339            mActivityManagerService = activityManagerService;
2340        }
2341
2342        @Override
2343        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2344            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2345                    != PackageManager.PERMISSION_GRANTED) {
2346                pw.println("Permission Denial: can't dump meminfo from from pid="
2347                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2348                        + " without permission " + android.Manifest.permission.DUMP);
2349                return;
2350            }
2351
2352            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2353        }
2354    }
2355
2356    static class GraphicsBinder extends Binder {
2357        ActivityManagerService mActivityManagerService;
2358        GraphicsBinder(ActivityManagerService activityManagerService) {
2359            mActivityManagerService = activityManagerService;
2360        }
2361
2362        @Override
2363        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2364            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2365                    != PackageManager.PERMISSION_GRANTED) {
2366                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2367                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2368                        + " without permission " + android.Manifest.permission.DUMP);
2369                return;
2370            }
2371
2372            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2373        }
2374    }
2375
2376    static class DbBinder extends Binder {
2377        ActivityManagerService mActivityManagerService;
2378        DbBinder(ActivityManagerService activityManagerService) {
2379            mActivityManagerService = activityManagerService;
2380        }
2381
2382        @Override
2383        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2384            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2385                    != PackageManager.PERMISSION_GRANTED) {
2386                pw.println("Permission Denial: can't dump dbinfo from from pid="
2387                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2388                        + " without permission " + android.Manifest.permission.DUMP);
2389                return;
2390            }
2391
2392            mActivityManagerService.dumpDbInfo(fd, pw, args);
2393        }
2394    }
2395
2396    static class CpuBinder extends Binder {
2397        ActivityManagerService mActivityManagerService;
2398        CpuBinder(ActivityManagerService activityManagerService) {
2399            mActivityManagerService = activityManagerService;
2400        }
2401
2402        @Override
2403        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2404            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2405                    != PackageManager.PERMISSION_GRANTED) {
2406                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2407                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2408                        + " without permission " + android.Manifest.permission.DUMP);
2409                return;
2410            }
2411
2412            synchronized (mActivityManagerService.mProcessCpuTracker) {
2413                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2414                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2415                        SystemClock.uptimeMillis()));
2416            }
2417        }
2418    }
2419
2420    public static final class Lifecycle extends SystemService {
2421        private final ActivityManagerService mService;
2422
2423        public Lifecycle(Context context) {
2424            super(context);
2425            mService = new ActivityManagerService(context);
2426        }
2427
2428        @Override
2429        public void onStart() {
2430            mService.start();
2431        }
2432
2433        public ActivityManagerService getService() {
2434            return mService;
2435        }
2436    }
2437
2438    // Note: This method is invoked on the main thread but may need to attach various
2439    // handlers to other threads.  So take care to be explicit about the looper.
2440    public ActivityManagerService(Context systemContext) {
2441        mContext = systemContext;
2442        mFactoryTest = FactoryTest.getMode();
2443        mSystemThread = ActivityThread.currentActivityThread();
2444
2445        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2446
2447        mHandlerThread = new ServiceThread(TAG,
2448                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2449        mHandlerThread.start();
2450        mHandler = new MainHandler(mHandlerThread.getLooper());
2451        mUiHandler = new UiHandler();
2452
2453        mProcessStartLogger = new ProcessStartLogger();
2454
2455        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2456                "foreground", BROADCAST_FG_TIMEOUT, false);
2457        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2458                "background", BROADCAST_BG_TIMEOUT, true);
2459        mBroadcastQueues[0] = mFgBroadcastQueue;
2460        mBroadcastQueues[1] = mBgBroadcastQueue;
2461
2462        mServices = new ActiveServices(this);
2463        mProviderMap = new ProviderMap(this);
2464        mAppErrors = new AppErrors(mContext, this);
2465
2466        // TODO: Move creation of battery stats service outside of activity manager service.
2467        File dataDir = Environment.getDataDirectory();
2468        File systemDir = new File(dataDir, "system");
2469        systemDir.mkdirs();
2470        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2471        mBatteryStatsService.getActiveStatistics().readLocked();
2472        mBatteryStatsService.scheduleWriteToDisk();
2473        mOnBattery = DEBUG_POWER ? true
2474                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2475        mBatteryStatsService.getActiveStatistics().setCallback(this);
2476
2477        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2478
2479        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2480        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2481                new IAppOpsCallback.Stub() {
2482                    @Override public void opChanged(int op, int uid, String packageName) {
2483                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2484                            if (mAppOpsService.checkOperation(op, uid, packageName)
2485                                    != AppOpsManager.MODE_ALLOWED) {
2486                                runInBackgroundDisabled(uid);
2487                            }
2488                        }
2489                    }
2490                });
2491
2492        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2493
2494        mUserController = new UserController(this);
2495
2496        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2497            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2498
2499        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2500
2501        mConfiguration.setToDefaults();
2502        mConfiguration.setLocales(LocaleList.getDefault());
2503
2504        mConfigurationSeq = mConfiguration.seq = 1;
2505        mProcessCpuTracker.init();
2506
2507        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2508        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2509        mStackSupervisor = new ActivityStackSupervisor(this);
2510        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2511        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2512
2513        mProcessCpuThread = new Thread("CpuTracker") {
2514            @Override
2515            public void run() {
2516                while (true) {
2517                    try {
2518                        try {
2519                            synchronized(this) {
2520                                final long now = SystemClock.uptimeMillis();
2521                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2522                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2523                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2524                                //        + ", write delay=" + nextWriteDelay);
2525                                if (nextWriteDelay < nextCpuDelay) {
2526                                    nextCpuDelay = nextWriteDelay;
2527                                }
2528                                if (nextCpuDelay > 0) {
2529                                    mProcessCpuMutexFree.set(true);
2530                                    this.wait(nextCpuDelay);
2531                                }
2532                            }
2533                        } catch (InterruptedException e) {
2534                        }
2535                        updateCpuStatsNow();
2536                    } catch (Exception e) {
2537                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2538                    }
2539                }
2540            }
2541        };
2542
2543        Watchdog.getInstance().addMonitor(this);
2544        Watchdog.getInstance().addThread(mHandler);
2545    }
2546
2547    public void setSystemServiceManager(SystemServiceManager mgr) {
2548        mSystemServiceManager = mgr;
2549    }
2550
2551    public void setInstaller(Installer installer) {
2552        mInstaller = installer;
2553    }
2554
2555    private void start() {
2556        Process.removeAllProcessGroups();
2557        mProcessCpuThread.start();
2558
2559        mBatteryStatsService.publish(mContext);
2560        mAppOpsService.publish(mContext);
2561        Slog.d("AppOps", "AppOpsService published");
2562        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2563    }
2564
2565    void onUserStoppedLocked(int userId) {
2566        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2567    }
2568
2569    public void initPowerManagement() {
2570        mStackSupervisor.initPowerManagement();
2571        mBatteryStatsService.initPowerManagement();
2572        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2573        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2574        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2575        mVoiceWakeLock.setReferenceCounted(false);
2576    }
2577
2578    @Override
2579    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2580            throws RemoteException {
2581        if (code == SYSPROPS_TRANSACTION) {
2582            // We need to tell all apps about the system property change.
2583            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2584            synchronized(this) {
2585                final int NP = mProcessNames.getMap().size();
2586                for (int ip=0; ip<NP; ip++) {
2587                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2588                    final int NA = apps.size();
2589                    for (int ia=0; ia<NA; ia++) {
2590                        ProcessRecord app = apps.valueAt(ia);
2591                        if (app.thread != null) {
2592                            procs.add(app.thread.asBinder());
2593                        }
2594                    }
2595                }
2596            }
2597
2598            int N = procs.size();
2599            for (int i=0; i<N; i++) {
2600                Parcel data2 = Parcel.obtain();
2601                try {
2602                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2603                } catch (RemoteException e) {
2604                }
2605                data2.recycle();
2606            }
2607        }
2608        try {
2609            return super.onTransact(code, data, reply, flags);
2610        } catch (RuntimeException e) {
2611            // The activity manager only throws security exceptions, so let's
2612            // log all others.
2613            if (!(e instanceof SecurityException)) {
2614                Slog.wtf(TAG, "Activity Manager Crash", e);
2615            }
2616            throw e;
2617        }
2618    }
2619
2620    void updateCpuStats() {
2621        final long now = SystemClock.uptimeMillis();
2622        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2623            return;
2624        }
2625        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2626            synchronized (mProcessCpuThread) {
2627                mProcessCpuThread.notify();
2628            }
2629        }
2630    }
2631
2632    void updateCpuStatsNow() {
2633        synchronized (mProcessCpuTracker) {
2634            mProcessCpuMutexFree.set(false);
2635            final long now = SystemClock.uptimeMillis();
2636            boolean haveNewCpuStats = false;
2637
2638            if (MONITOR_CPU_USAGE &&
2639                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2640                mLastCpuTime.set(now);
2641                mProcessCpuTracker.update();
2642                if (mProcessCpuTracker.hasGoodLastStats()) {
2643                    haveNewCpuStats = true;
2644                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2645                    //Slog.i(TAG, "Total CPU usage: "
2646                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2647
2648                    // Slog the cpu usage if the property is set.
2649                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2650                        int user = mProcessCpuTracker.getLastUserTime();
2651                        int system = mProcessCpuTracker.getLastSystemTime();
2652                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2653                        int irq = mProcessCpuTracker.getLastIrqTime();
2654                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2655                        int idle = mProcessCpuTracker.getLastIdleTime();
2656
2657                        int total = user + system + iowait + irq + softIrq + idle;
2658                        if (total == 0) total = 1;
2659
2660                        EventLog.writeEvent(EventLogTags.CPU,
2661                                ((user+system+iowait+irq+softIrq) * 100) / total,
2662                                (user * 100) / total,
2663                                (system * 100) / total,
2664                                (iowait * 100) / total,
2665                                (irq * 100) / total,
2666                                (softIrq * 100) / total);
2667                    }
2668                }
2669            }
2670
2671            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2672            synchronized(bstats) {
2673                synchronized(mPidsSelfLocked) {
2674                    if (haveNewCpuStats) {
2675                        if (bstats.startAddingCpuLocked()) {
2676                            int totalUTime = 0;
2677                            int totalSTime = 0;
2678                            final int N = mProcessCpuTracker.countStats();
2679                            for (int i=0; i<N; i++) {
2680                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2681                                if (!st.working) {
2682                                    continue;
2683                                }
2684                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2685                                totalUTime += st.rel_utime;
2686                                totalSTime += st.rel_stime;
2687                                if (pr != null) {
2688                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2689                                    if (ps == null || !ps.isActive()) {
2690                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2691                                                pr.info.uid, pr.processName);
2692                                    }
2693                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2694                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2695                                } else {
2696                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2697                                    if (ps == null || !ps.isActive()) {
2698                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2699                                                bstats.mapUid(st.uid), st.name);
2700                                    }
2701                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2702                                }
2703                            }
2704                            final int userTime = mProcessCpuTracker.getLastUserTime();
2705                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2706                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2707                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2708                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2709                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2710                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2711                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2712                        }
2713                    }
2714                }
2715
2716                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2717                    mLastWriteTime = now;
2718                    mBatteryStatsService.scheduleWriteToDisk();
2719                }
2720            }
2721        }
2722    }
2723
2724    @Override
2725    public void batteryNeedsCpuUpdate() {
2726        updateCpuStatsNow();
2727    }
2728
2729    @Override
2730    public void batteryPowerChanged(boolean onBattery) {
2731        // When plugging in, update the CPU stats first before changing
2732        // the plug state.
2733        updateCpuStatsNow();
2734        synchronized (this) {
2735            synchronized(mPidsSelfLocked) {
2736                mOnBattery = DEBUG_POWER ? true : onBattery;
2737            }
2738        }
2739    }
2740
2741    @Override
2742    public void batterySendBroadcast(Intent intent) {
2743        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2744                AppOpsManager.OP_NONE, null, false, false,
2745                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2746    }
2747
2748    /**
2749     * Initialize the application bind args. These are passed to each
2750     * process when the bindApplication() IPC is sent to the process. They're
2751     * lazily setup to make sure the services are running when they're asked for.
2752     */
2753    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2754        if (mAppBindArgs == null) {
2755            mAppBindArgs = new HashMap<>();
2756
2757            // Isolated processes won't get this optimization, so that we don't
2758            // violate the rules about which services they have access to.
2759            if (!isolated) {
2760                // Setup the application init args
2761                mAppBindArgs.put("package", ServiceManager.getService("package"));
2762                mAppBindArgs.put("window", ServiceManager.getService("window"));
2763                mAppBindArgs.put(Context.ALARM_SERVICE,
2764                        ServiceManager.getService(Context.ALARM_SERVICE));
2765            }
2766        }
2767        return mAppBindArgs;
2768    }
2769
2770    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2771        if (r == null || mFocusedActivity == r) {
2772            return false;
2773        }
2774
2775        if (!r.isFocusable()) {
2776            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2777            return false;
2778        }
2779
2780        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2781
2782        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2783        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2784                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2785        mDoingSetFocusedActivity = true;
2786
2787        final ActivityRecord last = mFocusedActivity;
2788        mFocusedActivity = r;
2789        if (r.task.isApplicationTask()) {
2790            if (mCurAppTimeTracker != r.appTimeTracker) {
2791                // We are switching app tracking.  Complete the current one.
2792                if (mCurAppTimeTracker != null) {
2793                    mCurAppTimeTracker.stop();
2794                    mHandler.obtainMessage(
2795                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2796                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2797                    mCurAppTimeTracker = null;
2798                }
2799                if (r.appTimeTracker != null) {
2800                    mCurAppTimeTracker = r.appTimeTracker;
2801                    startTimeTrackingFocusedActivityLocked();
2802                }
2803            } else {
2804                startTimeTrackingFocusedActivityLocked();
2805            }
2806        } else {
2807            r.appTimeTracker = null;
2808        }
2809        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2810        // TODO: Probably not, because we don't want to resume voice on switching
2811        // back to this activity
2812        if (r.task.voiceInteractor != null) {
2813            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2814        } else {
2815            finishRunningVoiceLocked();
2816            IVoiceInteractionSession session;
2817            if (last != null && ((session = last.task.voiceSession) != null
2818                    || (session = last.voiceSession) != null)) {
2819                // We had been in a voice interaction session, but now focused has
2820                // move to something different.  Just finish the session, we can't
2821                // return to it and retain the proper state and synchronization with
2822                // the voice interaction service.
2823                finishVoiceTask(session);
2824            }
2825        }
2826        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2827            mWindowManager.setFocusedApp(r.appToken, true);
2828        }
2829        applyUpdateLockStateLocked(r);
2830        applyUpdateVrModeLocked(r);
2831        if (mFocusedActivity.userId != mLastFocusedUserId) {
2832            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2833            mHandler.obtainMessage(
2834                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2835            mLastFocusedUserId = mFocusedActivity.userId;
2836        }
2837
2838        // Log a warning if the focused app is changed during the process. This could
2839        // indicate a problem of the focus setting logic!
2840        if (mFocusedActivity != r) Slog.w(TAG,
2841                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2842        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2843
2844        EventLogTags.writeAmFocusedActivity(
2845                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2846                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2847                reason);
2848        return true;
2849    }
2850
2851    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2852        if (mFocusedActivity != goingAway) {
2853            return;
2854        }
2855
2856        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2857        if (focusedStack != null) {
2858            final ActivityRecord top = focusedStack.topActivity();
2859            if (top != null && top.userId != mLastFocusedUserId) {
2860                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2861                mHandler.sendMessage(
2862                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2863                mLastFocusedUserId = top.userId;
2864            }
2865        }
2866
2867        // Try to move focus to another activity if possible.
2868        if (setFocusedActivityLocked(
2869                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2870            return;
2871        }
2872
2873        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2874                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2875        mFocusedActivity = null;
2876        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2877    }
2878
2879    @Override
2880    public void setFocusedStack(int stackId) {
2881        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2882        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2883        final long callingId = Binder.clearCallingIdentity();
2884        try {
2885            synchronized (this) {
2886                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2887                if (stack == null) {
2888                    return;
2889                }
2890                final ActivityRecord r = stack.topRunningActivityLocked();
2891                if (setFocusedActivityLocked(r, "setFocusedStack")) {
2892                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2893                }
2894            }
2895        } finally {
2896            Binder.restoreCallingIdentity(callingId);
2897        }
2898    }
2899
2900    @Override
2901    public void setFocusedTask(int taskId) {
2902        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2903        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2904        final long callingId = Binder.clearCallingIdentity();
2905        try {
2906            synchronized (this) {
2907                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2908                if (task == null) {
2909                    return;
2910                }
2911                final ActivityRecord r = task.topRunningActivityLocked();
2912                if (setFocusedActivityLocked(r, "setFocusedTask")) {
2913                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2914                }
2915            }
2916        } finally {
2917            Binder.restoreCallingIdentity(callingId);
2918        }
2919    }
2920
2921    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2922    @Override
2923    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2924        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
2925        synchronized (this) {
2926            if (listener != null) {
2927                mTaskStackListeners.register(listener);
2928            }
2929        }
2930    }
2931
2932    @Override
2933    public void notifyActivityDrawn(IBinder token) {
2934        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2935        synchronized (this) {
2936            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2937            if (r != null) {
2938                r.task.stack.notifyActivityDrawnLocked(r);
2939            }
2940        }
2941    }
2942
2943    final void applyUpdateLockStateLocked(ActivityRecord r) {
2944        // Modifications to the UpdateLock state are done on our handler, outside
2945        // the activity manager's locks.  The new state is determined based on the
2946        // state *now* of the relevant activity record.  The object is passed to
2947        // the handler solely for logging detail, not to be consulted/modified.
2948        final boolean nextState = r != null && r.immersive;
2949        mHandler.sendMessage(
2950                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2951    }
2952
2953    final void applyUpdateVrModeLocked(ActivityRecord r) {
2954        mHandler.sendMessage(
2955                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
2956    }
2957
2958    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2959        Message msg = Message.obtain();
2960        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
2961        msg.obj = r.task.askedCompatMode ? null : r;
2962        mUiHandler.sendMessage(msg);
2963    }
2964
2965    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2966            String what, Object obj, ProcessRecord srcApp) {
2967        app.lastActivityTime = now;
2968
2969        if (app.activities.size() > 0) {
2970            // Don't want to touch dependent processes that are hosting activities.
2971            return index;
2972        }
2973
2974        int lrui = mLruProcesses.lastIndexOf(app);
2975        if (lrui < 0) {
2976            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2977                    + what + " " + obj + " from " + srcApp);
2978            return index;
2979        }
2980
2981        if (lrui >= index) {
2982            // Don't want to cause this to move dependent processes *back* in the
2983            // list as if they were less frequently used.
2984            return index;
2985        }
2986
2987        if (lrui >= mLruProcessActivityStart) {
2988            // Don't want to touch dependent processes that are hosting activities.
2989            return index;
2990        }
2991
2992        mLruProcesses.remove(lrui);
2993        if (index > 0) {
2994            index--;
2995        }
2996        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2997                + " in LRU list: " + app);
2998        mLruProcesses.add(index, app);
2999        return index;
3000    }
3001
3002    static void killProcessGroup(int uid, int pid) {
3003        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
3004        Process.killProcessGroup(uid, pid);
3005        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3006    }
3007
3008    final void removeLruProcessLocked(ProcessRecord app) {
3009        int lrui = mLruProcesses.lastIndexOf(app);
3010        if (lrui >= 0) {
3011            if (!app.killed) {
3012                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3013                Process.killProcessQuiet(app.pid);
3014                killProcessGroup(app.info.uid, app.pid);
3015            }
3016            if (lrui <= mLruProcessActivityStart) {
3017                mLruProcessActivityStart--;
3018            }
3019            if (lrui <= mLruProcessServiceStart) {
3020                mLruProcessServiceStart--;
3021            }
3022            mLruProcesses.remove(lrui);
3023        }
3024    }
3025
3026    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3027            ProcessRecord client) {
3028        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3029                || app.treatLikeActivity;
3030        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3031        if (!activityChange && hasActivity) {
3032            // The process has activities, so we are only allowing activity-based adjustments
3033            // to move it.  It should be kept in the front of the list with other
3034            // processes that have activities, and we don't want those to change their
3035            // order except due to activity operations.
3036            return;
3037        }
3038
3039        mLruSeq++;
3040        final long now = SystemClock.uptimeMillis();
3041        app.lastActivityTime = now;
3042
3043        // First a quick reject: if the app is already at the position we will
3044        // put it, then there is nothing to do.
3045        if (hasActivity) {
3046            final int N = mLruProcesses.size();
3047            if (N > 0 && mLruProcesses.get(N-1) == app) {
3048                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3049                return;
3050            }
3051        } else {
3052            if (mLruProcessServiceStart > 0
3053                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3054                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3055                return;
3056            }
3057        }
3058
3059        int lrui = mLruProcesses.lastIndexOf(app);
3060
3061        if (app.persistent && lrui >= 0) {
3062            // We don't care about the position of persistent processes, as long as
3063            // they are in the list.
3064            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3065            return;
3066        }
3067
3068        /* In progress: compute new position first, so we can avoid doing work
3069           if the process is not actually going to move.  Not yet working.
3070        int addIndex;
3071        int nextIndex;
3072        boolean inActivity = false, inService = false;
3073        if (hasActivity) {
3074            // Process has activities, put it at the very tipsy-top.
3075            addIndex = mLruProcesses.size();
3076            nextIndex = mLruProcessServiceStart;
3077            inActivity = true;
3078        } else if (hasService) {
3079            // Process has services, put it at the top of the service list.
3080            addIndex = mLruProcessActivityStart;
3081            nextIndex = mLruProcessServiceStart;
3082            inActivity = true;
3083            inService = true;
3084        } else  {
3085            // Process not otherwise of interest, it goes to the top of the non-service area.
3086            addIndex = mLruProcessServiceStart;
3087            if (client != null) {
3088                int clientIndex = mLruProcesses.lastIndexOf(client);
3089                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3090                        + app);
3091                if (clientIndex >= 0 && addIndex > clientIndex) {
3092                    addIndex = clientIndex;
3093                }
3094            }
3095            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3096        }
3097
3098        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3099                + mLruProcessActivityStart + "): " + app);
3100        */
3101
3102        if (lrui >= 0) {
3103            if (lrui < mLruProcessActivityStart) {
3104                mLruProcessActivityStart--;
3105            }
3106            if (lrui < mLruProcessServiceStart) {
3107                mLruProcessServiceStart--;
3108            }
3109            /*
3110            if (addIndex > lrui) {
3111                addIndex--;
3112            }
3113            if (nextIndex > lrui) {
3114                nextIndex--;
3115            }
3116            */
3117            mLruProcesses.remove(lrui);
3118        }
3119
3120        /*
3121        mLruProcesses.add(addIndex, app);
3122        if (inActivity) {
3123            mLruProcessActivityStart++;
3124        }
3125        if (inService) {
3126            mLruProcessActivityStart++;
3127        }
3128        */
3129
3130        int nextIndex;
3131        if (hasActivity) {
3132            final int N = mLruProcesses.size();
3133            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3134                // Process doesn't have activities, but has clients with
3135                // activities...  move it up, but one below the top (the top
3136                // should always have a real activity).
3137                if (DEBUG_LRU) Slog.d(TAG_LRU,
3138                        "Adding to second-top of LRU activity list: " + app);
3139                mLruProcesses.add(N - 1, app);
3140                // To keep it from spamming the LRU list (by making a bunch of clients),
3141                // we will push down any other entries owned by the app.
3142                final int uid = app.info.uid;
3143                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3144                    ProcessRecord subProc = mLruProcesses.get(i);
3145                    if (subProc.info.uid == uid) {
3146                        // We want to push this one down the list.  If the process after
3147                        // it is for the same uid, however, don't do so, because we don't
3148                        // want them internally to be re-ordered.
3149                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3150                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3151                                    "Pushing uid " + uid + " swapping at " + i + ": "
3152                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3153                            ProcessRecord tmp = mLruProcesses.get(i);
3154                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3155                            mLruProcesses.set(i - 1, tmp);
3156                            i--;
3157                        }
3158                    } else {
3159                        // A gap, we can stop here.
3160                        break;
3161                    }
3162                }
3163            } else {
3164                // Process has activities, put it at the very tipsy-top.
3165                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3166                mLruProcesses.add(app);
3167            }
3168            nextIndex = mLruProcessServiceStart;
3169        } else if (hasService) {
3170            // Process has services, put it at the top of the service list.
3171            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3172            mLruProcesses.add(mLruProcessActivityStart, app);
3173            nextIndex = mLruProcessServiceStart;
3174            mLruProcessActivityStart++;
3175        } else  {
3176            // Process not otherwise of interest, it goes to the top of the non-service area.
3177            int index = mLruProcessServiceStart;
3178            if (client != null) {
3179                // If there is a client, don't allow the process to be moved up higher
3180                // in the list than that client.
3181                int clientIndex = mLruProcesses.lastIndexOf(client);
3182                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3183                        + " when updating " + app);
3184                if (clientIndex <= lrui) {
3185                    // Don't allow the client index restriction to push it down farther in the
3186                    // list than it already is.
3187                    clientIndex = lrui;
3188                }
3189                if (clientIndex >= 0 && index > clientIndex) {
3190                    index = clientIndex;
3191                }
3192            }
3193            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3194            mLruProcesses.add(index, app);
3195            nextIndex = index-1;
3196            mLruProcessActivityStart++;
3197            mLruProcessServiceStart++;
3198        }
3199
3200        // If the app is currently using a content provider or service,
3201        // bump those processes as well.
3202        for (int j=app.connections.size()-1; j>=0; j--) {
3203            ConnectionRecord cr = app.connections.valueAt(j);
3204            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3205                    && cr.binding.service.app != null
3206                    && cr.binding.service.app.lruSeq != mLruSeq
3207                    && !cr.binding.service.app.persistent) {
3208                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3209                        "service connection", cr, app);
3210            }
3211        }
3212        for (int j=app.conProviders.size()-1; j>=0; j--) {
3213            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3214            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3215                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3216                        "provider reference", cpr, app);
3217            }
3218        }
3219    }
3220
3221    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3222        if (uid == Process.SYSTEM_UID) {
3223            // The system gets to run in any process.  If there are multiple
3224            // processes with the same uid, just pick the first (this
3225            // should never happen).
3226            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3227            if (procs == null) return null;
3228            final int procCount = procs.size();
3229            for (int i = 0; i < procCount; i++) {
3230                final int procUid = procs.keyAt(i);
3231                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3232                    // Don't use an app process or different user process for system component.
3233                    continue;
3234                }
3235                return procs.valueAt(i);
3236            }
3237        }
3238        ProcessRecord proc = mProcessNames.get(processName, uid);
3239        if (false && proc != null && !keepIfLarge
3240                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3241                && proc.lastCachedPss >= 4000) {
3242            // Turn this condition on to cause killing to happen regularly, for testing.
3243            if (proc.baseProcessTracker != null) {
3244                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3245            }
3246            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3247        } else if (proc != null && !keepIfLarge
3248                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3249                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3250            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3251            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3252                if (proc.baseProcessTracker != null) {
3253                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3254                }
3255                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3256            }
3257        }
3258        return proc;
3259    }
3260
3261    void notifyPackageUse(String packageName) {
3262        IPackageManager pm = AppGlobals.getPackageManager();
3263        try {
3264            pm.notifyPackageUse(packageName);
3265        } catch (RemoteException e) {
3266        }
3267    }
3268
3269    boolean isNextTransitionForward() {
3270        int transit = mWindowManager.getPendingAppTransition();
3271        return transit == TRANSIT_ACTIVITY_OPEN
3272                || transit == TRANSIT_TASK_OPEN
3273                || transit == TRANSIT_TASK_TO_FRONT;
3274    }
3275
3276    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3277            String processName, String abiOverride, int uid, Runnable crashHandler) {
3278        synchronized(this) {
3279            ApplicationInfo info = new ApplicationInfo();
3280            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3281            // For isolated processes, the former contains the parent's uid and the latter the
3282            // actual uid of the isolated process.
3283            // In the special case introduced by this method (which is, starting an isolated
3284            // process directly from the SystemServer without an actual parent app process) the
3285            // closest thing to a parent's uid is SYSTEM_UID.
3286            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3287            // the |isolated| logic in the ProcessRecord constructor.
3288            info.uid = Process.SYSTEM_UID;
3289            info.processName = processName;
3290            info.className = entryPoint;
3291            info.packageName = "android";
3292            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3293                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3294                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3295                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3296                    crashHandler);
3297            return proc != null ? proc.pid : 0;
3298        }
3299    }
3300
3301    final ProcessRecord startProcessLocked(String processName,
3302            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3303            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3304            boolean isolated, boolean keepIfLarge) {
3305        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3306                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3307                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3308                null /* crashHandler */);
3309    }
3310
3311    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3312            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3313            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3314            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3315        long startTime = SystemClock.elapsedRealtime();
3316        ProcessRecord app;
3317        if (!isolated) {
3318            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3319            checkTime(startTime, "startProcess: after getProcessRecord");
3320
3321            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3322                // If we are in the background, then check to see if this process
3323                // is bad.  If so, we will just silently fail.
3324                if (mAppErrors.isBadProcessLocked(info)) {
3325                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3326                            + "/" + info.processName);
3327                    return null;
3328                }
3329            } else {
3330                // When the user is explicitly starting a process, then clear its
3331                // crash count so that we won't make it bad until they see at
3332                // least one crash dialog again, and make the process good again
3333                // if it had been bad.
3334                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3335                        + "/" + info.processName);
3336                mAppErrors.resetProcessCrashTimeLocked(info);
3337                if (mAppErrors.isBadProcessLocked(info)) {
3338                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3339                            UserHandle.getUserId(info.uid), info.uid,
3340                            info.processName);
3341                    mAppErrors.clearBadProcessLocked(info);
3342                    if (app != null) {
3343                        app.bad = false;
3344                    }
3345                }
3346            }
3347        } else {
3348            // If this is an isolated process, it can't re-use an existing process.
3349            app = null;
3350        }
3351
3352        // app launch boost for big.little configurations
3353        // use cpusets to migrate freshly launched tasks to big cores
3354        synchronized(ActivityManagerService.this) {
3355            nativeMigrateToBoost();
3356            mIsBoosted = true;
3357            mBoostStartTime = SystemClock.uptimeMillis();
3358            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3359            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3360        }
3361
3362        // We don't have to do anything more if:
3363        // (1) There is an existing application record; and
3364        // (2) The caller doesn't think it is dead, OR there is no thread
3365        //     object attached to it so we know it couldn't have crashed; and
3366        // (3) There is a pid assigned to it, so it is either starting or
3367        //     already running.
3368        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3369                + " app=" + app + " knownToBeDead=" + knownToBeDead
3370                + " thread=" + (app != null ? app.thread : null)
3371                + " pid=" + (app != null ? app.pid : -1));
3372        if (app != null && app.pid > 0) {
3373            if (!knownToBeDead || app.thread == null) {
3374                // We already have the app running, or are waiting for it to
3375                // come up (we have a pid but not yet its thread), so keep it.
3376                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3377                // If this is a new package in the process, add the package to the list
3378                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3379                checkTime(startTime, "startProcess: done, added package to proc");
3380                return app;
3381            }
3382
3383            // An application record is attached to a previous process,
3384            // clean it up now.
3385            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3386            checkTime(startTime, "startProcess: bad proc running, killing");
3387            killProcessGroup(app.info.uid, app.pid);
3388            handleAppDiedLocked(app, true, true);
3389            checkTime(startTime, "startProcess: done killing old proc");
3390        }
3391
3392        String hostingNameStr = hostingName != null
3393                ? hostingName.flattenToShortString() : null;
3394
3395        if (app == null) {
3396            checkTime(startTime, "startProcess: creating new process record");
3397            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3398            if (app == null) {
3399                Slog.w(TAG, "Failed making new process record for "
3400                        + processName + "/" + info.uid + " isolated=" + isolated);
3401                return null;
3402            }
3403            app.crashHandler = crashHandler;
3404            checkTime(startTime, "startProcess: done creating new process record");
3405        } else {
3406            // If this is a new package in the process, add the package to the list
3407            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3408            checkTime(startTime, "startProcess: added package to existing proc");
3409        }
3410
3411        // If the system is not ready yet, then hold off on starting this
3412        // process until it is.
3413        if (!mProcessesReady
3414                && !isAllowedWhileBooting(info)
3415                && !allowWhileBooting) {
3416            if (!mProcessesOnHold.contains(app)) {
3417                mProcessesOnHold.add(app);
3418            }
3419            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3420                    "System not ready, putting on hold: " + app);
3421            checkTime(startTime, "startProcess: returning with proc on hold");
3422            return app;
3423        }
3424
3425        checkTime(startTime, "startProcess: stepping in to startProcess");
3426        startProcessLocked(
3427                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3428        checkTime(startTime, "startProcess: done starting proc!");
3429        return (app.pid != 0) ? app : null;
3430    }
3431
3432    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3433        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3434    }
3435
3436    private final void startProcessLocked(ProcessRecord app,
3437            String hostingType, String hostingNameStr) {
3438        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3439                null /* entryPoint */, null /* entryPointArgs */);
3440    }
3441
3442    private final void startProcessLocked(ProcessRecord app, String hostingType,
3443            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3444        long startTime = SystemClock.elapsedRealtime();
3445        if (app.pid > 0 && app.pid != MY_PID) {
3446            checkTime(startTime, "startProcess: removing from pids map");
3447            synchronized (mPidsSelfLocked) {
3448                mPidsSelfLocked.remove(app.pid);
3449                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3450            }
3451            checkTime(startTime, "startProcess: done removing from pids map");
3452            app.setPid(0);
3453        }
3454
3455        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3456                "startProcessLocked removing on hold: " + app);
3457        mProcessesOnHold.remove(app);
3458
3459        checkTime(startTime, "startProcess: starting to update cpu stats");
3460        updateCpuStats();
3461        checkTime(startTime, "startProcess: done updating cpu stats");
3462
3463        try {
3464            try {
3465                final int userId = UserHandle.getUserId(app.uid);
3466                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3467            } catch (RemoteException e) {
3468                throw e.rethrowAsRuntimeException();
3469            }
3470
3471            int uid = app.uid;
3472            int[] gids = null;
3473            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3474            if (!app.isolated) {
3475                int[] permGids = null;
3476                try {
3477                    checkTime(startTime, "startProcess: getting gids from package manager");
3478                    final IPackageManager pm = AppGlobals.getPackageManager();
3479                    permGids = pm.getPackageGids(app.info.packageName,
3480                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3481                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3482                            MountServiceInternal.class);
3483                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3484                            app.info.packageName);
3485                } catch (RemoteException e) {
3486                    throw e.rethrowAsRuntimeException();
3487                }
3488
3489                /*
3490                 * Add shared application and profile GIDs so applications can share some
3491                 * resources like shared libraries and access user-wide resources
3492                 */
3493                if (ArrayUtils.isEmpty(permGids)) {
3494                    gids = new int[2];
3495                } else {
3496                    gids = new int[permGids.length + 2];
3497                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3498                }
3499                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3500                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3501            }
3502            checkTime(startTime, "startProcess: building args");
3503            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3504                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3505                        && mTopComponent != null
3506                        && app.processName.equals(mTopComponent.getPackageName())) {
3507                    uid = 0;
3508                }
3509                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3510                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3511                    uid = 0;
3512                }
3513            }
3514            int debugFlags = 0;
3515            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3516                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3517                // Also turn on CheckJNI for debuggable apps. It's quite
3518                // awkward to turn on otherwise.
3519                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3520            }
3521            // Run the app in safe mode if its manifest requests so or the
3522            // system is booted in safe mode.
3523            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3524                mSafeMode == true) {
3525                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3526            }
3527            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3528                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3529            }
3530            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3531            if ("true".equals(genDebugInfoProperty)) {
3532                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3533            }
3534            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3535                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3536            }
3537            if ("1".equals(SystemProperties.get("debug.assert"))) {
3538                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3539            }
3540            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3541                // Enable all debug flags required by the native debugger.
3542                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3543                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3544                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3545                mNativeDebuggingApp = null;
3546            }
3547
3548            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3549            if (requiredAbi == null) {
3550                requiredAbi = Build.SUPPORTED_ABIS[0];
3551            }
3552
3553            String instructionSet = null;
3554            if (app.info.primaryCpuAbi != null) {
3555                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3556            }
3557
3558            app.gids = gids;
3559            app.requiredAbi = requiredAbi;
3560            app.instructionSet = instructionSet;
3561
3562            // Start the process.  It will either succeed and return a result containing
3563            // the PID of the new process, or else throw a RuntimeException.
3564            boolean isActivityProcess = (entryPoint == null);
3565            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3566            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3567                    app.processName);
3568            checkTime(startTime, "startProcess: asking zygote to start proc");
3569            Process.ProcessStartResult startResult = Process.start(entryPoint,
3570                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3571                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3572                    app.info.dataDir, entryPointArgs);
3573            checkTime(startTime, "startProcess: returned from zygote!");
3574            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3575
3576            if (app.isolated) {
3577                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3578            }
3579            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3580            checkTime(startTime, "startProcess: done updating battery stats");
3581
3582            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3583                    UserHandle.getUserId(uid), startResult.pid, uid,
3584                    app.processName, hostingType,
3585                    hostingNameStr != null ? hostingNameStr : "");
3586
3587            mProcessStartLogger.logIfNeededLocked(app, startResult);
3588
3589            if (app.persistent) {
3590                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3591            }
3592
3593            if (DEBUG_PROCESSES) {
3594                checkTime(startTime, "startProcess: building log message");
3595                StringBuilder buf = mStringBuilder;
3596                buf.setLength(0);
3597                buf.append("Start proc ");
3598                buf.append(startResult.pid);
3599                buf.append(':');
3600                buf.append(app.processName);
3601                buf.append('/');
3602                UserHandle.formatUid(buf, uid);
3603                if (!isActivityProcess) {
3604                    buf.append(" [");
3605                    buf.append(entryPoint);
3606                    buf.append("]");
3607                }
3608                buf.append(" for ");
3609                buf.append(hostingType);
3610                if (hostingNameStr != null) {
3611                    buf.append(" ");
3612                    buf.append(hostingNameStr);
3613                }
3614                Slog.i(TAG, buf.toString());
3615            }
3616            app.setPid(startResult.pid);
3617            app.usingWrapper = startResult.usingWrapper;
3618            app.removed = false;
3619            app.killed = false;
3620            app.killedByAm = false;
3621            checkTime(startTime, "startProcess: starting to update pids map");
3622            synchronized (mPidsSelfLocked) {
3623                this.mPidsSelfLocked.put(startResult.pid, app);
3624                if (isActivityProcess) {
3625                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3626                    msg.obj = app;
3627                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3628                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3629                }
3630            }
3631            checkTime(startTime, "startProcess: done updating pids map");
3632        } catch (RuntimeException e) {
3633            // XXX do better error recovery.
3634            app.setPid(0);
3635            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3636            if (app.isolated) {
3637                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3638            }
3639            Slog.e(TAG, "Failure starting process " + app.processName, e);
3640        }
3641    }
3642
3643    void updateUsageStats(ActivityRecord component, boolean resumed) {
3644        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3645                "updateUsageStats: comp=" + component + "res=" + resumed);
3646        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3647        if (resumed) {
3648            if (mUsageStatsService != null) {
3649                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3650                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3651            }
3652            synchronized (stats) {
3653                stats.noteActivityResumedLocked(component.app.uid);
3654            }
3655        } else {
3656            if (mUsageStatsService != null) {
3657                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3658                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3659            }
3660            synchronized (stats) {
3661                stats.noteActivityPausedLocked(component.app.uid);
3662            }
3663        }
3664    }
3665
3666    Intent getHomeIntent() {
3667        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3668        intent.setComponent(mTopComponent);
3669        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3670        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3671            intent.addCategory(Intent.CATEGORY_HOME);
3672        }
3673        return intent;
3674    }
3675
3676    boolean startHomeActivityLocked(int userId, String reason) {
3677        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3678                && mTopAction == null) {
3679            // We are running in factory test mode, but unable to find
3680            // the factory test app, so just sit around displaying the
3681            // error message and don't try to start anything.
3682            return false;
3683        }
3684        Intent intent = getHomeIntent();
3685        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3686        if (aInfo != null) {
3687            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3688            // Don't do this if the home app is currently being
3689            // instrumented.
3690            aInfo = new ActivityInfo(aInfo);
3691            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3692            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3693                    aInfo.applicationInfo.uid, true);
3694            if (app == null || app.instrumentationClass == null) {
3695                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3696                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3697            }
3698        }
3699
3700        return true;
3701    }
3702
3703    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3704        ActivityInfo ai = null;
3705        ComponentName comp = intent.getComponent();
3706        try {
3707            if (comp != null) {
3708                // Factory test.
3709                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3710            } else {
3711                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3712                        intent,
3713                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3714                        flags, userId);
3715
3716                if (info != null) {
3717                    ai = info.activityInfo;
3718                }
3719            }
3720        } catch (RemoteException e) {
3721            // ignore
3722        }
3723
3724        return ai;
3725    }
3726
3727    /**
3728     * Starts the "new version setup screen" if appropriate.
3729     */
3730    void startSetupActivityLocked() {
3731        // Only do this once per boot.
3732        if (mCheckedForSetup) {
3733            return;
3734        }
3735
3736        // We will show this screen if the current one is a different
3737        // version than the last one shown, and we are not running in
3738        // low-level factory test mode.
3739        final ContentResolver resolver = mContext.getContentResolver();
3740        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3741                Settings.Global.getInt(resolver,
3742                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3743            mCheckedForSetup = true;
3744
3745            // See if we should be showing the platform update setup UI.
3746            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3747            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3748                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3749            if (!ris.isEmpty()) {
3750                final ResolveInfo ri = ris.get(0);
3751                String vers = ri.activityInfo.metaData != null
3752                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3753                        : null;
3754                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3755                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3756                            Intent.METADATA_SETUP_VERSION);
3757                }
3758                String lastVers = Settings.Secure.getString(
3759                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3760                if (vers != null && !vers.equals(lastVers)) {
3761                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3762                    intent.setComponent(new ComponentName(
3763                            ri.activityInfo.packageName, ri.activityInfo.name));
3764                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3765                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3766                            null, 0, 0, 0, null, false, false, null, null, null);
3767                }
3768            }
3769        }
3770    }
3771
3772    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3773        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3774    }
3775
3776    void enforceNotIsolatedCaller(String caller) {
3777        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3778            throw new SecurityException("Isolated process not allowed to call " + caller);
3779        }
3780    }
3781
3782    void enforceShellRestriction(String restriction, int userHandle) {
3783        if (Binder.getCallingUid() == Process.SHELL_UID) {
3784            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3785                throw new SecurityException("Shell does not have permission to access user "
3786                        + userHandle);
3787            }
3788        }
3789    }
3790
3791    @Override
3792    public int getFrontActivityScreenCompatMode() {
3793        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3794        synchronized (this) {
3795            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3796        }
3797    }
3798
3799    @Override
3800    public void setFrontActivityScreenCompatMode(int mode) {
3801        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3802                "setFrontActivityScreenCompatMode");
3803        synchronized (this) {
3804            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3805        }
3806    }
3807
3808    @Override
3809    public int getPackageScreenCompatMode(String packageName) {
3810        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3811        synchronized (this) {
3812            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3813        }
3814    }
3815
3816    @Override
3817    public void setPackageScreenCompatMode(String packageName, int mode) {
3818        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3819                "setPackageScreenCompatMode");
3820        synchronized (this) {
3821            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3822        }
3823    }
3824
3825    @Override
3826    public boolean getPackageAskScreenCompat(String packageName) {
3827        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3828        synchronized (this) {
3829            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3830        }
3831    }
3832
3833    @Override
3834    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3835        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3836                "setPackageAskScreenCompat");
3837        synchronized (this) {
3838            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3839        }
3840    }
3841
3842    private boolean hasUsageStatsPermission(String callingPackage) {
3843        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3844                Binder.getCallingUid(), callingPackage);
3845        if (mode == AppOpsManager.MODE_DEFAULT) {
3846            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3847                    == PackageManager.PERMISSION_GRANTED;
3848        }
3849        return mode == AppOpsManager.MODE_ALLOWED;
3850    }
3851
3852    @Override
3853    public int getPackageProcessState(String packageName, String callingPackage) {
3854        if (!hasUsageStatsPermission(callingPackage)) {
3855            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3856                    "getPackageProcessState");
3857        }
3858
3859        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3860        synchronized (this) {
3861            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3862                final ProcessRecord proc = mLruProcesses.get(i);
3863                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3864                        || procState > proc.setProcState) {
3865                    boolean found = false;
3866                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3867                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3868                            procState = proc.setProcState;
3869                            found = true;
3870                        }
3871                    }
3872                    if (proc.pkgDeps != null && !found) {
3873                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3874                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3875                                procState = proc.setProcState;
3876                                break;
3877                            }
3878                        }
3879                    }
3880                }
3881            }
3882        }
3883        return procState;
3884    }
3885
3886    @Override
3887    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3888        synchronized (this) {
3889            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3890            if (app == null) {
3891                return false;
3892            }
3893            if (app.trimMemoryLevel < level && app.thread != null &&
3894                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3895                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3896                try {
3897                    app.thread.scheduleTrimMemory(level);
3898                    app.trimMemoryLevel = level;
3899                    return true;
3900                } catch (RemoteException e) {
3901                    // Fallthrough to failure case.
3902                }
3903            }
3904        }
3905        return false;
3906    }
3907
3908    private void dispatchProcessesChanged() {
3909        int N;
3910        synchronized (this) {
3911            N = mPendingProcessChanges.size();
3912            if (mActiveProcessChanges.length < N) {
3913                mActiveProcessChanges = new ProcessChangeItem[N];
3914            }
3915            mPendingProcessChanges.toArray(mActiveProcessChanges);
3916            mPendingProcessChanges.clear();
3917            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3918                    "*** Delivering " + N + " process changes");
3919        }
3920
3921        int i = mProcessObservers.beginBroadcast();
3922        while (i > 0) {
3923            i--;
3924            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3925            if (observer != null) {
3926                try {
3927                    for (int j=0; j<N; j++) {
3928                        ProcessChangeItem item = mActiveProcessChanges[j];
3929                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3930                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3931                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3932                                    + item.uid + ": " + item.foregroundActivities);
3933                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3934                                    item.foregroundActivities);
3935                        }
3936                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3937                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3938                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3939                                    + ": " + item.processState);
3940                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3941                        }
3942                    }
3943                } catch (RemoteException e) {
3944                }
3945            }
3946        }
3947        mProcessObservers.finishBroadcast();
3948
3949        synchronized (this) {
3950            for (int j=0; j<N; j++) {
3951                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3952            }
3953        }
3954    }
3955
3956    private void dispatchProcessDied(int pid, int uid) {
3957        int i = mProcessObservers.beginBroadcast();
3958        while (i > 0) {
3959            i--;
3960            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3961            if (observer != null) {
3962                try {
3963                    observer.onProcessDied(pid, uid);
3964                } catch (RemoteException e) {
3965                }
3966            }
3967        }
3968        mProcessObservers.finishBroadcast();
3969    }
3970
3971    private void dispatchUidsChanged() {
3972        int N;
3973        synchronized (this) {
3974            N = mPendingUidChanges.size();
3975            if (mActiveUidChanges.length < N) {
3976                mActiveUidChanges = new UidRecord.ChangeItem[N];
3977            }
3978            for (int i=0; i<N; i++) {
3979                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3980                mActiveUidChanges[i] = change;
3981                if (change.uidRecord != null) {
3982                    change.uidRecord.pendingChange = null;
3983                    change.uidRecord = null;
3984                }
3985            }
3986            mPendingUidChanges.clear();
3987            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3988                    "*** Delivering " + N + " uid changes");
3989        }
3990
3991        if (mLocalPowerManager != null) {
3992            for (int j=0; j<N; j++) {
3993                UidRecord.ChangeItem item = mActiveUidChanges[j];
3994                if (item.change == UidRecord.CHANGE_GONE
3995                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
3996                    mLocalPowerManager.uidGone(item.uid);
3997                } else {
3998                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3999                }
4000            }
4001        }
4002
4003        int i = mUidObservers.beginBroadcast();
4004        while (i > 0) {
4005            i--;
4006            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4007            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4008            if (observer != null) {
4009                try {
4010                    for (int j=0; j<N; j++) {
4011                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4012                        final int change = item.change;
4013                        UidRecord validateUid = null;
4014                        if (VALIDATE_UID_STATES && i == 0) {
4015                            validateUid = mValidateUids.get(item.uid);
4016                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4017                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4018                                validateUid = new UidRecord(item.uid);
4019                                mValidateUids.put(item.uid, validateUid);
4020                            }
4021                        }
4022                        if (change == UidRecord.CHANGE_IDLE
4023                                || change == UidRecord.CHANGE_GONE_IDLE) {
4024                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4025                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4026                                        "UID idle uid=" + item.uid);
4027                                observer.onUidIdle(item.uid);
4028                            }
4029                            if (VALIDATE_UID_STATES && i == 0) {
4030                                if (validateUid != null) {
4031                                    validateUid.idle = true;
4032                                }
4033                            }
4034                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4035                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4036                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4037                                        "UID active uid=" + item.uid);
4038                                observer.onUidActive(item.uid);
4039                            }
4040                            if (VALIDATE_UID_STATES && i == 0) {
4041                                validateUid.idle = false;
4042                            }
4043                        }
4044                        if (change == UidRecord.CHANGE_GONE
4045                                || change == UidRecord.CHANGE_GONE_IDLE) {
4046                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4047                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4048                                        "UID gone uid=" + item.uid);
4049                                observer.onUidGone(item.uid);
4050                            }
4051                            if (VALIDATE_UID_STATES && i == 0) {
4052                                if (validateUid != null) {
4053                                    mValidateUids.remove(item.uid);
4054                                }
4055                            }
4056                        } else {
4057                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4058                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4059                                        "UID CHANGED uid=" + item.uid
4060                                                + ": " + item.processState);
4061                                observer.onUidStateChanged(item.uid, item.processState);
4062                            }
4063                            if (VALIDATE_UID_STATES && i == 0) {
4064                                validateUid.curProcState = validateUid.setProcState
4065                                        = item.processState;
4066                            }
4067                        }
4068                    }
4069                } catch (RemoteException e) {
4070                }
4071            }
4072        }
4073        mUidObservers.finishBroadcast();
4074
4075        synchronized (this) {
4076            for (int j=0; j<N; j++) {
4077                mAvailUidChanges.add(mActiveUidChanges[j]);
4078            }
4079        }
4080    }
4081
4082    @Override
4083    public final int startActivity(IApplicationThread caller, String callingPackage,
4084            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4085            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4086        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4087                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4088                UserHandle.getCallingUserId());
4089    }
4090
4091    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4092        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4093        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4094                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4095                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4096
4097        // TODO: Switch to user app stacks here.
4098        String mimeType = intent.getType();
4099        final Uri data = intent.getData();
4100        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4101            mimeType = getProviderMimeType(data, userId);
4102        }
4103        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4104
4105        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4106        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4107                null, 0, 0, null, null, null, null, false, userId, container, null);
4108    }
4109
4110    @Override
4111    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4112            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4113            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4114        enforceNotIsolatedCaller("startActivity");
4115        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4116                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4117        // TODO: Switch to user app stacks here.
4118        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4119                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4120                profilerInfo, null, null, bOptions, false, userId, null, null);
4121    }
4122
4123    @Override
4124    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4125            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4126            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4127            int userId) {
4128
4129        // This is very dangerous -- it allows you to perform a start activity (including
4130        // permission grants) as any app that may launch one of your own activities.  So
4131        // we will only allow this to be done from activities that are part of the core framework,
4132        // and then only when they are running as the system.
4133        final ActivityRecord sourceRecord;
4134        final int targetUid;
4135        final String targetPackage;
4136        synchronized (this) {
4137            if (resultTo == null) {
4138                throw new SecurityException("Must be called from an activity");
4139            }
4140            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4141            if (sourceRecord == null) {
4142                throw new SecurityException("Called with bad activity token: " + resultTo);
4143            }
4144            if (!sourceRecord.info.packageName.equals("android")) {
4145                throw new SecurityException(
4146                        "Must be called from an activity that is declared in the android package");
4147            }
4148            if (sourceRecord.app == null) {
4149                throw new SecurityException("Called without a process attached to activity");
4150            }
4151            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4152                // This is still okay, as long as this activity is running under the
4153                // uid of the original calling activity.
4154                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4155                    throw new SecurityException(
4156                            "Calling activity in uid " + sourceRecord.app.uid
4157                                    + " must be system uid or original calling uid "
4158                                    + sourceRecord.launchedFromUid);
4159                }
4160            }
4161            if (ignoreTargetSecurity) {
4162                if (intent.getComponent() == null) {
4163                    throw new SecurityException(
4164                            "Component must be specified with ignoreTargetSecurity");
4165                }
4166                if (intent.getSelector() != null) {
4167                    throw new SecurityException(
4168                            "Selector not allowed with ignoreTargetSecurity");
4169                }
4170            }
4171            targetUid = sourceRecord.launchedFromUid;
4172            targetPackage = sourceRecord.launchedFromPackage;
4173        }
4174
4175        if (userId == UserHandle.USER_NULL) {
4176            userId = UserHandle.getUserId(sourceRecord.app.uid);
4177        }
4178
4179        // TODO: Switch to user app stacks here.
4180        try {
4181            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4182                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4183                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4184            return ret;
4185        } catch (SecurityException e) {
4186            // XXX need to figure out how to propagate to original app.
4187            // A SecurityException here is generally actually a fault of the original
4188            // calling activity (such as a fairly granting permissions), so propagate it
4189            // back to them.
4190            /*
4191            StringBuilder msg = new StringBuilder();
4192            msg.append("While launching");
4193            msg.append(intent.toString());
4194            msg.append(": ");
4195            msg.append(e.getMessage());
4196            */
4197            throw e;
4198        }
4199    }
4200
4201    @Override
4202    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4203            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4204            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4205        enforceNotIsolatedCaller("startActivityAndWait");
4206        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4207                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4208        WaitResult res = new WaitResult();
4209        // TODO: Switch to user app stacks here.
4210        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4211                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4212                bOptions, false, userId, null, null);
4213        return res;
4214    }
4215
4216    @Override
4217    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4218            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4219            int startFlags, Configuration config, Bundle bOptions, int userId) {
4220        enforceNotIsolatedCaller("startActivityWithConfig");
4221        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4222                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4223        // TODO: Switch to user app stacks here.
4224        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4225                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4226                null, null, config, bOptions, false, userId, null, null);
4227        return ret;
4228    }
4229
4230    @Override
4231    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4232            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4233            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4234            throws TransactionTooLargeException {
4235        enforceNotIsolatedCaller("startActivityIntentSender");
4236        // Refuse possible leaked file descriptors
4237        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4238            throw new IllegalArgumentException("File descriptors passed in Intent");
4239        }
4240
4241        IIntentSender sender = intent.getTarget();
4242        if (!(sender instanceof PendingIntentRecord)) {
4243            throw new IllegalArgumentException("Bad PendingIntent object");
4244        }
4245
4246        PendingIntentRecord pir = (PendingIntentRecord)sender;
4247
4248        synchronized (this) {
4249            // If this is coming from the currently resumed activity, it is
4250            // effectively saying that app switches are allowed at this point.
4251            final ActivityStack stack = getFocusedStack();
4252            if (stack.mResumedActivity != null &&
4253                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4254                mAppSwitchesAllowedTime = 0;
4255            }
4256        }
4257        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4258                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4259        return ret;
4260    }
4261
4262    @Override
4263    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4264            Intent intent, String resolvedType, IVoiceInteractionSession session,
4265            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4266            Bundle bOptions, int userId) {
4267        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4268                != PackageManager.PERMISSION_GRANTED) {
4269            String msg = "Permission Denial: startVoiceActivity() from pid="
4270                    + Binder.getCallingPid()
4271                    + ", uid=" + Binder.getCallingUid()
4272                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4273            Slog.w(TAG, msg);
4274            throw new SecurityException(msg);
4275        }
4276        if (session == null || interactor == null) {
4277            throw new NullPointerException("null session or interactor");
4278        }
4279        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4280                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4281        // TODO: Switch to user app stacks here.
4282        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4283                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4284                null, bOptions, false, userId, null, null);
4285    }
4286
4287    @Override
4288    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4289            throws RemoteException {
4290        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4291        synchronized (this) {
4292            ActivityRecord activity = getFocusedStack().topActivity();
4293            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4294                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4295            }
4296            if (mRunningVoice != null || activity.task.voiceSession != null
4297                    || activity.voiceSession != null) {
4298                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4299                return;
4300            }
4301            if (activity.pendingVoiceInteractionStart) {
4302                Slog.w(TAG, "Pending start of voice interaction already.");
4303                return;
4304            }
4305            activity.pendingVoiceInteractionStart = true;
4306        }
4307        LocalServices.getService(VoiceInteractionManagerInternal.class)
4308                .startLocalVoiceInteraction(callingActivity, options);
4309    }
4310
4311    @Override
4312    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4313        LocalServices.getService(VoiceInteractionManagerInternal.class)
4314                .stopLocalVoiceInteraction(callingActivity);
4315    }
4316
4317    @Override
4318    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4319        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4320                .supportsLocalVoiceInteraction();
4321    }
4322
4323    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4324            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4325        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4326        if (activityToCallback == null) return;
4327        activityToCallback.setVoiceSessionLocked(voiceSession);
4328
4329        // Inform the activity
4330        try {
4331            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4332                    voiceInteractor);
4333            long token = Binder.clearCallingIdentity();
4334            try {
4335                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4336            } finally {
4337                Binder.restoreCallingIdentity(token);
4338            }
4339            // TODO: VI Should we cache the activity so that it's easier to find later
4340            // rather than scan through all the stacks and activities?
4341        } catch (RemoteException re) {
4342            activityToCallback.clearVoiceSessionLocked();
4343            // TODO: VI Should this terminate the voice session?
4344        }
4345    }
4346
4347    @Override
4348    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4349        synchronized (this) {
4350            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4351                if (keepAwake) {
4352                    mVoiceWakeLock.acquire();
4353                } else {
4354                    mVoiceWakeLock.release();
4355                }
4356            }
4357        }
4358    }
4359
4360    @Override
4361    public boolean startNextMatchingActivity(IBinder callingActivity,
4362            Intent intent, Bundle bOptions) {
4363        // Refuse possible leaked file descriptors
4364        if (intent != null && intent.hasFileDescriptors() == true) {
4365            throw new IllegalArgumentException("File descriptors passed in Intent");
4366        }
4367        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4368
4369        synchronized (this) {
4370            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4371            if (r == null) {
4372                ActivityOptions.abort(options);
4373                return false;
4374            }
4375            if (r.app == null || r.app.thread == null) {
4376                // The caller is not running...  d'oh!
4377                ActivityOptions.abort(options);
4378                return false;
4379            }
4380            intent = new Intent(intent);
4381            // The caller is not allowed to change the data.
4382            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4383            // And we are resetting to find the next component...
4384            intent.setComponent(null);
4385
4386            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4387
4388            ActivityInfo aInfo = null;
4389            try {
4390                List<ResolveInfo> resolves =
4391                    AppGlobals.getPackageManager().queryIntentActivities(
4392                            intent, r.resolvedType,
4393                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4394                            UserHandle.getCallingUserId()).getList();
4395
4396                // Look for the original activity in the list...
4397                final int N = resolves != null ? resolves.size() : 0;
4398                for (int i=0; i<N; i++) {
4399                    ResolveInfo rInfo = resolves.get(i);
4400                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4401                            && rInfo.activityInfo.name.equals(r.info.name)) {
4402                        // We found the current one...  the next matching is
4403                        // after it.
4404                        i++;
4405                        if (i<N) {
4406                            aInfo = resolves.get(i).activityInfo;
4407                        }
4408                        if (debug) {
4409                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4410                                    + "/" + r.info.name);
4411                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4412                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4413                        }
4414                        break;
4415                    }
4416                }
4417            } catch (RemoteException e) {
4418            }
4419
4420            if (aInfo == null) {
4421                // Nobody who is next!
4422                ActivityOptions.abort(options);
4423                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4424                return false;
4425            }
4426
4427            intent.setComponent(new ComponentName(
4428                    aInfo.applicationInfo.packageName, aInfo.name));
4429            intent.setFlags(intent.getFlags()&~(
4430                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4431                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4432                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4433                    Intent.FLAG_ACTIVITY_NEW_TASK));
4434
4435            // Okay now we need to start the new activity, replacing the
4436            // currently running activity.  This is a little tricky because
4437            // we want to start the new one as if the current one is finished,
4438            // but not finish the current one first so that there is no flicker.
4439            // And thus...
4440            final boolean wasFinishing = r.finishing;
4441            r.finishing = true;
4442
4443            // Propagate reply information over to the new activity.
4444            final ActivityRecord resultTo = r.resultTo;
4445            final String resultWho = r.resultWho;
4446            final int requestCode = r.requestCode;
4447            r.resultTo = null;
4448            if (resultTo != null) {
4449                resultTo.removeResultsLocked(r, resultWho, requestCode);
4450            }
4451
4452            final long origId = Binder.clearCallingIdentity();
4453            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4454                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4455                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4456                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4457                    false, false, null, null, null);
4458            Binder.restoreCallingIdentity(origId);
4459
4460            r.finishing = wasFinishing;
4461            if (res != ActivityManager.START_SUCCESS) {
4462                return false;
4463            }
4464            return true;
4465        }
4466    }
4467
4468    @Override
4469    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4470        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4471            String msg = "Permission Denial: startActivityFromRecents called without " +
4472                    START_TASKS_FROM_RECENTS;
4473            Slog.w(TAG, msg);
4474            throw new SecurityException(msg);
4475        }
4476        final long origId = Binder.clearCallingIdentity();
4477        try {
4478            return startActivityFromRecentsInner(taskId, bOptions);
4479        } finally {
4480            Binder.restoreCallingIdentity(origId);
4481        }
4482    }
4483
4484    final int startActivityFromRecentsInner(int taskId, Bundle bOptions) {
4485        final TaskRecord task;
4486        final int callingUid;
4487        final String callingPackage;
4488        final Intent intent;
4489        final int userId;
4490        synchronized (this) {
4491            final ActivityOptions activityOptions = (bOptions != null)
4492                    ? new ActivityOptions(bOptions) : null;
4493            final int launchStackId = (activityOptions != null)
4494                    ? activityOptions.getLaunchStackId() : INVALID_STACK_ID;
4495
4496            if (launchStackId == HOME_STACK_ID) {
4497                throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4498                        + taskId + " can't be launch in the home stack.");
4499            }
4500            task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4501            if (task == null) {
4502                throw new IllegalArgumentException(
4503                        "startActivityFromRecentsInner: Task " + taskId + " not found.");
4504            }
4505
4506            if (launchStackId != INVALID_STACK_ID) {
4507                if (launchStackId == DOCKED_STACK_ID && activityOptions != null) {
4508                    mWindowManager.setDockedStackCreateState(
4509                            activityOptions.getDockCreateMode(), null /* initialBounds */);
4510                }
4511                if (task.stack.mStackId != launchStackId) {
4512                    mStackSupervisor.moveTaskToStackLocked(
4513                            taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
4514                            ANIMATE);
4515                }
4516            }
4517
4518            // If the user must confirm credentials (e.g. when first launching a work app and the
4519            // Work Challenge is present) let startActivityInPackage handle the intercepting.
4520            if (!mUserController.shouldConfirmCredentials(task.userId)
4521                    && task.getRootActivity() != null) {
4522                moveTaskToFrontLocked(task.taskId, 0, bOptions);
4523                return ActivityManager.START_TASK_TO_FRONT;
4524            }
4525            callingUid = task.mCallingUid;
4526            callingPackage = task.mCallingPackage;
4527            intent = task.intent;
4528            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4529            userId = task.userId;
4530        }
4531        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4532                bOptions, userId, null, task);
4533    }
4534
4535    final int startActivityInPackage(int uid, String callingPackage,
4536            Intent intent, String resolvedType, IBinder resultTo,
4537            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4538            IActivityContainer container, TaskRecord inTask) {
4539
4540        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4541                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4542
4543        // TODO: Switch to user app stacks here.
4544        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4545                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4546                null, null, null, bOptions, false, userId, container, inTask);
4547        return ret;
4548    }
4549
4550    @Override
4551    public final int startActivities(IApplicationThread caller, String callingPackage,
4552            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4553            int userId) {
4554        enforceNotIsolatedCaller("startActivities");
4555        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4556                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4557        // TODO: Switch to user app stacks here.
4558        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4559                resolvedTypes, resultTo, bOptions, userId);
4560        return ret;
4561    }
4562
4563    final int startActivitiesInPackage(int uid, String callingPackage,
4564            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4565            Bundle bOptions, int userId) {
4566
4567        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4568                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4569        // TODO: Switch to user app stacks here.
4570        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4571                resultTo, bOptions, userId);
4572        return ret;
4573    }
4574
4575    @Override
4576    public void reportActivityFullyDrawn(IBinder token) {
4577        synchronized (this) {
4578            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4579            if (r == null) {
4580                return;
4581            }
4582            r.reportFullyDrawnLocked();
4583        }
4584    }
4585
4586    @Override
4587    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4588        synchronized (this) {
4589            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4590            if (r == null) {
4591                return;
4592            }
4593            TaskRecord task = r.task;
4594            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4595                // Fixed screen orientation isn't supported when activities aren't in full screen
4596                // mode.
4597                return;
4598            }
4599            final long origId = Binder.clearCallingIdentity();
4600            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4601            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4602                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4603            if (config != null) {
4604                r.frozenBeforeDestroy = true;
4605                if (!updateConfigurationLocked(config, r, false)) {
4606                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4607                }
4608            }
4609            Binder.restoreCallingIdentity(origId);
4610        }
4611    }
4612
4613    @Override
4614    public int getRequestedOrientation(IBinder token) {
4615        synchronized (this) {
4616            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4617            if (r == null) {
4618                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4619            }
4620            return mWindowManager.getAppOrientation(r.appToken);
4621        }
4622    }
4623
4624    /**
4625     * This is the internal entry point for handling Activity.finish().
4626     *
4627     * @param token The Binder token referencing the Activity we want to finish.
4628     * @param resultCode Result code, if any, from this Activity.
4629     * @param resultData Result data (Intent), if any, from this Activity.
4630     * @param finishTask Whether to finish the task associated with this Activity.
4631     *
4632     * @return Returns true if the activity successfully finished, or false if it is still running.
4633     */
4634    @Override
4635    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4636            int finishTask) {
4637        // Refuse possible leaked file descriptors
4638        if (resultData != null && resultData.hasFileDescriptors() == true) {
4639            throw new IllegalArgumentException("File descriptors passed in Intent");
4640        }
4641
4642        synchronized(this) {
4643            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4644            if (r == null) {
4645                return true;
4646            }
4647            // Keep track of the root activity of the task before we finish it
4648            TaskRecord tr = r.task;
4649            ActivityRecord rootR = tr.getRootActivity();
4650            if (rootR == null) {
4651                Slog.w(TAG, "Finishing task with all activities already finished");
4652            }
4653            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4654            // finish.
4655            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4656                    mStackSupervisor.isLastLockedTask(tr)) {
4657                Slog.i(TAG, "Not finishing task in lock task mode");
4658                mStackSupervisor.showLockTaskToast();
4659                return false;
4660            }
4661            if (mController != null) {
4662                // Find the first activity that is not finishing.
4663                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4664                if (next != null) {
4665                    // ask watcher if this is allowed
4666                    boolean resumeOK = true;
4667                    try {
4668                        resumeOK = mController.activityResuming(next.packageName);
4669                    } catch (RemoteException e) {
4670                        mController = null;
4671                        Watchdog.getInstance().setActivityController(null);
4672                    }
4673
4674                    if (!resumeOK) {
4675                        Slog.i(TAG, "Not finishing activity because controller resumed");
4676                        return false;
4677                    }
4678                }
4679            }
4680            final long origId = Binder.clearCallingIdentity();
4681            try {
4682                boolean res;
4683                final boolean finishWithRootActivity =
4684                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4685                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4686                        || (finishWithRootActivity && r == rootR)) {
4687                    // If requested, remove the task that is associated to this activity only if it
4688                    // was the root activity in the task. The result code and data is ignored
4689                    // because we don't support returning them across task boundaries. Also, to
4690                    // keep backwards compatibility we remove the task from recents when finishing
4691                    // task with root activity.
4692                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4693                    if (!res) {
4694                        Slog.i(TAG, "Removing task failed to finish activity");
4695                    }
4696                } else {
4697                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4698                            resultData, "app-request", true);
4699                    if (!res) {
4700                        Slog.i(TAG, "Failed to finish by app-request");
4701                    }
4702                }
4703                return res;
4704            } finally {
4705                Binder.restoreCallingIdentity(origId);
4706            }
4707        }
4708    }
4709
4710    @Override
4711    public final void finishHeavyWeightApp() {
4712        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4713                != PackageManager.PERMISSION_GRANTED) {
4714            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4715                    + Binder.getCallingPid()
4716                    + ", uid=" + Binder.getCallingUid()
4717                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4718            Slog.w(TAG, msg);
4719            throw new SecurityException(msg);
4720        }
4721
4722        synchronized(this) {
4723            if (mHeavyWeightProcess == null) {
4724                return;
4725            }
4726
4727            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4728            for (int i = 0; i < activities.size(); i++) {
4729                ActivityRecord r = activities.get(i);
4730                if (!r.finishing && r.isInStackLocked()) {
4731                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4732                            null, "finish-heavy", true);
4733                }
4734            }
4735
4736            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4737                    mHeavyWeightProcess.userId, 0));
4738            mHeavyWeightProcess = null;
4739        }
4740    }
4741
4742    @Override
4743    public void crashApplication(int uid, int initialPid, String packageName,
4744            String message) {
4745        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4746                != PackageManager.PERMISSION_GRANTED) {
4747            String msg = "Permission Denial: crashApplication() from pid="
4748                    + Binder.getCallingPid()
4749                    + ", uid=" + Binder.getCallingUid()
4750                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4751            Slog.w(TAG, msg);
4752            throw new SecurityException(msg);
4753        }
4754
4755        synchronized(this) {
4756            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4757        }
4758    }
4759
4760    @Override
4761    public final void finishSubActivity(IBinder token, String resultWho,
4762            int requestCode) {
4763        synchronized(this) {
4764            final long origId = Binder.clearCallingIdentity();
4765            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4766            if (r != null) {
4767                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4768            }
4769            Binder.restoreCallingIdentity(origId);
4770        }
4771    }
4772
4773    @Override
4774    public boolean finishActivityAffinity(IBinder token) {
4775        synchronized(this) {
4776            final long origId = Binder.clearCallingIdentity();
4777            try {
4778                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4779                if (r == null) {
4780                    return false;
4781                }
4782
4783                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4784                // can finish.
4785                final TaskRecord task = r.task;
4786                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4787                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4788                    mStackSupervisor.showLockTaskToast();
4789                    return false;
4790                }
4791                return task.stack.finishActivityAffinityLocked(r);
4792            } finally {
4793                Binder.restoreCallingIdentity(origId);
4794            }
4795        }
4796    }
4797
4798    @Override
4799    public void finishVoiceTask(IVoiceInteractionSession session) {
4800        synchronized (this) {
4801            final long origId = Binder.clearCallingIdentity();
4802            try {
4803                // TODO: VI Consider treating local voice interactions and voice tasks
4804                // differently here
4805                mStackSupervisor.finishVoiceTask(session);
4806            } finally {
4807                Binder.restoreCallingIdentity(origId);
4808            }
4809        }
4810
4811    }
4812
4813    @Override
4814    public boolean releaseActivityInstance(IBinder token) {
4815        synchronized(this) {
4816            final long origId = Binder.clearCallingIdentity();
4817            try {
4818                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4819                if (r == null) {
4820                    return false;
4821                }
4822                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4823            } finally {
4824                Binder.restoreCallingIdentity(origId);
4825            }
4826        }
4827    }
4828
4829    @Override
4830    public void releaseSomeActivities(IApplicationThread appInt) {
4831        synchronized(this) {
4832            final long origId = Binder.clearCallingIdentity();
4833            try {
4834                ProcessRecord app = getRecordForAppLocked(appInt);
4835                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4836            } finally {
4837                Binder.restoreCallingIdentity(origId);
4838            }
4839        }
4840    }
4841
4842    @Override
4843    public boolean willActivityBeVisible(IBinder token) {
4844        synchronized(this) {
4845            ActivityStack stack = ActivityRecord.getStackLocked(token);
4846            if (stack != null) {
4847                return stack.willActivityBeVisibleLocked(token);
4848            }
4849            return false;
4850        }
4851    }
4852
4853    @Override
4854    public void overridePendingTransition(IBinder token, String packageName,
4855            int enterAnim, int exitAnim) {
4856        synchronized(this) {
4857            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4858            if (self == null) {
4859                return;
4860            }
4861
4862            final long origId = Binder.clearCallingIdentity();
4863
4864            if (self.state == ActivityState.RESUMED
4865                    || self.state == ActivityState.PAUSING) {
4866                mWindowManager.overridePendingAppTransition(packageName,
4867                        enterAnim, exitAnim, null);
4868            }
4869
4870            Binder.restoreCallingIdentity(origId);
4871        }
4872    }
4873
4874    /**
4875     * Main function for removing an existing process from the activity manager
4876     * as a result of that process going away.  Clears out all connections
4877     * to the process.
4878     */
4879    private final void handleAppDiedLocked(ProcessRecord app,
4880            boolean restarting, boolean allowRestart) {
4881        int pid = app.pid;
4882        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4883        if (!kept && !restarting) {
4884            removeLruProcessLocked(app);
4885            if (pid > 0) {
4886                ProcessList.remove(pid);
4887            }
4888        }
4889
4890        if (mProfileProc == app) {
4891            clearProfilerLocked();
4892        }
4893
4894        // Remove this application's activities from active lists.
4895        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4896
4897        app.activities.clear();
4898
4899        if (app.instrumentationClass != null) {
4900            Slog.w(TAG, "Crash of app " + app.processName
4901                  + " running instrumentation " + app.instrumentationClass);
4902            Bundle info = new Bundle();
4903            info.putString("shortMsg", "Process crashed.");
4904            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4905        }
4906
4907        if (!restarting && hasVisibleActivities
4908                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4909            // If there was nothing to resume, and we are not already restarting this process, but
4910            // there is a visible activity that is hosted by the process...  then make sure all
4911            // visible activities are running, taking care of restarting this process.
4912            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4913        }
4914    }
4915
4916    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4917        IBinder threadBinder = thread.asBinder();
4918        // Find the application record.
4919        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4920            ProcessRecord rec = mLruProcesses.get(i);
4921            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4922                return i;
4923            }
4924        }
4925        return -1;
4926    }
4927
4928    final ProcessRecord getRecordForAppLocked(
4929            IApplicationThread thread) {
4930        if (thread == null) {
4931            return null;
4932        }
4933
4934        int appIndex = getLRURecordIndexForAppLocked(thread);
4935        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4936    }
4937
4938    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4939        // If there are no longer any background processes running,
4940        // and the app that died was not running instrumentation,
4941        // then tell everyone we are now low on memory.
4942        boolean haveBg = false;
4943        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4944            ProcessRecord rec = mLruProcesses.get(i);
4945            if (rec.thread != null
4946                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4947                haveBg = true;
4948                break;
4949            }
4950        }
4951
4952        if (!haveBg) {
4953            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4954            if (doReport) {
4955                long now = SystemClock.uptimeMillis();
4956                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4957                    doReport = false;
4958                } else {
4959                    mLastMemUsageReportTime = now;
4960                }
4961            }
4962            final ArrayList<ProcessMemInfo> memInfos
4963                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4964            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4965            long now = SystemClock.uptimeMillis();
4966            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4967                ProcessRecord rec = mLruProcesses.get(i);
4968                if (rec == dyingProc || rec.thread == null) {
4969                    continue;
4970                }
4971                if (doReport) {
4972                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4973                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4974                }
4975                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4976                    // The low memory report is overriding any current
4977                    // state for a GC request.  Make sure to do
4978                    // heavy/important/visible/foreground processes first.
4979                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4980                        rec.lastRequestedGc = 0;
4981                    } else {
4982                        rec.lastRequestedGc = rec.lastLowMemory;
4983                    }
4984                    rec.reportLowMemory = true;
4985                    rec.lastLowMemory = now;
4986                    mProcessesToGc.remove(rec);
4987                    addProcessToGcListLocked(rec);
4988                }
4989            }
4990            if (doReport) {
4991                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4992                mHandler.sendMessage(msg);
4993            }
4994            scheduleAppGcsLocked();
4995        }
4996    }
4997
4998    final void appDiedLocked(ProcessRecord app) {
4999       appDiedLocked(app, app.pid, app.thread, false);
5000    }
5001
5002    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5003            boolean fromBinderDied) {
5004        // First check if this ProcessRecord is actually active for the pid.
5005        synchronized (mPidsSelfLocked) {
5006            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5007            if (curProc != app) {
5008                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5009                return;
5010            }
5011        }
5012
5013        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5014        synchronized (stats) {
5015            stats.noteProcessDiedLocked(app.info.uid, pid);
5016        }
5017
5018        if (!app.killed) {
5019            if (!fromBinderDied) {
5020                Process.killProcessQuiet(pid);
5021            }
5022            killProcessGroup(app.info.uid, pid);
5023            app.killed = true;
5024        }
5025
5026        // Clean up already done if the process has been re-started.
5027        if (app.pid == pid && app.thread != null &&
5028                app.thread.asBinder() == thread.asBinder()) {
5029            boolean doLowMem = app.instrumentationClass == null;
5030            boolean doOomAdj = doLowMem;
5031            if (!app.killedByAm) {
5032                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5033                        + ") has died");
5034                mAllowLowerMemLevel = true;
5035            } else {
5036                // Note that we always want to do oom adj to update our state with the
5037                // new number of procs.
5038                mAllowLowerMemLevel = false;
5039                doLowMem = false;
5040            }
5041            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5042            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5043                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5044            handleAppDiedLocked(app, false, true);
5045
5046            if (doOomAdj) {
5047                updateOomAdjLocked();
5048            }
5049            if (doLowMem) {
5050                doLowMemReportIfNeededLocked(app);
5051            }
5052        } else if (app.pid != pid) {
5053            // A new process has already been started.
5054            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5055                    + ") has died and restarted (pid " + app.pid + ").");
5056            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5057        } else if (DEBUG_PROCESSES) {
5058            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5059                    + thread.asBinder());
5060        }
5061    }
5062
5063    /**
5064     * If a stack trace dump file is configured, dump process stack traces.
5065     * @param clearTraces causes the dump file to be erased prior to the new
5066     *    traces being written, if true; when false, the new traces will be
5067     *    appended to any existing file content.
5068     * @param firstPids of dalvik VM processes to dump stack traces for first
5069     * @param lastPids of dalvik VM processes to dump stack traces for last
5070     * @param nativeProcs optional list of native process names to dump stack crawls
5071     * @return file containing stack traces, or null if no dump file is configured
5072     */
5073    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5074            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5075        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5076        if (tracesPath == null || tracesPath.length() == 0) {
5077            return null;
5078        }
5079
5080        File tracesFile = new File(tracesPath);
5081        try {
5082            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5083            tracesFile.createNewFile();
5084            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5085        } catch (IOException e) {
5086            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5087            return null;
5088        }
5089
5090        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5091        return tracesFile;
5092    }
5093
5094    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5095            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5096        // Use a FileObserver to detect when traces finish writing.
5097        // The order of traces is considered important to maintain for legibility.
5098        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5099            @Override
5100            public synchronized void onEvent(int event, String path) { notify(); }
5101        };
5102
5103        try {
5104            observer.startWatching();
5105
5106            // First collect all of the stacks of the most important pids.
5107            if (firstPids != null) {
5108                try {
5109                    int num = firstPids.size();
5110                    for (int i = 0; i < num; i++) {
5111                        synchronized (observer) {
5112                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5113                                    + firstPids.get(i));
5114                            final long sime = SystemClock.elapsedRealtime();
5115                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5116                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5117                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5118                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5119                        }
5120                    }
5121                } catch (InterruptedException e) {
5122                    Slog.wtf(TAG, e);
5123                }
5124            }
5125
5126            // Next collect the stacks of the native pids
5127            if (nativeProcs != null) {
5128                int[] pids = Process.getPidsForCommands(nativeProcs);
5129                if (pids != null) {
5130                    for (int pid : pids) {
5131                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5132                        final long sime = SystemClock.elapsedRealtime();
5133                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5134                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5135                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5136                    }
5137                }
5138            }
5139
5140            // Lastly, measure CPU usage.
5141            if (processCpuTracker != null) {
5142                processCpuTracker.init();
5143                System.gc();
5144                processCpuTracker.update();
5145                try {
5146                    synchronized (processCpuTracker) {
5147                        processCpuTracker.wait(500); // measure over 1/2 second.
5148                    }
5149                } catch (InterruptedException e) {
5150                }
5151                processCpuTracker.update();
5152
5153                // We'll take the stack crawls of just the top apps using CPU.
5154                final int N = processCpuTracker.countWorkingStats();
5155                int numProcs = 0;
5156                for (int i=0; i<N && numProcs<5; i++) {
5157                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5158                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5159                        numProcs++;
5160                        try {
5161                            synchronized (observer) {
5162                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5163                                        + stats.pid);
5164                                final long stime = SystemClock.elapsedRealtime();
5165                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5166                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5167                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5168                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5169                            }
5170                        } catch (InterruptedException e) {
5171                            Slog.wtf(TAG, e);
5172                        }
5173                    } else if (DEBUG_ANR) {
5174                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5175                                + stats.pid);
5176                    }
5177                }
5178            }
5179        } finally {
5180            observer.stopWatching();
5181        }
5182    }
5183
5184    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5185        if (true || IS_USER_BUILD) {
5186            return;
5187        }
5188        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5189        if (tracesPath == null || tracesPath.length() == 0) {
5190            return;
5191        }
5192
5193        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5194        StrictMode.allowThreadDiskWrites();
5195        try {
5196            final File tracesFile = new File(tracesPath);
5197            final File tracesDir = tracesFile.getParentFile();
5198            final File tracesTmp = new File(tracesDir, "__tmp__");
5199            try {
5200                if (tracesFile.exists()) {
5201                    tracesTmp.delete();
5202                    tracesFile.renameTo(tracesTmp);
5203                }
5204                StringBuilder sb = new StringBuilder();
5205                Time tobj = new Time();
5206                tobj.set(System.currentTimeMillis());
5207                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5208                sb.append(": ");
5209                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5210                sb.append(" since ");
5211                sb.append(msg);
5212                FileOutputStream fos = new FileOutputStream(tracesFile);
5213                fos.write(sb.toString().getBytes());
5214                if (app == null) {
5215                    fos.write("\n*** No application process!".getBytes());
5216                }
5217                fos.close();
5218                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5219            } catch (IOException e) {
5220                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5221                return;
5222            }
5223
5224            if (app != null) {
5225                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5226                firstPids.add(app.pid);
5227                dumpStackTraces(tracesPath, firstPids, null, null, null);
5228            }
5229
5230            File lastTracesFile = null;
5231            File curTracesFile = null;
5232            for (int i=9; i>=0; i--) {
5233                String name = String.format(Locale.US, "slow%02d.txt", i);
5234                curTracesFile = new File(tracesDir, name);
5235                if (curTracesFile.exists()) {
5236                    if (lastTracesFile != null) {
5237                        curTracesFile.renameTo(lastTracesFile);
5238                    } else {
5239                        curTracesFile.delete();
5240                    }
5241                }
5242                lastTracesFile = curTracesFile;
5243            }
5244            tracesFile.renameTo(curTracesFile);
5245            if (tracesTmp.exists()) {
5246                tracesTmp.renameTo(tracesFile);
5247            }
5248        } finally {
5249            StrictMode.setThreadPolicy(oldPolicy);
5250        }
5251    }
5252
5253    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5254        if (!mLaunchWarningShown) {
5255            mLaunchWarningShown = true;
5256            mUiHandler.post(new Runnable() {
5257                @Override
5258                public void run() {
5259                    synchronized (ActivityManagerService.this) {
5260                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5261                        d.show();
5262                        mUiHandler.postDelayed(new Runnable() {
5263                            @Override
5264                            public void run() {
5265                                synchronized (ActivityManagerService.this) {
5266                                    d.dismiss();
5267                                    mLaunchWarningShown = false;
5268                                }
5269                            }
5270                        }, 4000);
5271                    }
5272                }
5273            });
5274        }
5275    }
5276
5277    @Override
5278    public boolean clearApplicationUserData(final String packageName,
5279            final IPackageDataObserver observer, int userId) {
5280        enforceNotIsolatedCaller("clearApplicationUserData");
5281        int uid = Binder.getCallingUid();
5282        int pid = Binder.getCallingPid();
5283        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5284                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5285
5286        final DevicePolicyManagerInternal dpmi = LocalServices
5287                .getService(DevicePolicyManagerInternal.class);
5288        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5289            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5290        }
5291
5292        long callingId = Binder.clearCallingIdentity();
5293        try {
5294            IPackageManager pm = AppGlobals.getPackageManager();
5295            int pkgUid = -1;
5296            synchronized(this) {
5297                try {
5298                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5299                } catch (RemoteException e) {
5300                }
5301                if (pkgUid == -1) {
5302                    Slog.w(TAG, "Invalid packageName: " + packageName);
5303                    if (observer != null) {
5304                        try {
5305                            observer.onRemoveCompleted(packageName, false);
5306                        } catch (RemoteException e) {
5307                            Slog.i(TAG, "Observer no longer exists.");
5308                        }
5309                    }
5310                    return false;
5311                }
5312                if (uid == pkgUid || checkComponentPermission(
5313                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5314                        pid, uid, -1, true)
5315                        == PackageManager.PERMISSION_GRANTED) {
5316                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5317                } else {
5318                    throw new SecurityException("PID " + pid + " does not have permission "
5319                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5320                                    + " of package " + packageName);
5321                }
5322
5323                // Remove all tasks match the cleared application package and user
5324                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5325                    final TaskRecord tr = mRecentTasks.get(i);
5326                    final String taskPackageName =
5327                            tr.getBaseIntent().getComponent().getPackageName();
5328                    if (tr.userId != userId) continue;
5329                    if (!taskPackageName.equals(packageName)) continue;
5330                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5331                }
5332            }
5333
5334            try {
5335                // Clear application user data
5336                pm.clearApplicationUserData(packageName, observer, userId);
5337
5338                synchronized(this) {
5339                    // Remove all permissions granted from/to this package
5340                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5341                }
5342
5343                // Remove all zen rules created by this package; revoke it's zen access.
5344                INotificationManager inm = NotificationManager.getService();
5345                inm.removeAutomaticZenRules(packageName);
5346                inm.setNotificationPolicyAccessGranted(packageName, false);
5347
5348                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5349                        Uri.fromParts("package", packageName, null));
5350                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5351                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5352                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5353                        null, null, 0, null, null, null, null, false, false, userId);
5354            } catch (RemoteException e) {
5355            }
5356        } finally {
5357            Binder.restoreCallingIdentity(callingId);
5358        }
5359        return true;
5360    }
5361
5362    @Override
5363    public void killBackgroundProcesses(final String packageName, int userId) {
5364        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5365                != PackageManager.PERMISSION_GRANTED &&
5366                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5367                        != PackageManager.PERMISSION_GRANTED) {
5368            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5369                    + Binder.getCallingPid()
5370                    + ", uid=" + Binder.getCallingUid()
5371                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5372            Slog.w(TAG, msg);
5373            throw new SecurityException(msg);
5374        }
5375
5376        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5377                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5378        long callingId = Binder.clearCallingIdentity();
5379        try {
5380            IPackageManager pm = AppGlobals.getPackageManager();
5381            synchronized(this) {
5382                int appId = -1;
5383                try {
5384                    appId = UserHandle.getAppId(
5385                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5386                } catch (RemoteException e) {
5387                }
5388                if (appId == -1) {
5389                    Slog.w(TAG, "Invalid packageName: " + packageName);
5390                    return;
5391                }
5392                killPackageProcessesLocked(packageName, appId, userId,
5393                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5394            }
5395        } finally {
5396            Binder.restoreCallingIdentity(callingId);
5397        }
5398    }
5399
5400    @Override
5401    public void killAllBackgroundProcesses() {
5402        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5403                != PackageManager.PERMISSION_GRANTED) {
5404            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5405                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5406                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5407            Slog.w(TAG, msg);
5408            throw new SecurityException(msg);
5409        }
5410
5411        final long callingId = Binder.clearCallingIdentity();
5412        try {
5413            synchronized (this) {
5414                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5415                final int NP = mProcessNames.getMap().size();
5416                for (int ip = 0; ip < NP; ip++) {
5417                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5418                    final int NA = apps.size();
5419                    for (int ia = 0; ia < NA; ia++) {
5420                        final ProcessRecord app = apps.valueAt(ia);
5421                        if (app.persistent) {
5422                            // We don't kill persistent processes.
5423                            continue;
5424                        }
5425                        if (app.removed) {
5426                            procs.add(app);
5427                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5428                            app.removed = true;
5429                            procs.add(app);
5430                        }
5431                    }
5432                }
5433
5434                final int N = procs.size();
5435                for (int i = 0; i < N; i++) {
5436                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5437                }
5438
5439                mAllowLowerMemLevel = true;
5440
5441                updateOomAdjLocked();
5442                doLowMemReportIfNeededLocked(null);
5443            }
5444        } finally {
5445            Binder.restoreCallingIdentity(callingId);
5446        }
5447    }
5448
5449    /**
5450     * Kills all background processes, except those matching any of the
5451     * specified properties.
5452     *
5453     * @param minTargetSdk the target SDK version at or above which to preserve
5454     *                     processes, or {@code -1} to ignore the target SDK
5455     * @param maxProcState the process state at or below which to preserve
5456     *                     processes, or {@code -1} to ignore the process state
5457     */
5458    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5459        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5460                != PackageManager.PERMISSION_GRANTED) {
5461            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5462                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5463                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5464            Slog.w(TAG, msg);
5465            throw new SecurityException(msg);
5466        }
5467
5468        final long callingId = Binder.clearCallingIdentity();
5469        try {
5470            synchronized (this) {
5471                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5472                final int NP = mProcessNames.getMap().size();
5473                for (int ip = 0; ip < NP; ip++) {
5474                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5475                    final int NA = apps.size();
5476                    for (int ia = 0; ia < NA; ia++) {
5477                        final ProcessRecord app = apps.valueAt(ia);
5478                        if (app.removed) {
5479                            procs.add(app);
5480                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5481                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5482                            app.removed = true;
5483                            procs.add(app);
5484                        }
5485                    }
5486                }
5487
5488                final int N = procs.size();
5489                for (int i = 0; i < N; i++) {
5490                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5491                }
5492            }
5493        } finally {
5494            Binder.restoreCallingIdentity(callingId);
5495        }
5496    }
5497
5498    @Override
5499    public void forceStopPackage(final String packageName, int userId) {
5500        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5501                != PackageManager.PERMISSION_GRANTED) {
5502            String msg = "Permission Denial: forceStopPackage() from pid="
5503                    + Binder.getCallingPid()
5504                    + ", uid=" + Binder.getCallingUid()
5505                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5506            Slog.w(TAG, msg);
5507            throw new SecurityException(msg);
5508        }
5509        final int callingPid = Binder.getCallingPid();
5510        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5511                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5512        long callingId = Binder.clearCallingIdentity();
5513        try {
5514            IPackageManager pm = AppGlobals.getPackageManager();
5515            synchronized(this) {
5516                int[] users = userId == UserHandle.USER_ALL
5517                        ? mUserController.getUsers() : new int[] { userId };
5518                for (int user : users) {
5519                    int pkgUid = -1;
5520                    try {
5521                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5522                                user);
5523                    } catch (RemoteException e) {
5524                    }
5525                    if (pkgUid == -1) {
5526                        Slog.w(TAG, "Invalid packageName: " + packageName);
5527                        continue;
5528                    }
5529                    try {
5530                        pm.setPackageStoppedState(packageName, true, user);
5531                    } catch (RemoteException e) {
5532                    } catch (IllegalArgumentException e) {
5533                        Slog.w(TAG, "Failed trying to unstop package "
5534                                + packageName + ": " + e);
5535                    }
5536                    if (mUserController.isUserRunningLocked(user, 0)) {
5537                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5538                    }
5539                }
5540            }
5541        } finally {
5542            Binder.restoreCallingIdentity(callingId);
5543        }
5544    }
5545
5546    @Override
5547    public void addPackageDependency(String packageName) {
5548        synchronized (this) {
5549            int callingPid = Binder.getCallingPid();
5550            if (callingPid == Process.myPid()) {
5551                //  Yeah, um, no.
5552                return;
5553            }
5554            ProcessRecord proc;
5555            synchronized (mPidsSelfLocked) {
5556                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5557            }
5558            if (proc != null) {
5559                if (proc.pkgDeps == null) {
5560                    proc.pkgDeps = new ArraySet<String>(1);
5561                }
5562                proc.pkgDeps.add(packageName);
5563            }
5564        }
5565    }
5566
5567    /*
5568     * The pkg name and app id have to be specified.
5569     */
5570    @Override
5571    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5572        if (pkg == null) {
5573            return;
5574        }
5575        // Make sure the uid is valid.
5576        if (appid < 0) {
5577            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5578            return;
5579        }
5580        int callerUid = Binder.getCallingUid();
5581        // Only the system server can kill an application
5582        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5583            // Post an aysnc message to kill the application
5584            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5585            msg.arg1 = appid;
5586            msg.arg2 = 0;
5587            Bundle bundle = new Bundle();
5588            bundle.putString("pkg", pkg);
5589            bundle.putString("reason", reason);
5590            msg.obj = bundle;
5591            mHandler.sendMessage(msg);
5592        } else {
5593            throw new SecurityException(callerUid + " cannot kill pkg: " +
5594                    pkg);
5595        }
5596    }
5597
5598    @Override
5599    public void closeSystemDialogs(String reason) {
5600        enforceNotIsolatedCaller("closeSystemDialogs");
5601
5602        final int pid = Binder.getCallingPid();
5603        final int uid = Binder.getCallingUid();
5604        final long origId = Binder.clearCallingIdentity();
5605        try {
5606            synchronized (this) {
5607                // Only allow this from foreground processes, so that background
5608                // applications can't abuse it to prevent system UI from being shown.
5609                if (uid >= Process.FIRST_APPLICATION_UID) {
5610                    ProcessRecord proc;
5611                    synchronized (mPidsSelfLocked) {
5612                        proc = mPidsSelfLocked.get(pid);
5613                    }
5614                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5615                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5616                                + " from background process " + proc);
5617                        return;
5618                    }
5619                }
5620                closeSystemDialogsLocked(reason);
5621            }
5622        } finally {
5623            Binder.restoreCallingIdentity(origId);
5624        }
5625    }
5626
5627    void closeSystemDialogsLocked(String reason) {
5628        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5629        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5630                | Intent.FLAG_RECEIVER_FOREGROUND);
5631        if (reason != null) {
5632            intent.putExtra("reason", reason);
5633        }
5634        mWindowManager.closeSystemDialogs(reason);
5635
5636        mStackSupervisor.closeSystemDialogsLocked();
5637
5638        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5639                AppOpsManager.OP_NONE, null, false, false,
5640                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5641    }
5642
5643    @Override
5644    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5645        enforceNotIsolatedCaller("getProcessMemoryInfo");
5646        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5647        for (int i=pids.length-1; i>=0; i--) {
5648            ProcessRecord proc;
5649            int oomAdj;
5650            synchronized (this) {
5651                synchronized (mPidsSelfLocked) {
5652                    proc = mPidsSelfLocked.get(pids[i]);
5653                    oomAdj = proc != null ? proc.setAdj : 0;
5654                }
5655            }
5656            infos[i] = new Debug.MemoryInfo();
5657            Debug.getMemoryInfo(pids[i], infos[i]);
5658            if (proc != null) {
5659                synchronized (this) {
5660                    if (proc.thread != null && proc.setAdj == oomAdj) {
5661                        // Record this for posterity if the process has been stable.
5662                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5663                                infos[i].getTotalUss(), false, proc.pkgList);
5664                    }
5665                }
5666            }
5667        }
5668        return infos;
5669    }
5670
5671    @Override
5672    public long[] getProcessPss(int[] pids) {
5673        enforceNotIsolatedCaller("getProcessPss");
5674        long[] pss = new long[pids.length];
5675        for (int i=pids.length-1; i>=0; i--) {
5676            ProcessRecord proc;
5677            int oomAdj;
5678            synchronized (this) {
5679                synchronized (mPidsSelfLocked) {
5680                    proc = mPidsSelfLocked.get(pids[i]);
5681                    oomAdj = proc != null ? proc.setAdj : 0;
5682                }
5683            }
5684            long[] tmpUss = new long[1];
5685            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5686            if (proc != null) {
5687                synchronized (this) {
5688                    if (proc.thread != null && proc.setAdj == oomAdj) {
5689                        // Record this for posterity if the process has been stable.
5690                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5691                    }
5692                }
5693            }
5694        }
5695        return pss;
5696    }
5697
5698    @Override
5699    public void killApplicationProcess(String processName, int uid) {
5700        if (processName == null) {
5701            return;
5702        }
5703
5704        int callerUid = Binder.getCallingUid();
5705        // Only the system server can kill an application
5706        if (callerUid == Process.SYSTEM_UID) {
5707            synchronized (this) {
5708                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5709                if (app != null && app.thread != null) {
5710                    try {
5711                        app.thread.scheduleSuicide();
5712                    } catch (RemoteException e) {
5713                        // If the other end already died, then our work here is done.
5714                    }
5715                } else {
5716                    Slog.w(TAG, "Process/uid not found attempting kill of "
5717                            + processName + " / " + uid);
5718                }
5719            }
5720        } else {
5721            throw new SecurityException(callerUid + " cannot kill app process: " +
5722                    processName);
5723        }
5724    }
5725
5726    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5727        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5728                false, true, false, false, UserHandle.getUserId(uid), reason);
5729        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5730                Uri.fromParts("package", packageName, null));
5731        if (!mProcessesReady) {
5732            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5733                    | Intent.FLAG_RECEIVER_FOREGROUND);
5734        }
5735        intent.putExtra(Intent.EXTRA_UID, uid);
5736        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5737        broadcastIntentLocked(null, null, intent,
5738                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5739                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5740    }
5741
5742
5743    private final boolean killPackageProcessesLocked(String packageName, int appId,
5744            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5745            boolean doit, boolean evenPersistent, String reason) {
5746        ArrayList<ProcessRecord> procs = new ArrayList<>();
5747
5748        // Remove all processes this package may have touched: all with the
5749        // same UID (except for the system or root user), and all whose name
5750        // matches the package name.
5751        final int NP = mProcessNames.getMap().size();
5752        for (int ip=0; ip<NP; ip++) {
5753            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5754            final int NA = apps.size();
5755            for (int ia=0; ia<NA; ia++) {
5756                ProcessRecord app = apps.valueAt(ia);
5757                if (app.persistent && !evenPersistent) {
5758                    // we don't kill persistent processes
5759                    continue;
5760                }
5761                if (app.removed) {
5762                    if (doit) {
5763                        procs.add(app);
5764                    }
5765                    continue;
5766                }
5767
5768                // Skip process if it doesn't meet our oom adj requirement.
5769                if (app.setAdj < minOomAdj) {
5770                    continue;
5771                }
5772
5773                // If no package is specified, we call all processes under the
5774                // give user id.
5775                if (packageName == null) {
5776                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5777                        continue;
5778                    }
5779                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5780                        continue;
5781                    }
5782                // Package has been specified, we want to hit all processes
5783                // that match it.  We need to qualify this by the processes
5784                // that are running under the specified app and user ID.
5785                } else {
5786                    final boolean isDep = app.pkgDeps != null
5787                            && app.pkgDeps.contains(packageName);
5788                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5789                        continue;
5790                    }
5791                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5792                        continue;
5793                    }
5794                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5795                        continue;
5796                    }
5797                }
5798
5799                // Process has passed all conditions, kill it!
5800                if (!doit) {
5801                    return true;
5802                }
5803                app.removed = true;
5804                procs.add(app);
5805            }
5806        }
5807
5808        int N = procs.size();
5809        for (int i=0; i<N; i++) {
5810            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5811        }
5812        updateOomAdjLocked();
5813        return N > 0;
5814    }
5815
5816    private void cleanupDisabledPackageComponentsLocked(
5817            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5818
5819        Set<String> disabledClasses = null;
5820        boolean packageDisabled = false;
5821        IPackageManager pm = AppGlobals.getPackageManager();
5822
5823        if (changedClasses == null) {
5824            // Nothing changed...
5825            return;
5826        }
5827
5828        // Determine enable/disable state of the package and its components.
5829        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5830        for (int i = changedClasses.length - 1; i >= 0; i--) {
5831            final String changedClass = changedClasses[i];
5832
5833            if (changedClass.equals(packageName)) {
5834                try {
5835                    // Entire package setting changed
5836                    enabled = pm.getApplicationEnabledSetting(packageName,
5837                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5838                } catch (Exception e) {
5839                    // No such package/component; probably racing with uninstall.  In any
5840                    // event it means we have nothing further to do here.
5841                    return;
5842                }
5843                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5844                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5845                if (packageDisabled) {
5846                    // Entire package is disabled.
5847                    // No need to continue to check component states.
5848                    disabledClasses = null;
5849                    break;
5850                }
5851            } else {
5852                try {
5853                    enabled = pm.getComponentEnabledSetting(
5854                            new ComponentName(packageName, changedClass),
5855                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5856                } catch (Exception e) {
5857                    // As above, probably racing with uninstall.
5858                    return;
5859                }
5860                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5861                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5862                    if (disabledClasses == null) {
5863                        disabledClasses = new ArraySet<>(changedClasses.length);
5864                    }
5865                    disabledClasses.add(changedClass);
5866                }
5867            }
5868        }
5869
5870        if (!packageDisabled && disabledClasses == null) {
5871            // Nothing to do here...
5872            return;
5873        }
5874
5875        // Clean-up disabled activities.
5876        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5877                packageName, disabledClasses, true, false, userId) && mBooted) {
5878            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5879            mStackSupervisor.scheduleIdleLocked();
5880        }
5881
5882        // Clean-up disabled tasks
5883        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5884
5885        // Clean-up disabled services.
5886        mServices.bringDownDisabledPackageServicesLocked(
5887                packageName, disabledClasses, userId, false, killProcess, true);
5888
5889        // Clean-up disabled providers.
5890        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5891        mProviderMap.collectPackageProvidersLocked(
5892                packageName, disabledClasses, true, false, userId, providers);
5893        for (int i = providers.size() - 1; i >= 0; i--) {
5894            removeDyingProviderLocked(null, providers.get(i), true);
5895        }
5896
5897        // Clean-up disabled broadcast receivers.
5898        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5899            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5900                    packageName, disabledClasses, userId, true);
5901        }
5902
5903    }
5904
5905    final boolean forceStopPackageLocked(String packageName, int appId,
5906            boolean callerWillRestart, boolean purgeCache, boolean doit,
5907            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5908        int i;
5909
5910        if (userId == UserHandle.USER_ALL && packageName == null) {
5911            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5912        }
5913
5914        if (appId < 0 && packageName != null) {
5915            try {
5916                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5917                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5918            } catch (RemoteException e) {
5919            }
5920        }
5921
5922        if (doit) {
5923            if (packageName != null) {
5924                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5925                        + " user=" + userId + ": " + reason);
5926            } else {
5927                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5928            }
5929
5930            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
5931        }
5932
5933        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5934                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5935                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5936
5937        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5938                packageName, null, doit, evenPersistent, userId)) {
5939            if (!doit) {
5940                return true;
5941            }
5942            didSomething = true;
5943        }
5944
5945        if (mServices.bringDownDisabledPackageServicesLocked(
5946                packageName, null, userId, evenPersistent, true, doit)) {
5947            if (!doit) {
5948                return true;
5949            }
5950            didSomething = true;
5951        }
5952
5953        if (packageName == null) {
5954            // Remove all sticky broadcasts from this user.
5955            mStickyBroadcasts.remove(userId);
5956        }
5957
5958        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5959        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5960                userId, providers)) {
5961            if (!doit) {
5962                return true;
5963            }
5964            didSomething = true;
5965        }
5966        for (i = providers.size() - 1; i >= 0; i--) {
5967            removeDyingProviderLocked(null, providers.get(i), true);
5968        }
5969
5970        // Remove transient permissions granted from/to this package/user
5971        removeUriPermissionsForPackageLocked(packageName, userId, false);
5972
5973        if (doit) {
5974            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5975                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5976                        packageName, null, userId, doit);
5977            }
5978        }
5979
5980        if (packageName == null || uninstalling) {
5981            // Remove pending intents.  For now we only do this when force
5982            // stopping users, because we have some problems when doing this
5983            // for packages -- app widgets are not currently cleaned up for
5984            // such packages, so they can be left with bad pending intents.
5985            if (mIntentSenderRecords.size() > 0) {
5986                Iterator<WeakReference<PendingIntentRecord>> it
5987                        = mIntentSenderRecords.values().iterator();
5988                while (it.hasNext()) {
5989                    WeakReference<PendingIntentRecord> wpir = it.next();
5990                    if (wpir == null) {
5991                        it.remove();
5992                        continue;
5993                    }
5994                    PendingIntentRecord pir = wpir.get();
5995                    if (pir == null) {
5996                        it.remove();
5997                        continue;
5998                    }
5999                    if (packageName == null) {
6000                        // Stopping user, remove all objects for the user.
6001                        if (pir.key.userId != userId) {
6002                            // Not the same user, skip it.
6003                            continue;
6004                        }
6005                    } else {
6006                        if (UserHandle.getAppId(pir.uid) != appId) {
6007                            // Different app id, skip it.
6008                            continue;
6009                        }
6010                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6011                            // Different user, skip it.
6012                            continue;
6013                        }
6014                        if (!pir.key.packageName.equals(packageName)) {
6015                            // Different package, skip it.
6016                            continue;
6017                        }
6018                    }
6019                    if (!doit) {
6020                        return true;
6021                    }
6022                    didSomething = true;
6023                    it.remove();
6024                    pir.canceled = true;
6025                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6026                        pir.key.activity.pendingResults.remove(pir.ref);
6027                    }
6028                }
6029            }
6030        }
6031
6032        if (doit) {
6033            if (purgeCache && packageName != null) {
6034                AttributeCache ac = AttributeCache.instance();
6035                if (ac != null) {
6036                    ac.removePackage(packageName);
6037                }
6038            }
6039            if (mBooted) {
6040                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6041                mStackSupervisor.scheduleIdleLocked();
6042            }
6043        }
6044
6045        return didSomething;
6046    }
6047
6048    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6049        ProcessRecord old = mProcessNames.remove(name, uid);
6050        if (old != null) {
6051            old.uidRecord.numProcs--;
6052            if (old.uidRecord.numProcs == 0) {
6053                // No more processes using this uid, tell clients it is gone.
6054                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6055                        "No more processes in " + old.uidRecord);
6056                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6057                mActiveUids.remove(uid);
6058                mBatteryStatsService.noteUidProcessState(uid,
6059                        ActivityManager.PROCESS_STATE_NONEXISTENT);
6060            }
6061            old.uidRecord = null;
6062        }
6063        mIsolatedProcesses.remove(uid);
6064        return old;
6065    }
6066
6067    private final void addProcessNameLocked(ProcessRecord proc) {
6068        // We shouldn't already have a process under this name, but just in case we
6069        // need to clean up whatever may be there now.
6070        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6071        if (old == proc && proc.persistent) {
6072            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6073            Slog.w(TAG, "Re-adding persistent process " + proc);
6074        } else if (old != null) {
6075            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6076        }
6077        UidRecord uidRec = mActiveUids.get(proc.uid);
6078        if (uidRec == null) {
6079            uidRec = new UidRecord(proc.uid);
6080            // This is the first appearance of the uid, report it now!
6081            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6082                    "Creating new process uid: " + uidRec);
6083            mActiveUids.put(proc.uid, uidRec);
6084            mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
6085            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6086        }
6087        proc.uidRecord = uidRec;
6088        uidRec.numProcs++;
6089        mProcessNames.put(proc.processName, proc.uid, proc);
6090        if (proc.isolated) {
6091            mIsolatedProcesses.put(proc.uid, proc);
6092        }
6093    }
6094
6095    boolean removeProcessLocked(ProcessRecord app,
6096            boolean callerWillRestart, boolean allowRestart, String reason) {
6097        final String name = app.processName;
6098        final int uid = app.uid;
6099        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6100            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6101
6102        removeProcessNameLocked(name, uid);
6103        if (mHeavyWeightProcess == app) {
6104            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6105                    mHeavyWeightProcess.userId, 0));
6106            mHeavyWeightProcess = null;
6107        }
6108        boolean needRestart = false;
6109        if (app.pid > 0 && app.pid != MY_PID) {
6110            int pid = app.pid;
6111            synchronized (mPidsSelfLocked) {
6112                mPidsSelfLocked.remove(pid);
6113                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6114            }
6115            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6116            if (app.isolated) {
6117                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6118            }
6119            boolean willRestart = false;
6120            if (app.persistent && !app.isolated) {
6121                if (!callerWillRestart) {
6122                    willRestart = true;
6123                } else {
6124                    needRestart = true;
6125                }
6126            }
6127            app.kill(reason, true);
6128            handleAppDiedLocked(app, willRestart, allowRestart);
6129            if (willRestart) {
6130                removeLruProcessLocked(app);
6131                addAppLocked(app.info, false, null /* ABI override */);
6132            }
6133        } else {
6134            mRemovedProcesses.add(app);
6135        }
6136
6137        return needRestart;
6138    }
6139
6140    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6141        cleanupAppInLaunchingProvidersLocked(app, true);
6142        removeProcessLocked(app, false, true, "timeout publishing content providers");
6143    }
6144
6145    private final void processStartTimedOutLocked(ProcessRecord app) {
6146        final int pid = app.pid;
6147        boolean gone = false;
6148        synchronized (mPidsSelfLocked) {
6149            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6150            if (knownApp != null && knownApp.thread == null) {
6151                mPidsSelfLocked.remove(pid);
6152                gone = true;
6153            }
6154        }
6155
6156        if (gone) {
6157            Slog.w(TAG, "Process " + app + " failed to attach");
6158            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6159                    pid, app.uid, app.processName);
6160            removeProcessNameLocked(app.processName, app.uid);
6161            if (mHeavyWeightProcess == app) {
6162                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6163                        mHeavyWeightProcess.userId, 0));
6164                mHeavyWeightProcess = null;
6165            }
6166            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6167            if (app.isolated) {
6168                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6169            }
6170            // Take care of any launching providers waiting for this process.
6171            cleanupAppInLaunchingProvidersLocked(app, true);
6172            // Take care of any services that are waiting for the process.
6173            mServices.processStartTimedOutLocked(app);
6174            app.kill("start timeout", true);
6175            removeLruProcessLocked(app);
6176            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6177                Slog.w(TAG, "Unattached app died before backup, skipping");
6178                try {
6179                    IBackupManager bm = IBackupManager.Stub.asInterface(
6180                            ServiceManager.getService(Context.BACKUP_SERVICE));
6181                    bm.agentDisconnected(app.info.packageName);
6182                } catch (RemoteException e) {
6183                    // Can't happen; the backup manager is local
6184                }
6185            }
6186            if (isPendingBroadcastProcessLocked(pid)) {
6187                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6188                skipPendingBroadcastLocked(pid);
6189            }
6190        } else {
6191            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6192        }
6193    }
6194
6195    private final boolean attachApplicationLocked(IApplicationThread thread,
6196            int pid) {
6197
6198        // Find the application record that is being attached...  either via
6199        // the pid if we are running in multiple processes, or just pull the
6200        // next app record if we are emulating process with anonymous threads.
6201        ProcessRecord app;
6202        if (pid != MY_PID && pid >= 0) {
6203            synchronized (mPidsSelfLocked) {
6204                app = mPidsSelfLocked.get(pid);
6205            }
6206        } else {
6207            app = null;
6208        }
6209
6210        if (app == null) {
6211            Slog.w(TAG, "No pending application record for pid " + pid
6212                    + " (IApplicationThread " + thread + "); dropping process");
6213            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6214            if (pid > 0 && pid != MY_PID) {
6215                Process.killProcessQuiet(pid);
6216                //TODO: killProcessGroup(app.info.uid, pid);
6217            } else {
6218                try {
6219                    thread.scheduleExit();
6220                } catch (Exception e) {
6221                    // Ignore exceptions.
6222                }
6223            }
6224            return false;
6225        }
6226
6227        // If this application record is still attached to a previous
6228        // process, clean it up now.
6229        if (app.thread != null) {
6230            handleAppDiedLocked(app, true, true);
6231        }
6232
6233        // Tell the process all about itself.
6234
6235        if (DEBUG_ALL) Slog.v(
6236                TAG, "Binding process pid " + pid + " to record " + app);
6237
6238        final String processName = app.processName;
6239        try {
6240            AppDeathRecipient adr = new AppDeathRecipient(
6241                    app, pid, thread);
6242            thread.asBinder().linkToDeath(adr, 0);
6243            app.deathRecipient = adr;
6244        } catch (RemoteException e) {
6245            app.resetPackageList(mProcessStats);
6246            startProcessLocked(app, "link fail", processName);
6247            return false;
6248        }
6249
6250        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6251
6252        app.makeActive(thread, mProcessStats);
6253        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6254        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6255        app.forcingToForeground = null;
6256        updateProcessForegroundLocked(app, false, false);
6257        app.hasShownUi = false;
6258        app.debugging = false;
6259        app.cached = false;
6260        app.killedByAm = false;
6261
6262        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6263
6264        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6265        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6266
6267        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6268            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6269            msg.obj = app;
6270            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6271        }
6272
6273        if (!normalMode) {
6274            Slog.i(TAG, "Launching preboot mode app: " + app);
6275        }
6276
6277        if (DEBUG_ALL) Slog.v(
6278            TAG, "New app record " + app
6279            + " thread=" + thread.asBinder() + " pid=" + pid);
6280        try {
6281            int testMode = IApplicationThread.DEBUG_OFF;
6282            if (mDebugApp != null && mDebugApp.equals(processName)) {
6283                testMode = mWaitForDebugger
6284                    ? IApplicationThread.DEBUG_WAIT
6285                    : IApplicationThread.DEBUG_ON;
6286                app.debugging = true;
6287                if (mDebugTransient) {
6288                    mDebugApp = mOrigDebugApp;
6289                    mWaitForDebugger = mOrigWaitForDebugger;
6290                }
6291            }
6292            String profileFile = app.instrumentationProfileFile;
6293            ParcelFileDescriptor profileFd = null;
6294            int samplingInterval = 0;
6295            boolean profileAutoStop = false;
6296            if (mProfileApp != null && mProfileApp.equals(processName)) {
6297                mProfileProc = app;
6298                profileFile = mProfileFile;
6299                profileFd = mProfileFd;
6300                samplingInterval = mSamplingInterval;
6301                profileAutoStop = mAutoStopProfiler;
6302            }
6303            boolean enableTrackAllocation = false;
6304            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6305                enableTrackAllocation = true;
6306                mTrackAllocationApp = null;
6307            }
6308
6309            // If the app is being launched for restore or full backup, set it up specially
6310            boolean isRestrictedBackupMode = false;
6311            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6312                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6313                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6314                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6315                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6316            }
6317
6318            notifyPackageUse(app.instrumentationInfo != null
6319                    ? app.instrumentationInfo.packageName
6320                    : app.info.packageName);
6321            if (app.instrumentationClass != null) {
6322                notifyPackageUse(app.instrumentationClass.getPackageName());
6323            }
6324            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6325                    + processName + " with config " + mConfiguration);
6326            ApplicationInfo appInfo = app.instrumentationInfo != null
6327                    ? app.instrumentationInfo : app.info;
6328            app.compat = compatibilityInfoForPackageLocked(appInfo);
6329            if (profileFd != null) {
6330                profileFd = profileFd.dup();
6331            }
6332            ProfilerInfo profilerInfo = profileFile == null ? null
6333                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6334            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6335                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6336                    app.instrumentationUiAutomationConnection, testMode,
6337                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6338                    isRestrictedBackupMode || !normalMode, app.persistent,
6339                    new Configuration(mConfiguration), app.compat,
6340                    getCommonServicesLocked(app.isolated),
6341                    mCoreSettingsObserver.getCoreSettingsLocked());
6342            updateLruProcessLocked(app, false, null);
6343            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6344        } catch (Exception e) {
6345            // todo: Yikes!  What should we do?  For now we will try to
6346            // start another process, but that could easily get us in
6347            // an infinite loop of restarting processes...
6348            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6349
6350            app.resetPackageList(mProcessStats);
6351            app.unlinkDeathRecipient();
6352            startProcessLocked(app, "bind fail", processName);
6353            return false;
6354        }
6355
6356        // Remove this record from the list of starting applications.
6357        mPersistentStartingProcesses.remove(app);
6358        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6359                "Attach application locked removing on hold: " + app);
6360        mProcessesOnHold.remove(app);
6361
6362        boolean badApp = false;
6363        boolean didSomething = false;
6364
6365        // See if the top visible activity is waiting to run in this process...
6366        if (normalMode) {
6367            try {
6368                if (mStackSupervisor.attachApplicationLocked(app)) {
6369                    didSomething = true;
6370                }
6371            } catch (Exception e) {
6372                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6373                badApp = true;
6374            }
6375        }
6376
6377        // Find any services that should be running in this process...
6378        if (!badApp) {
6379            try {
6380                didSomething |= mServices.attachApplicationLocked(app, processName);
6381            } catch (Exception e) {
6382                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6383                badApp = true;
6384            }
6385        }
6386
6387        // Check if a next-broadcast receiver is in this process...
6388        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6389            try {
6390                didSomething |= sendPendingBroadcastsLocked(app);
6391            } catch (Exception e) {
6392                // If the app died trying to launch the receiver we declare it 'bad'
6393                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6394                badApp = true;
6395            }
6396        }
6397
6398        // Check whether the next backup agent is in this process...
6399        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6400            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6401                    "New app is backup target, launching agent for " + app);
6402            notifyPackageUse(mBackupTarget.appInfo.packageName);
6403            try {
6404                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6405                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6406                        mBackupTarget.backupMode);
6407            } catch (Exception e) {
6408                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6409                badApp = true;
6410            }
6411        }
6412
6413        if (badApp) {
6414            app.kill("error during init", true);
6415            handleAppDiedLocked(app, false, true);
6416            return false;
6417        }
6418
6419        if (!didSomething) {
6420            updateOomAdjLocked();
6421        }
6422
6423        return true;
6424    }
6425
6426    @Override
6427    public final void attachApplication(IApplicationThread thread) {
6428        synchronized (this) {
6429            int callingPid = Binder.getCallingPid();
6430            final long origId = Binder.clearCallingIdentity();
6431            attachApplicationLocked(thread, callingPid);
6432            Binder.restoreCallingIdentity(origId);
6433        }
6434    }
6435
6436    @Override
6437    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6438        final long origId = Binder.clearCallingIdentity();
6439        synchronized (this) {
6440            ActivityStack stack = ActivityRecord.getStackLocked(token);
6441            if (stack != null) {
6442                ActivityRecord r =
6443                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6444                if (stopProfiling) {
6445                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6446                        try {
6447                            mProfileFd.close();
6448                        } catch (IOException e) {
6449                        }
6450                        clearProfilerLocked();
6451                    }
6452                }
6453            }
6454        }
6455        Binder.restoreCallingIdentity(origId);
6456    }
6457
6458    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6459        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6460                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6461    }
6462
6463    void enableScreenAfterBoot() {
6464        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6465                SystemClock.uptimeMillis());
6466        mWindowManager.enableScreenAfterBoot();
6467
6468        synchronized (this) {
6469            updateEventDispatchingLocked();
6470        }
6471    }
6472
6473    @Override
6474    public void showBootMessage(final CharSequence msg, final boolean always) {
6475        if (Binder.getCallingUid() != Process.myUid()) {
6476            // These days only the core system can call this, so apps can't get in
6477            // the way of what we show about running them.
6478        }
6479        mWindowManager.showBootMessage(msg, always);
6480    }
6481
6482    @Override
6483    public void keyguardWaitingForActivityDrawn() {
6484        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6485        final long token = Binder.clearCallingIdentity();
6486        try {
6487            synchronized (this) {
6488                if (DEBUG_LOCKSCREEN) logLockScreen("");
6489                mWindowManager.keyguardWaitingForActivityDrawn();
6490                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6491                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6492                    updateSleepIfNeededLocked();
6493                }
6494            }
6495        } finally {
6496            Binder.restoreCallingIdentity(token);
6497        }
6498    }
6499
6500    @Override
6501    public void keyguardGoingAway(int flags) {
6502        enforceNotIsolatedCaller("keyguardGoingAway");
6503        final long token = Binder.clearCallingIdentity();
6504        try {
6505            synchronized (this) {
6506                if (DEBUG_LOCKSCREEN) logLockScreen("");
6507                mWindowManager.keyguardGoingAway(flags);
6508                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6509                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6510                    updateSleepIfNeededLocked();
6511
6512                    // Some stack visibility might change (e.g. docked stack)
6513                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6514                }
6515            }
6516        } finally {
6517            Binder.restoreCallingIdentity(token);
6518        }
6519    }
6520
6521    final void finishBooting() {
6522        synchronized (this) {
6523            if (!mBootAnimationComplete) {
6524                mCallFinishBooting = true;
6525                return;
6526            }
6527            mCallFinishBooting = false;
6528        }
6529
6530        ArraySet<String> completedIsas = new ArraySet<String>();
6531        for (String abi : Build.SUPPORTED_ABIS) {
6532            Process.establishZygoteConnectionForAbi(abi);
6533            final String instructionSet = VMRuntime.getInstructionSet(abi);
6534            if (!completedIsas.contains(instructionSet)) {
6535                try {
6536                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6537                } catch (InstallerException e) {
6538                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
6539                }
6540                completedIsas.add(instructionSet);
6541            }
6542        }
6543
6544        IntentFilter pkgFilter = new IntentFilter();
6545        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6546        pkgFilter.addDataScheme("package");
6547        mContext.registerReceiver(new BroadcastReceiver() {
6548            @Override
6549            public void onReceive(Context context, Intent intent) {
6550                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6551                if (pkgs != null) {
6552                    for (String pkg : pkgs) {
6553                        synchronized (ActivityManagerService.this) {
6554                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6555                                    0, "query restart")) {
6556                                setResultCode(Activity.RESULT_OK);
6557                                return;
6558                            }
6559                        }
6560                    }
6561                }
6562            }
6563        }, pkgFilter);
6564
6565        IntentFilter dumpheapFilter = new IntentFilter();
6566        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6567        mContext.registerReceiver(new BroadcastReceiver() {
6568            @Override
6569            public void onReceive(Context context, Intent intent) {
6570                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6571                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6572                } else {
6573                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6574                }
6575            }
6576        }, dumpheapFilter);
6577
6578        mProcessStartLogger.registerListener(mContext);
6579
6580        // Let system services know.
6581        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6582
6583        synchronized (this) {
6584            // Ensure that any processes we had put on hold are now started
6585            // up.
6586            final int NP = mProcessesOnHold.size();
6587            if (NP > 0) {
6588                ArrayList<ProcessRecord> procs =
6589                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6590                for (int ip=0; ip<NP; ip++) {
6591                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6592                            + procs.get(ip));
6593                    startProcessLocked(procs.get(ip), "on-hold", null);
6594                }
6595            }
6596
6597            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6598                // Start looking for apps that are abusing wake locks.
6599                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6600                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6601                // Tell anyone interested that we are done booting!
6602                SystemProperties.set("sys.boot_completed", "1");
6603
6604                // And trigger dev.bootcomplete if we are not showing encryption progress
6605                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6606                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6607                    SystemProperties.set("dev.bootcomplete", "1");
6608                }
6609                mUserController.sendBootCompletedLocked(
6610                        new IIntentReceiver.Stub() {
6611                            @Override
6612                            public void performReceive(Intent intent, int resultCode,
6613                                    String data, Bundle extras, boolean ordered,
6614                                    boolean sticky, int sendingUser) {
6615                                synchronized (ActivityManagerService.this) {
6616                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6617                                            true, false);
6618                                }
6619                            }
6620                        });
6621                scheduleStartProfilesLocked();
6622            }
6623        }
6624    }
6625
6626    @Override
6627    public void bootAnimationComplete() {
6628        final boolean callFinishBooting;
6629        synchronized (this) {
6630            callFinishBooting = mCallFinishBooting;
6631            mBootAnimationComplete = true;
6632        }
6633        if (callFinishBooting) {
6634            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6635            finishBooting();
6636            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6637        }
6638    }
6639
6640    final void ensureBootCompleted() {
6641        boolean booting;
6642        boolean enableScreen;
6643        synchronized (this) {
6644            booting = mBooting;
6645            mBooting = false;
6646            enableScreen = !mBooted;
6647            mBooted = true;
6648        }
6649
6650        if (booting) {
6651            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6652            finishBooting();
6653            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6654        }
6655
6656        if (enableScreen) {
6657            enableScreenAfterBoot();
6658        }
6659    }
6660
6661    @Override
6662    public final void activityResumed(IBinder token) {
6663        final long origId = Binder.clearCallingIdentity();
6664        synchronized(this) {
6665            ActivityStack stack = ActivityRecord.getStackLocked(token);
6666            if (stack != null) {
6667                stack.activityResumedLocked(token);
6668            }
6669        }
6670        Binder.restoreCallingIdentity(origId);
6671    }
6672
6673    @Override
6674    public final void activityPaused(IBinder token) {
6675        final long origId = Binder.clearCallingIdentity();
6676        synchronized(this) {
6677            ActivityStack stack = ActivityRecord.getStackLocked(token);
6678            if (stack != null) {
6679                stack.activityPausedLocked(token, false);
6680            }
6681        }
6682        Binder.restoreCallingIdentity(origId);
6683    }
6684
6685    @Override
6686    public final void activityStopped(IBinder token, Bundle icicle,
6687            PersistableBundle persistentState, CharSequence description) {
6688        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6689
6690        // Refuse possible leaked file descriptors
6691        if (icicle != null && icicle.hasFileDescriptors()) {
6692            throw new IllegalArgumentException("File descriptors passed in Bundle");
6693        }
6694
6695        final long origId = Binder.clearCallingIdentity();
6696
6697        synchronized (this) {
6698            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6699            if (r != null) {
6700                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6701            }
6702        }
6703
6704        trimApplications();
6705
6706        Binder.restoreCallingIdentity(origId);
6707    }
6708
6709    @Override
6710    public final void activityDestroyed(IBinder token) {
6711        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6712        synchronized (this) {
6713            ActivityStack stack = ActivityRecord.getStackLocked(token);
6714            if (stack != null) {
6715                stack.activityDestroyedLocked(token, "activityDestroyed");
6716            }
6717        }
6718    }
6719
6720    @Override
6721    public final void activityRelaunched(IBinder token) {
6722        final long origId = Binder.clearCallingIdentity();
6723        synchronized (this) {
6724            mStackSupervisor.activityRelaunchedLocked(token);
6725        }
6726        Binder.restoreCallingIdentity(origId);
6727    }
6728
6729    @Override
6730    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6731            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6732        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6733                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6734        synchronized (this) {
6735            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6736            if (record == null) {
6737                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6738                        + "found for: " + token);
6739            }
6740            record.setSizeConfigurations(horizontalSizeConfiguration,
6741                    verticalSizeConfigurations, smallestSizeConfigurations);
6742        }
6743    }
6744
6745    @Override
6746    public final void backgroundResourcesReleased(IBinder token) {
6747        final long origId = Binder.clearCallingIdentity();
6748        try {
6749            synchronized (this) {
6750                ActivityStack stack = ActivityRecord.getStackLocked(token);
6751                if (stack != null) {
6752                    stack.backgroundResourcesReleased();
6753                }
6754            }
6755        } finally {
6756            Binder.restoreCallingIdentity(origId);
6757        }
6758    }
6759
6760    @Override
6761    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6762        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6763    }
6764
6765    @Override
6766    public final void notifyEnterAnimationComplete(IBinder token) {
6767        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6768    }
6769
6770    @Override
6771    public String getCallingPackage(IBinder token) {
6772        synchronized (this) {
6773            ActivityRecord r = getCallingRecordLocked(token);
6774            return r != null ? r.info.packageName : null;
6775        }
6776    }
6777
6778    @Override
6779    public ComponentName getCallingActivity(IBinder token) {
6780        synchronized (this) {
6781            ActivityRecord r = getCallingRecordLocked(token);
6782            return r != null ? r.intent.getComponent() : null;
6783        }
6784    }
6785
6786    private ActivityRecord getCallingRecordLocked(IBinder token) {
6787        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6788        if (r == null) {
6789            return null;
6790        }
6791        return r.resultTo;
6792    }
6793
6794    @Override
6795    public ComponentName getActivityClassForToken(IBinder token) {
6796        synchronized(this) {
6797            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6798            if (r == null) {
6799                return null;
6800            }
6801            return r.intent.getComponent();
6802        }
6803    }
6804
6805    @Override
6806    public String getPackageForToken(IBinder token) {
6807        synchronized(this) {
6808            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6809            if (r == null) {
6810                return null;
6811            }
6812            return r.packageName;
6813        }
6814    }
6815
6816    @Override
6817    public boolean isRootVoiceInteraction(IBinder token) {
6818        synchronized(this) {
6819            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6820            if (r == null) {
6821                return false;
6822            }
6823            return r.rootVoiceInteraction;
6824        }
6825    }
6826
6827    @Override
6828    public IIntentSender getIntentSender(int type,
6829            String packageName, IBinder token, String resultWho,
6830            int requestCode, Intent[] intents, String[] resolvedTypes,
6831            int flags, Bundle bOptions, int userId) {
6832        enforceNotIsolatedCaller("getIntentSender");
6833        // Refuse possible leaked file descriptors
6834        if (intents != null) {
6835            if (intents.length < 1) {
6836                throw new IllegalArgumentException("Intents array length must be >= 1");
6837            }
6838            for (int i=0; i<intents.length; i++) {
6839                Intent intent = intents[i];
6840                if (intent != null) {
6841                    if (intent.hasFileDescriptors()) {
6842                        throw new IllegalArgumentException("File descriptors passed in Intent");
6843                    }
6844                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6845                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6846                        throw new IllegalArgumentException(
6847                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6848                    }
6849                    intents[i] = new Intent(intent);
6850                }
6851            }
6852            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6853                throw new IllegalArgumentException(
6854                        "Intent array length does not match resolvedTypes length");
6855            }
6856        }
6857        if (bOptions != null) {
6858            if (bOptions.hasFileDescriptors()) {
6859                throw new IllegalArgumentException("File descriptors passed in options");
6860            }
6861        }
6862
6863        synchronized(this) {
6864            int callingUid = Binder.getCallingUid();
6865            int origUserId = userId;
6866            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6867                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6868                    ALLOW_NON_FULL, "getIntentSender", null);
6869            if (origUserId == UserHandle.USER_CURRENT) {
6870                // We don't want to evaluate this until the pending intent is
6871                // actually executed.  However, we do want to always do the
6872                // security checking for it above.
6873                userId = UserHandle.USER_CURRENT;
6874            }
6875            try {
6876                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6877                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6878                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6879                    if (!UserHandle.isSameApp(callingUid, uid)) {
6880                        String msg = "Permission Denial: getIntentSender() from pid="
6881                            + Binder.getCallingPid()
6882                            + ", uid=" + Binder.getCallingUid()
6883                            + ", (need uid=" + uid + ")"
6884                            + " is not allowed to send as package " + packageName;
6885                        Slog.w(TAG, msg);
6886                        throw new SecurityException(msg);
6887                    }
6888                }
6889
6890                return getIntentSenderLocked(type, packageName, callingUid, userId,
6891                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6892
6893            } catch (RemoteException e) {
6894                throw new SecurityException(e);
6895            }
6896        }
6897    }
6898
6899    IIntentSender getIntentSenderLocked(int type, String packageName,
6900            int callingUid, int userId, IBinder token, String resultWho,
6901            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6902            Bundle bOptions) {
6903        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6904        ActivityRecord activity = null;
6905        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6906            activity = ActivityRecord.isInStackLocked(token);
6907            if (activity == null) {
6908                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6909                return null;
6910            }
6911            if (activity.finishing) {
6912                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6913                return null;
6914            }
6915        }
6916
6917        // We're going to be splicing together extras before sending, so we're
6918        // okay poking into any contained extras.
6919        if (intents != null) {
6920            for (int i = 0; i < intents.length; i++) {
6921                intents[i].setDefusable(true);
6922            }
6923        }
6924
6925        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6926        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6927        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6928        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6929                |PendingIntent.FLAG_UPDATE_CURRENT);
6930
6931        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6932                type, packageName, activity, resultWho,
6933                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6934        WeakReference<PendingIntentRecord> ref;
6935        ref = mIntentSenderRecords.get(key);
6936        PendingIntentRecord rec = ref != null ? ref.get() : null;
6937        if (rec != null) {
6938            if (!cancelCurrent) {
6939                if (updateCurrent) {
6940                    if (rec.key.requestIntent != null) {
6941                        rec.key.requestIntent.replaceExtras(intents != null ?
6942                                intents[intents.length - 1] : null);
6943                    }
6944                    if (intents != null) {
6945                        intents[intents.length-1] = rec.key.requestIntent;
6946                        rec.key.allIntents = intents;
6947                        rec.key.allResolvedTypes = resolvedTypes;
6948                    } else {
6949                        rec.key.allIntents = null;
6950                        rec.key.allResolvedTypes = null;
6951                    }
6952                }
6953                return rec;
6954            }
6955            rec.canceled = true;
6956            mIntentSenderRecords.remove(key);
6957        }
6958        if (noCreate) {
6959            return rec;
6960        }
6961        rec = new PendingIntentRecord(this, key, callingUid);
6962        mIntentSenderRecords.put(key, rec.ref);
6963        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6964            if (activity.pendingResults == null) {
6965                activity.pendingResults
6966                        = new HashSet<WeakReference<PendingIntentRecord>>();
6967            }
6968            activity.pendingResults.add(rec.ref);
6969        }
6970        return rec;
6971    }
6972
6973    @Override
6974    public void cancelIntentSender(IIntentSender sender) {
6975        if (!(sender instanceof PendingIntentRecord)) {
6976            return;
6977        }
6978        synchronized(this) {
6979            PendingIntentRecord rec = (PendingIntentRecord)sender;
6980            try {
6981                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
6982                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
6983                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6984                    String msg = "Permission Denial: cancelIntentSender() from pid="
6985                        + Binder.getCallingPid()
6986                        + ", uid=" + Binder.getCallingUid()
6987                        + " is not allowed to cancel packges "
6988                        + rec.key.packageName;
6989                    Slog.w(TAG, msg);
6990                    throw new SecurityException(msg);
6991                }
6992            } catch (RemoteException e) {
6993                throw new SecurityException(e);
6994            }
6995            cancelIntentSenderLocked(rec, true);
6996        }
6997    }
6998
6999    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7000        rec.canceled = true;
7001        mIntentSenderRecords.remove(rec.key);
7002        if (cleanActivity && rec.key.activity != null) {
7003            rec.key.activity.pendingResults.remove(rec.ref);
7004        }
7005    }
7006
7007    @Override
7008    public String getPackageForIntentSender(IIntentSender pendingResult) {
7009        if (!(pendingResult instanceof PendingIntentRecord)) {
7010            return null;
7011        }
7012        try {
7013            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7014            return res.key.packageName;
7015        } catch (ClassCastException e) {
7016        }
7017        return null;
7018    }
7019
7020    @Override
7021    public int getUidForIntentSender(IIntentSender sender) {
7022        if (sender instanceof PendingIntentRecord) {
7023            try {
7024                PendingIntentRecord res = (PendingIntentRecord)sender;
7025                return res.uid;
7026            } catch (ClassCastException e) {
7027            }
7028        }
7029        return -1;
7030    }
7031
7032    @Override
7033    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7034        if (!(pendingResult instanceof PendingIntentRecord)) {
7035            return false;
7036        }
7037        try {
7038            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7039            if (res.key.allIntents == null) {
7040                return false;
7041            }
7042            for (int i=0; i<res.key.allIntents.length; i++) {
7043                Intent intent = res.key.allIntents[i];
7044                if (intent.getPackage() != null && intent.getComponent() != null) {
7045                    return false;
7046                }
7047            }
7048            return true;
7049        } catch (ClassCastException e) {
7050        }
7051        return false;
7052    }
7053
7054    @Override
7055    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7056        if (!(pendingResult instanceof PendingIntentRecord)) {
7057            return false;
7058        }
7059        try {
7060            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7061            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7062                return true;
7063            }
7064            return false;
7065        } catch (ClassCastException e) {
7066        }
7067        return false;
7068    }
7069
7070    @Override
7071    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7072        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7073                "getIntentForIntentSender()");
7074        if (!(pendingResult instanceof PendingIntentRecord)) {
7075            return null;
7076        }
7077        try {
7078            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7079            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7080        } catch (ClassCastException e) {
7081        }
7082        return null;
7083    }
7084
7085    @Override
7086    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7087        if (!(pendingResult instanceof PendingIntentRecord)) {
7088            return null;
7089        }
7090        try {
7091            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7092            synchronized (this) {
7093                return getTagForIntentSenderLocked(res, prefix);
7094            }
7095        } catch (ClassCastException e) {
7096        }
7097        return null;
7098    }
7099
7100    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7101        final Intent intent = res.key.requestIntent;
7102        if (intent != null) {
7103            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7104                    || res.lastTagPrefix.equals(prefix))) {
7105                return res.lastTag;
7106            }
7107            res.lastTagPrefix = prefix;
7108            final StringBuilder sb = new StringBuilder(128);
7109            if (prefix != null) {
7110                sb.append(prefix);
7111            }
7112            if (intent.getAction() != null) {
7113                sb.append(intent.getAction());
7114            } else if (intent.getComponent() != null) {
7115                intent.getComponent().appendShortString(sb);
7116            } else {
7117                sb.append("?");
7118            }
7119            return res.lastTag = sb.toString();
7120        }
7121        return null;
7122    }
7123
7124    @Override
7125    public void setProcessLimit(int max) {
7126        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7127                "setProcessLimit()");
7128        synchronized (this) {
7129            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7130            mProcessLimitOverride = max;
7131        }
7132        trimApplications();
7133    }
7134
7135    @Override
7136    public int getProcessLimit() {
7137        synchronized (this) {
7138            return mProcessLimitOverride;
7139        }
7140    }
7141
7142    void foregroundTokenDied(ForegroundToken token) {
7143        synchronized (ActivityManagerService.this) {
7144            synchronized (mPidsSelfLocked) {
7145                ForegroundToken cur
7146                    = mForegroundProcesses.get(token.pid);
7147                if (cur != token) {
7148                    return;
7149                }
7150                mForegroundProcesses.remove(token.pid);
7151                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7152                if (pr == null) {
7153                    return;
7154                }
7155                pr.forcingToForeground = null;
7156                updateProcessForegroundLocked(pr, false, false);
7157            }
7158            updateOomAdjLocked();
7159        }
7160    }
7161
7162    @Override
7163    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7164        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7165                "setProcessForeground()");
7166        synchronized(this) {
7167            boolean changed = false;
7168
7169            synchronized (mPidsSelfLocked) {
7170                ProcessRecord pr = mPidsSelfLocked.get(pid);
7171                if (pr == null && isForeground) {
7172                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7173                    return;
7174                }
7175                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7176                if (oldToken != null) {
7177                    oldToken.token.unlinkToDeath(oldToken, 0);
7178                    mForegroundProcesses.remove(pid);
7179                    if (pr != null) {
7180                        pr.forcingToForeground = null;
7181                    }
7182                    changed = true;
7183                }
7184                if (isForeground && token != null) {
7185                    ForegroundToken newToken = new ForegroundToken() {
7186                        @Override
7187                        public void binderDied() {
7188                            foregroundTokenDied(this);
7189                        }
7190                    };
7191                    newToken.pid = pid;
7192                    newToken.token = token;
7193                    try {
7194                        token.linkToDeath(newToken, 0);
7195                        mForegroundProcesses.put(pid, newToken);
7196                        pr.forcingToForeground = token;
7197                        changed = true;
7198                    } catch (RemoteException e) {
7199                        // If the process died while doing this, we will later
7200                        // do the cleanup with the process death link.
7201                    }
7202                }
7203            }
7204
7205            if (changed) {
7206                updateOomAdjLocked();
7207            }
7208        }
7209    }
7210
7211    @Override
7212    public boolean isAppForeground(int uid) throws RemoteException {
7213        synchronized (this) {
7214            UidRecord uidRec = mActiveUids.get(uid);
7215            if (uidRec == null || uidRec.idle) {
7216                return false;
7217            }
7218            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7219        }
7220    }
7221
7222    @Override
7223    public boolean inMultiWindow(IBinder token) {
7224        final long origId = Binder.clearCallingIdentity();
7225        try {
7226            synchronized(this) {
7227                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7228                if (r == null) {
7229                    return false;
7230                }
7231                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7232                return !r.task.mFullscreen;
7233            }
7234        } finally {
7235            Binder.restoreCallingIdentity(origId);
7236        }
7237    }
7238
7239    @Override
7240    public boolean inPictureInPicture(IBinder token) {
7241        final long origId = Binder.clearCallingIdentity();
7242        try {
7243            synchronized(this) {
7244                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7245                if (stack == null) {
7246                    return false;
7247                }
7248                return stack.mStackId == PINNED_STACK_ID;
7249            }
7250        } finally {
7251            Binder.restoreCallingIdentity(origId);
7252        }
7253    }
7254
7255    @Override
7256    public void enterPictureInPicture(IBinder token) {
7257        final long origId = Binder.clearCallingIdentity();
7258        try {
7259            synchronized(this) {
7260                if (!mSupportsPictureInPicture) {
7261                    throw new IllegalStateException("enterPictureInPicture: "
7262                            + "Device doesn't support picture-in-picture mode.");
7263                }
7264
7265                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7266
7267                if (r == null) {
7268                    throw new IllegalStateException("enterPictureInPicture: "
7269                            + "Can't find activity for token=" + token);
7270                }
7271
7272                if (!r.supportsPictureInPicture()) {
7273                    throw new IllegalArgumentException("enterPictureInPicture: "
7274                            + "Picture-In-Picture not supported for r=" + r);
7275                }
7276
7277                // Use the default launch bounds for pinned stack if it doesn't exist yet.
7278                final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7279                        ? mDefaultPinnedStackBounds : null;
7280
7281                mStackSupervisor.moveActivityToPinnedStackLocked(
7282                        r, "enterPictureInPicture", bounds);
7283            }
7284        } finally {
7285            Binder.restoreCallingIdentity(origId);
7286        }
7287    }
7288
7289    // =========================================================
7290    // PROCESS INFO
7291    // =========================================================
7292
7293    static class ProcessInfoService extends IProcessInfoService.Stub {
7294        final ActivityManagerService mActivityManagerService;
7295        ProcessInfoService(ActivityManagerService activityManagerService) {
7296            mActivityManagerService = activityManagerService;
7297        }
7298
7299        @Override
7300        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7301            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7302                    /*in*/ pids, /*out*/ states, null);
7303        }
7304
7305        @Override
7306        public void getProcessStatesAndOomScoresFromPids(
7307                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7308            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7309                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7310        }
7311    }
7312
7313    /**
7314     * For each PID in the given input array, write the current process state
7315     * for that process into the states array, or -1 to indicate that no
7316     * process with the given PID exists. If scores array is provided, write
7317     * the oom score for the process into the scores array, with INVALID_ADJ
7318     * indicating the PID doesn't exist.
7319     */
7320    public void getProcessStatesAndOomScoresForPIDs(
7321            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7322        if (scores != null) {
7323            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7324                    "getProcessStatesAndOomScoresForPIDs()");
7325        }
7326
7327        if (pids == null) {
7328            throw new NullPointerException("pids");
7329        } else if (states == null) {
7330            throw new NullPointerException("states");
7331        } else if (pids.length != states.length) {
7332            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7333        } else if (scores != null && pids.length != scores.length) {
7334            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7335        }
7336
7337        synchronized (mPidsSelfLocked) {
7338            for (int i = 0; i < pids.length; i++) {
7339                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7340                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7341                        pr.curProcState;
7342                if (scores != null) {
7343                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7344                }
7345            }
7346        }
7347    }
7348
7349    // =========================================================
7350    // PERMISSIONS
7351    // =========================================================
7352
7353    static class PermissionController extends IPermissionController.Stub {
7354        ActivityManagerService mActivityManagerService;
7355        PermissionController(ActivityManagerService activityManagerService) {
7356            mActivityManagerService = activityManagerService;
7357        }
7358
7359        @Override
7360        public boolean checkPermission(String permission, int pid, int uid) {
7361            return mActivityManagerService.checkPermission(permission, pid,
7362                    uid) == PackageManager.PERMISSION_GRANTED;
7363        }
7364
7365        @Override
7366        public String[] getPackagesForUid(int uid) {
7367            return mActivityManagerService.mContext.getPackageManager()
7368                    .getPackagesForUid(uid);
7369        }
7370
7371        @Override
7372        public boolean isRuntimePermission(String permission) {
7373            try {
7374                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7375                        .getPermissionInfo(permission, 0);
7376                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7377            } catch (NameNotFoundException nnfe) {
7378                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7379            }
7380            return false;
7381        }
7382    }
7383
7384    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7385        @Override
7386        public int checkComponentPermission(String permission, int pid, int uid,
7387                int owningUid, boolean exported) {
7388            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7389                    owningUid, exported);
7390        }
7391
7392        @Override
7393        public Object getAMSLock() {
7394            return ActivityManagerService.this;
7395        }
7396    }
7397
7398    /**
7399     * This can be called with or without the global lock held.
7400     */
7401    int checkComponentPermission(String permission, int pid, int uid,
7402            int owningUid, boolean exported) {
7403        if (pid == MY_PID) {
7404            return PackageManager.PERMISSION_GRANTED;
7405        }
7406        return ActivityManager.checkComponentPermission(permission, uid,
7407                owningUid, exported);
7408    }
7409
7410    /**
7411     * As the only public entry point for permissions checking, this method
7412     * can enforce the semantic that requesting a check on a null global
7413     * permission is automatically denied.  (Internally a null permission
7414     * string is used when calling {@link #checkComponentPermission} in cases
7415     * when only uid-based security is needed.)
7416     *
7417     * This can be called with or without the global lock held.
7418     */
7419    @Override
7420    public int checkPermission(String permission, int pid, int uid) {
7421        if (permission == null) {
7422            return PackageManager.PERMISSION_DENIED;
7423        }
7424        return checkComponentPermission(permission, pid, uid, -1, true);
7425    }
7426
7427    @Override
7428    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7429        if (permission == null) {
7430            return PackageManager.PERMISSION_DENIED;
7431        }
7432
7433        // We might be performing an operation on behalf of an indirect binder
7434        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7435        // client identity accordingly before proceeding.
7436        Identity tlsIdentity = sCallerIdentity.get();
7437        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7438            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7439                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7440            uid = tlsIdentity.uid;
7441            pid = tlsIdentity.pid;
7442        }
7443
7444        return checkComponentPermission(permission, pid, uid, -1, true);
7445    }
7446
7447    /**
7448     * Binder IPC calls go through the public entry point.
7449     * This can be called with or without the global lock held.
7450     */
7451    int checkCallingPermission(String permission) {
7452        return checkPermission(permission,
7453                Binder.getCallingPid(),
7454                UserHandle.getAppId(Binder.getCallingUid()));
7455    }
7456
7457    /**
7458     * This can be called with or without the global lock held.
7459     */
7460    void enforceCallingPermission(String permission, String func) {
7461        if (checkCallingPermission(permission)
7462                == PackageManager.PERMISSION_GRANTED) {
7463            return;
7464        }
7465
7466        String msg = "Permission Denial: " + func + " from pid="
7467                + Binder.getCallingPid()
7468                + ", uid=" + Binder.getCallingUid()
7469                + " requires " + permission;
7470        Slog.w(TAG, msg);
7471        throw new SecurityException(msg);
7472    }
7473
7474    /**
7475     * Determine if UID is holding permissions required to access {@link Uri} in
7476     * the given {@link ProviderInfo}. Final permission checking is always done
7477     * in {@link ContentProvider}.
7478     */
7479    private final boolean checkHoldingPermissionsLocked(
7480            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7481        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7482                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7483        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7484            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7485                    != PERMISSION_GRANTED) {
7486                return false;
7487            }
7488        }
7489        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7490    }
7491
7492    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7493            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7494        if (pi.applicationInfo.uid == uid) {
7495            return true;
7496        } else if (!pi.exported) {
7497            return false;
7498        }
7499
7500        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7501        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7502        try {
7503            // check if target holds top-level <provider> permissions
7504            if (!readMet && pi.readPermission != null && considerUidPermissions
7505                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7506                readMet = true;
7507            }
7508            if (!writeMet && pi.writePermission != null && considerUidPermissions
7509                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7510                writeMet = true;
7511            }
7512
7513            // track if unprotected read/write is allowed; any denied
7514            // <path-permission> below removes this ability
7515            boolean allowDefaultRead = pi.readPermission == null;
7516            boolean allowDefaultWrite = pi.writePermission == null;
7517
7518            // check if target holds any <path-permission> that match uri
7519            final PathPermission[] pps = pi.pathPermissions;
7520            if (pps != null) {
7521                final String path = grantUri.uri.getPath();
7522                int i = pps.length;
7523                while (i > 0 && (!readMet || !writeMet)) {
7524                    i--;
7525                    PathPermission pp = pps[i];
7526                    if (pp.match(path)) {
7527                        if (!readMet) {
7528                            final String pprperm = pp.getReadPermission();
7529                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7530                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7531                                    + ": match=" + pp.match(path)
7532                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7533                            if (pprperm != null) {
7534                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7535                                        == PERMISSION_GRANTED) {
7536                                    readMet = true;
7537                                } else {
7538                                    allowDefaultRead = false;
7539                                }
7540                            }
7541                        }
7542                        if (!writeMet) {
7543                            final String ppwperm = pp.getWritePermission();
7544                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7545                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7546                                    + ": match=" + pp.match(path)
7547                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7548                            if (ppwperm != null) {
7549                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7550                                        == PERMISSION_GRANTED) {
7551                                    writeMet = true;
7552                                } else {
7553                                    allowDefaultWrite = false;
7554                                }
7555                            }
7556                        }
7557                    }
7558                }
7559            }
7560
7561            // grant unprotected <provider> read/write, if not blocked by
7562            // <path-permission> above
7563            if (allowDefaultRead) readMet = true;
7564            if (allowDefaultWrite) writeMet = true;
7565
7566        } catch (RemoteException e) {
7567            return false;
7568        }
7569
7570        return readMet && writeMet;
7571    }
7572
7573    public int getAppStartMode(int uid, String packageName) {
7574        synchronized (this) {
7575            return checkAllowBackgroundLocked(uid, packageName, -1);
7576        }
7577    }
7578
7579    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid) {
7580        UidRecord uidRec = mActiveUids.get(uid);
7581        if (!mLenientBackgroundCheck) {
7582            if (uidRec == null
7583                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7584                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7585                        packageName) != AppOpsManager.MODE_ALLOWED) {
7586                    return ActivityManager.APP_START_MODE_DELAYED;
7587                }
7588            }
7589
7590        } else if (uidRec == null || uidRec.idle) {
7591            if (callingPid >= 0) {
7592                ProcessRecord proc;
7593                synchronized (mPidsSelfLocked) {
7594                    proc = mPidsSelfLocked.get(callingPid);
7595                }
7596                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7597                    // Whoever is instigating this is in the foreground, so we will allow it
7598                    // to go through.
7599                    return ActivityManager.APP_START_MODE_NORMAL;
7600                }
7601            }
7602            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7603                    != AppOpsManager.MODE_ALLOWED) {
7604                return ActivityManager.APP_START_MODE_DELAYED;
7605            }
7606        }
7607        return ActivityManager.APP_START_MODE_NORMAL;
7608    }
7609
7610    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7611        ProviderInfo pi = null;
7612        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7613        if (cpr != null) {
7614            pi = cpr.info;
7615        } else {
7616            try {
7617                pi = AppGlobals.getPackageManager().resolveContentProvider(
7618                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7619            } catch (RemoteException ex) {
7620            }
7621        }
7622        return pi;
7623    }
7624
7625    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7626        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7627        if (targetUris != null) {
7628            return targetUris.get(grantUri);
7629        }
7630        return null;
7631    }
7632
7633    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7634            String targetPkg, int targetUid, GrantUri grantUri) {
7635        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7636        if (targetUris == null) {
7637            targetUris = Maps.newArrayMap();
7638            mGrantedUriPermissions.put(targetUid, targetUris);
7639        }
7640
7641        UriPermission perm = targetUris.get(grantUri);
7642        if (perm == null) {
7643            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7644            targetUris.put(grantUri, perm);
7645        }
7646
7647        return perm;
7648    }
7649
7650    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7651            final int modeFlags) {
7652        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7653        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7654                : UriPermission.STRENGTH_OWNED;
7655
7656        // Root gets to do everything.
7657        if (uid == 0) {
7658            return true;
7659        }
7660
7661        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7662        if (perms == null) return false;
7663
7664        // First look for exact match
7665        final UriPermission exactPerm = perms.get(grantUri);
7666        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7667            return true;
7668        }
7669
7670        // No exact match, look for prefixes
7671        final int N = perms.size();
7672        for (int i = 0; i < N; i++) {
7673            final UriPermission perm = perms.valueAt(i);
7674            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7675                    && perm.getStrength(modeFlags) >= minStrength) {
7676                return true;
7677            }
7678        }
7679
7680        return false;
7681    }
7682
7683    /**
7684     * @param uri This uri must NOT contain an embedded userId.
7685     * @param userId The userId in which the uri is to be resolved.
7686     */
7687    @Override
7688    public int checkUriPermission(Uri uri, int pid, int uid,
7689            final int modeFlags, int userId, IBinder callerToken) {
7690        enforceNotIsolatedCaller("checkUriPermission");
7691
7692        // Another redirected-binder-call permissions check as in
7693        // {@link checkPermissionWithToken}.
7694        Identity tlsIdentity = sCallerIdentity.get();
7695        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7696            uid = tlsIdentity.uid;
7697            pid = tlsIdentity.pid;
7698        }
7699
7700        // Our own process gets to do everything.
7701        if (pid == MY_PID) {
7702            return PackageManager.PERMISSION_GRANTED;
7703        }
7704        synchronized (this) {
7705            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7706                    ? PackageManager.PERMISSION_GRANTED
7707                    : PackageManager.PERMISSION_DENIED;
7708        }
7709    }
7710
7711    /**
7712     * Check if the targetPkg can be granted permission to access uri by
7713     * the callingUid using the given modeFlags.  Throws a security exception
7714     * if callingUid is not allowed to do this.  Returns the uid of the target
7715     * if the URI permission grant should be performed; returns -1 if it is not
7716     * needed (for example targetPkg already has permission to access the URI).
7717     * If you already know the uid of the target, you can supply it in
7718     * lastTargetUid else set that to -1.
7719     */
7720    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7721            final int modeFlags, int lastTargetUid) {
7722        if (!Intent.isAccessUriMode(modeFlags)) {
7723            return -1;
7724        }
7725
7726        if (targetPkg != null) {
7727            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7728                    "Checking grant " + targetPkg + " permission to " + grantUri);
7729        }
7730
7731        final IPackageManager pm = AppGlobals.getPackageManager();
7732
7733        // If this is not a content: uri, we can't do anything with it.
7734        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7735            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7736                    "Can't grant URI permission for non-content URI: " + grantUri);
7737            return -1;
7738        }
7739
7740        final String authority = grantUri.uri.getAuthority();
7741        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7742        if (pi == null) {
7743            Slog.w(TAG, "No content provider found for permission check: " +
7744                    grantUri.uri.toSafeString());
7745            return -1;
7746        }
7747
7748        int targetUid = lastTargetUid;
7749        if (targetUid < 0 && targetPkg != null) {
7750            try {
7751                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7752                        UserHandle.getUserId(callingUid));
7753                if (targetUid < 0) {
7754                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7755                            "Can't grant URI permission no uid for: " + targetPkg);
7756                    return -1;
7757                }
7758            } catch (RemoteException ex) {
7759                return -1;
7760            }
7761        }
7762
7763        if (targetUid >= 0) {
7764            // First...  does the target actually need this permission?
7765            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7766                // No need to grant the target this permission.
7767                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7768                        "Target " + targetPkg + " already has full permission to " + grantUri);
7769                return -1;
7770            }
7771        } else {
7772            // First...  there is no target package, so can anyone access it?
7773            boolean allowed = pi.exported;
7774            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7775                if (pi.readPermission != null) {
7776                    allowed = false;
7777                }
7778            }
7779            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7780                if (pi.writePermission != null) {
7781                    allowed = false;
7782                }
7783            }
7784            if (allowed) {
7785                return -1;
7786            }
7787        }
7788
7789        /* There is a special cross user grant if:
7790         * - The target is on another user.
7791         * - Apps on the current user can access the uri without any uid permissions.
7792         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7793         * grant uri permissions.
7794         */
7795        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7796                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7797                modeFlags, false /*without considering the uid permissions*/);
7798
7799        // Second...  is the provider allowing granting of URI permissions?
7800        if (!specialCrossUserGrant) {
7801            if (!pi.grantUriPermissions) {
7802                throw new SecurityException("Provider " + pi.packageName
7803                        + "/" + pi.name
7804                        + " does not allow granting of Uri permissions (uri "
7805                        + grantUri + ")");
7806            }
7807            if (pi.uriPermissionPatterns != null) {
7808                final int N = pi.uriPermissionPatterns.length;
7809                boolean allowed = false;
7810                for (int i=0; i<N; i++) {
7811                    if (pi.uriPermissionPatterns[i] != null
7812                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7813                        allowed = true;
7814                        break;
7815                    }
7816                }
7817                if (!allowed) {
7818                    throw new SecurityException("Provider " + pi.packageName
7819                            + "/" + pi.name
7820                            + " does not allow granting of permission to path of Uri "
7821                            + grantUri);
7822                }
7823            }
7824        }
7825
7826        // Third...  does the caller itself have permission to access
7827        // this uri?
7828        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7829            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7830                // Require they hold a strong enough Uri permission
7831                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7832                    throw new SecurityException("Uid " + callingUid
7833                            + " does not have permission to uri " + grantUri);
7834                }
7835            }
7836        }
7837        return targetUid;
7838    }
7839
7840    /**
7841     * @param uri This uri must NOT contain an embedded userId.
7842     * @param userId The userId in which the uri is to be resolved.
7843     */
7844    @Override
7845    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7846            final int modeFlags, int userId) {
7847        enforceNotIsolatedCaller("checkGrantUriPermission");
7848        synchronized(this) {
7849            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7850                    new GrantUri(userId, uri, false), modeFlags, -1);
7851        }
7852    }
7853
7854    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7855            final int modeFlags, UriPermissionOwner owner) {
7856        if (!Intent.isAccessUriMode(modeFlags)) {
7857            return;
7858        }
7859
7860        // So here we are: the caller has the assumed permission
7861        // to the uri, and the target doesn't.  Let's now give this to
7862        // the target.
7863
7864        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7865                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7866
7867        final String authority = grantUri.uri.getAuthority();
7868        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7869        if (pi == null) {
7870            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7871            return;
7872        }
7873
7874        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7875            grantUri.prefix = true;
7876        }
7877        final UriPermission perm = findOrCreateUriPermissionLocked(
7878                pi.packageName, targetPkg, targetUid, grantUri);
7879        perm.grantModes(modeFlags, owner);
7880    }
7881
7882    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7883            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7884        if (targetPkg == null) {
7885            throw new NullPointerException("targetPkg");
7886        }
7887        int targetUid;
7888        final IPackageManager pm = AppGlobals.getPackageManager();
7889        try {
7890            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7891        } catch (RemoteException ex) {
7892            return;
7893        }
7894
7895        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7896                targetUid);
7897        if (targetUid < 0) {
7898            return;
7899        }
7900
7901        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7902                owner);
7903    }
7904
7905    static class NeededUriGrants extends ArrayList<GrantUri> {
7906        final String targetPkg;
7907        final int targetUid;
7908        final int flags;
7909
7910        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7911            this.targetPkg = targetPkg;
7912            this.targetUid = targetUid;
7913            this.flags = flags;
7914        }
7915    }
7916
7917    /**
7918     * Like checkGrantUriPermissionLocked, but takes an Intent.
7919     */
7920    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7921            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7922        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7923                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7924                + " clip=" + (intent != null ? intent.getClipData() : null)
7925                + " from " + intent + "; flags=0x"
7926                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7927
7928        if (targetPkg == null) {
7929            throw new NullPointerException("targetPkg");
7930        }
7931
7932        if (intent == null) {
7933            return null;
7934        }
7935        Uri data = intent.getData();
7936        ClipData clip = intent.getClipData();
7937        if (data == null && clip == null) {
7938            return null;
7939        }
7940        // Default userId for uris in the intent (if they don't specify it themselves)
7941        int contentUserHint = intent.getContentUserHint();
7942        if (contentUserHint == UserHandle.USER_CURRENT) {
7943            contentUserHint = UserHandle.getUserId(callingUid);
7944        }
7945        final IPackageManager pm = AppGlobals.getPackageManager();
7946        int targetUid;
7947        if (needed != null) {
7948            targetUid = needed.targetUid;
7949        } else {
7950            try {
7951                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7952                        targetUserId);
7953            } catch (RemoteException ex) {
7954                return null;
7955            }
7956            if (targetUid < 0) {
7957                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7958                        "Can't grant URI permission no uid for: " + targetPkg
7959                        + " on user " + targetUserId);
7960                return null;
7961            }
7962        }
7963        if (data != null) {
7964            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7965            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7966                    targetUid);
7967            if (targetUid > 0) {
7968                if (needed == null) {
7969                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7970                }
7971                needed.add(grantUri);
7972            }
7973        }
7974        if (clip != null) {
7975            for (int i=0; i<clip.getItemCount(); i++) {
7976                Uri uri = clip.getItemAt(i).getUri();
7977                if (uri != null) {
7978                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7979                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7980                            targetUid);
7981                    if (targetUid > 0) {
7982                        if (needed == null) {
7983                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7984                        }
7985                        needed.add(grantUri);
7986                    }
7987                } else {
7988                    Intent clipIntent = clip.getItemAt(i).getIntent();
7989                    if (clipIntent != null) {
7990                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7991                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7992                        if (newNeeded != null) {
7993                            needed = newNeeded;
7994                        }
7995                    }
7996                }
7997            }
7998        }
7999
8000        return needed;
8001    }
8002
8003    /**
8004     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8005     */
8006    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8007            UriPermissionOwner owner) {
8008        if (needed != null) {
8009            for (int i=0; i<needed.size(); i++) {
8010                GrantUri grantUri = needed.get(i);
8011                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8012                        grantUri, needed.flags, owner);
8013            }
8014        }
8015    }
8016
8017    void grantUriPermissionFromIntentLocked(int callingUid,
8018            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8019        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8020                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8021        if (needed == null) {
8022            return;
8023        }
8024
8025        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8026    }
8027
8028    /**
8029     * @param uri This uri must NOT contain an embedded userId.
8030     * @param userId The userId in which the uri is to be resolved.
8031     */
8032    @Override
8033    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8034            final int modeFlags, int userId) {
8035        enforceNotIsolatedCaller("grantUriPermission");
8036        GrantUri grantUri = new GrantUri(userId, uri, false);
8037        synchronized(this) {
8038            final ProcessRecord r = getRecordForAppLocked(caller);
8039            if (r == null) {
8040                throw new SecurityException("Unable to find app for caller "
8041                        + caller
8042                        + " when granting permission to uri " + grantUri);
8043            }
8044            if (targetPkg == null) {
8045                throw new IllegalArgumentException("null target");
8046            }
8047            if (grantUri == null) {
8048                throw new IllegalArgumentException("null uri");
8049            }
8050
8051            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8052                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8053                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8054                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8055
8056            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8057                    UserHandle.getUserId(r.uid));
8058        }
8059    }
8060
8061    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8062        if (perm.modeFlags == 0) {
8063            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8064                    perm.targetUid);
8065            if (perms != null) {
8066                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8067                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8068
8069                perms.remove(perm.uri);
8070                if (perms.isEmpty()) {
8071                    mGrantedUriPermissions.remove(perm.targetUid);
8072                }
8073            }
8074        }
8075    }
8076
8077    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8078        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8079                "Revoking all granted permissions to " + grantUri);
8080
8081        final IPackageManager pm = AppGlobals.getPackageManager();
8082        final String authority = grantUri.uri.getAuthority();
8083        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8084        if (pi == null) {
8085            Slog.w(TAG, "No content provider found for permission revoke: "
8086                    + grantUri.toSafeString());
8087            return;
8088        }
8089
8090        // Does the caller have this permission on the URI?
8091        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8092            // If they don't have direct access to the URI, then revoke any
8093            // ownerless URI permissions that have been granted to them.
8094            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8095            if (perms != null) {
8096                boolean persistChanged = false;
8097                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8098                    final UriPermission perm = it.next();
8099                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8100                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8101                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8102                                "Revoking non-owned " + perm.targetUid
8103                                + " permission to " + perm.uri);
8104                        persistChanged |= perm.revokeModes(
8105                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8106                        if (perm.modeFlags == 0) {
8107                            it.remove();
8108                        }
8109                    }
8110                }
8111                if (perms.isEmpty()) {
8112                    mGrantedUriPermissions.remove(callingUid);
8113                }
8114                if (persistChanged) {
8115                    schedulePersistUriGrants();
8116                }
8117            }
8118            return;
8119        }
8120
8121        boolean persistChanged = false;
8122
8123        // Go through all of the permissions and remove any that match.
8124        int N = mGrantedUriPermissions.size();
8125        for (int i = 0; i < N; i++) {
8126            final int targetUid = mGrantedUriPermissions.keyAt(i);
8127            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8128
8129            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8130                final UriPermission perm = it.next();
8131                if (perm.uri.sourceUserId == grantUri.sourceUserId
8132                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8133                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8134                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8135                    persistChanged |= perm.revokeModes(
8136                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8137                    if (perm.modeFlags == 0) {
8138                        it.remove();
8139                    }
8140                }
8141            }
8142
8143            if (perms.isEmpty()) {
8144                mGrantedUriPermissions.remove(targetUid);
8145                N--;
8146                i--;
8147            }
8148        }
8149
8150        if (persistChanged) {
8151            schedulePersistUriGrants();
8152        }
8153    }
8154
8155    /**
8156     * @param uri This uri must NOT contain an embedded userId.
8157     * @param userId The userId in which the uri is to be resolved.
8158     */
8159    @Override
8160    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8161            int userId) {
8162        enforceNotIsolatedCaller("revokeUriPermission");
8163        synchronized(this) {
8164            final ProcessRecord r = getRecordForAppLocked(caller);
8165            if (r == null) {
8166                throw new SecurityException("Unable to find app for caller "
8167                        + caller
8168                        + " when revoking permission to uri " + uri);
8169            }
8170            if (uri == null) {
8171                Slog.w(TAG, "revokeUriPermission: null uri");
8172                return;
8173            }
8174
8175            if (!Intent.isAccessUriMode(modeFlags)) {
8176                return;
8177            }
8178
8179            final String authority = uri.getAuthority();
8180            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8181            if (pi == null) {
8182                Slog.w(TAG, "No content provider found for permission revoke: "
8183                        + uri.toSafeString());
8184                return;
8185            }
8186
8187            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8188        }
8189    }
8190
8191    /**
8192     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8193     * given package.
8194     *
8195     * @param packageName Package name to match, or {@code null} to apply to all
8196     *            packages.
8197     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8198     *            to all users.
8199     * @param persistable If persistable grants should be removed.
8200     */
8201    private void removeUriPermissionsForPackageLocked(
8202            String packageName, int userHandle, boolean persistable) {
8203        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8204            throw new IllegalArgumentException("Must narrow by either package or user");
8205        }
8206
8207        boolean persistChanged = false;
8208
8209        int N = mGrantedUriPermissions.size();
8210        for (int i = 0; i < N; i++) {
8211            final int targetUid = mGrantedUriPermissions.keyAt(i);
8212            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8213
8214            // Only inspect grants matching user
8215            if (userHandle == UserHandle.USER_ALL
8216                    || userHandle == UserHandle.getUserId(targetUid)) {
8217                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8218                    final UriPermission perm = it.next();
8219
8220                    // Only inspect grants matching package
8221                    if (packageName == null || perm.sourcePkg.equals(packageName)
8222                            || perm.targetPkg.equals(packageName)) {
8223                        persistChanged |= perm.revokeModes(persistable
8224                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8225
8226                        // Only remove when no modes remain; any persisted grants
8227                        // will keep this alive.
8228                        if (perm.modeFlags == 0) {
8229                            it.remove();
8230                        }
8231                    }
8232                }
8233
8234                if (perms.isEmpty()) {
8235                    mGrantedUriPermissions.remove(targetUid);
8236                    N--;
8237                    i--;
8238                }
8239            }
8240        }
8241
8242        if (persistChanged) {
8243            schedulePersistUriGrants();
8244        }
8245    }
8246
8247    @Override
8248    public IBinder newUriPermissionOwner(String name) {
8249        enforceNotIsolatedCaller("newUriPermissionOwner");
8250        synchronized(this) {
8251            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8252            return owner.getExternalTokenLocked();
8253        }
8254    }
8255
8256    @Override
8257    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8258        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8259        synchronized(this) {
8260            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8261            if (r == null) {
8262                throw new IllegalArgumentException("Activity does not exist; token="
8263                        + activityToken);
8264            }
8265            return r.getUriPermissionsLocked().getExternalTokenLocked();
8266        }
8267    }
8268    /**
8269     * @param uri This uri must NOT contain an embedded userId.
8270     * @param sourceUserId The userId in which the uri is to be resolved.
8271     * @param targetUserId The userId of the app that receives the grant.
8272     */
8273    @Override
8274    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8275            final int modeFlags, int sourceUserId, int targetUserId) {
8276        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8277                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8278                "grantUriPermissionFromOwner", null);
8279        synchronized(this) {
8280            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8281            if (owner == null) {
8282                throw new IllegalArgumentException("Unknown owner: " + token);
8283            }
8284            if (fromUid != Binder.getCallingUid()) {
8285                if (Binder.getCallingUid() != Process.myUid()) {
8286                    // Only system code can grant URI permissions on behalf
8287                    // of other users.
8288                    throw new SecurityException("nice try");
8289                }
8290            }
8291            if (targetPkg == null) {
8292                throw new IllegalArgumentException("null target");
8293            }
8294            if (uri == null) {
8295                throw new IllegalArgumentException("null uri");
8296            }
8297
8298            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8299                    modeFlags, owner, targetUserId);
8300        }
8301    }
8302
8303    /**
8304     * @param uri This uri must NOT contain an embedded userId.
8305     * @param userId The userId in which the uri is to be resolved.
8306     */
8307    @Override
8308    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8309        synchronized(this) {
8310            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8311            if (owner == null) {
8312                throw new IllegalArgumentException("Unknown owner: " + token);
8313            }
8314
8315            if (uri == null) {
8316                owner.removeUriPermissionsLocked(mode);
8317            } else {
8318                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8319            }
8320        }
8321    }
8322
8323    private void schedulePersistUriGrants() {
8324        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8325            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8326                    10 * DateUtils.SECOND_IN_MILLIS);
8327        }
8328    }
8329
8330    private void writeGrantedUriPermissions() {
8331        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8332
8333        // Snapshot permissions so we can persist without lock
8334        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8335        synchronized (this) {
8336            final int size = mGrantedUriPermissions.size();
8337            for (int i = 0; i < size; i++) {
8338                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8339                for (UriPermission perm : perms.values()) {
8340                    if (perm.persistedModeFlags != 0) {
8341                        persist.add(perm.snapshot());
8342                    }
8343                }
8344            }
8345        }
8346
8347        FileOutputStream fos = null;
8348        try {
8349            fos = mGrantFile.startWrite();
8350
8351            XmlSerializer out = new FastXmlSerializer();
8352            out.setOutput(fos, StandardCharsets.UTF_8.name());
8353            out.startDocument(null, true);
8354            out.startTag(null, TAG_URI_GRANTS);
8355            for (UriPermission.Snapshot perm : persist) {
8356                out.startTag(null, TAG_URI_GRANT);
8357                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8358                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8359                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8360                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8361                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8362                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8363                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8364                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8365                out.endTag(null, TAG_URI_GRANT);
8366            }
8367            out.endTag(null, TAG_URI_GRANTS);
8368            out.endDocument();
8369
8370            mGrantFile.finishWrite(fos);
8371        } catch (IOException e) {
8372            if (fos != null) {
8373                mGrantFile.failWrite(fos);
8374            }
8375        }
8376    }
8377
8378    private void readGrantedUriPermissionsLocked() {
8379        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8380
8381        final long now = System.currentTimeMillis();
8382
8383        FileInputStream fis = null;
8384        try {
8385            fis = mGrantFile.openRead();
8386            final XmlPullParser in = Xml.newPullParser();
8387            in.setInput(fis, StandardCharsets.UTF_8.name());
8388
8389            int type;
8390            while ((type = in.next()) != END_DOCUMENT) {
8391                final String tag = in.getName();
8392                if (type == START_TAG) {
8393                    if (TAG_URI_GRANT.equals(tag)) {
8394                        final int sourceUserId;
8395                        final int targetUserId;
8396                        final int userHandle = readIntAttribute(in,
8397                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8398                        if (userHandle != UserHandle.USER_NULL) {
8399                            // For backwards compatibility.
8400                            sourceUserId = userHandle;
8401                            targetUserId = userHandle;
8402                        } else {
8403                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8404                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8405                        }
8406                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8407                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8408                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8409                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8410                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8411                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8412
8413                        // Sanity check that provider still belongs to source package
8414                        final ProviderInfo pi = getProviderInfoLocked(
8415                                uri.getAuthority(), sourceUserId);
8416                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8417                            int targetUid = -1;
8418                            try {
8419                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8420                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8421                            } catch (RemoteException e) {
8422                            }
8423                            if (targetUid != -1) {
8424                                final UriPermission perm = findOrCreateUriPermissionLocked(
8425                                        sourcePkg, targetPkg, targetUid,
8426                                        new GrantUri(sourceUserId, uri, prefix));
8427                                perm.initPersistedModes(modeFlags, createdTime);
8428                            }
8429                        } else {
8430                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8431                                    + " but instead found " + pi);
8432                        }
8433                    }
8434                }
8435            }
8436        } catch (FileNotFoundException e) {
8437            // Missing grants is okay
8438        } catch (IOException e) {
8439            Slog.wtf(TAG, "Failed reading Uri grants", e);
8440        } catch (XmlPullParserException e) {
8441            Slog.wtf(TAG, "Failed reading Uri grants", e);
8442        } finally {
8443            IoUtils.closeQuietly(fis);
8444        }
8445    }
8446
8447    /**
8448     * @param uri This uri must NOT contain an embedded userId.
8449     * @param userId The userId in which the uri is to be resolved.
8450     */
8451    @Override
8452    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8453        enforceNotIsolatedCaller("takePersistableUriPermission");
8454
8455        Preconditions.checkFlagsArgument(modeFlags,
8456                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8457
8458        synchronized (this) {
8459            final int callingUid = Binder.getCallingUid();
8460            boolean persistChanged = false;
8461            GrantUri grantUri = new GrantUri(userId, uri, false);
8462
8463            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8464                    new GrantUri(userId, uri, false));
8465            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8466                    new GrantUri(userId, uri, true));
8467
8468            final boolean exactValid = (exactPerm != null)
8469                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8470            final boolean prefixValid = (prefixPerm != null)
8471                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8472
8473            if (!(exactValid || prefixValid)) {
8474                throw new SecurityException("No persistable permission grants found for UID "
8475                        + callingUid + " and Uri " + grantUri.toSafeString());
8476            }
8477
8478            if (exactValid) {
8479                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8480            }
8481            if (prefixValid) {
8482                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8483            }
8484
8485            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8486
8487            if (persistChanged) {
8488                schedulePersistUriGrants();
8489            }
8490        }
8491    }
8492
8493    /**
8494     * @param uri This uri must NOT contain an embedded userId.
8495     * @param userId The userId in which the uri is to be resolved.
8496     */
8497    @Override
8498    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8499        enforceNotIsolatedCaller("releasePersistableUriPermission");
8500
8501        Preconditions.checkFlagsArgument(modeFlags,
8502                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8503
8504        synchronized (this) {
8505            final int callingUid = Binder.getCallingUid();
8506            boolean persistChanged = false;
8507
8508            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8509                    new GrantUri(userId, uri, false));
8510            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8511                    new GrantUri(userId, uri, true));
8512            if (exactPerm == null && prefixPerm == null) {
8513                throw new SecurityException("No permission grants found for UID " + callingUid
8514                        + " and Uri " + uri.toSafeString());
8515            }
8516
8517            if (exactPerm != null) {
8518                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8519                removeUriPermissionIfNeededLocked(exactPerm);
8520            }
8521            if (prefixPerm != null) {
8522                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8523                removeUriPermissionIfNeededLocked(prefixPerm);
8524            }
8525
8526            if (persistChanged) {
8527                schedulePersistUriGrants();
8528            }
8529        }
8530    }
8531
8532    /**
8533     * Prune any older {@link UriPermission} for the given UID until outstanding
8534     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8535     *
8536     * @return if any mutations occured that require persisting.
8537     */
8538    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8539        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8540        if (perms == null) return false;
8541        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8542
8543        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8544        for (UriPermission perm : perms.values()) {
8545            if (perm.persistedModeFlags != 0) {
8546                persisted.add(perm);
8547            }
8548        }
8549
8550        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8551        if (trimCount <= 0) return false;
8552
8553        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8554        for (int i = 0; i < trimCount; i++) {
8555            final UriPermission perm = persisted.get(i);
8556
8557            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8558                    "Trimming grant created at " + perm.persistedCreateTime);
8559
8560            perm.releasePersistableModes(~0);
8561            removeUriPermissionIfNeededLocked(perm);
8562        }
8563
8564        return true;
8565    }
8566
8567    @Override
8568    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8569            String packageName, boolean incoming) {
8570        enforceNotIsolatedCaller("getPersistedUriPermissions");
8571        Preconditions.checkNotNull(packageName, "packageName");
8572
8573        final int callingUid = Binder.getCallingUid();
8574        final IPackageManager pm = AppGlobals.getPackageManager();
8575        try {
8576            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8577                    UserHandle.getUserId(callingUid));
8578            if (packageUid != callingUid) {
8579                throw new SecurityException(
8580                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8581            }
8582        } catch (RemoteException e) {
8583            throw new SecurityException("Failed to verify package name ownership");
8584        }
8585
8586        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8587        synchronized (this) {
8588            if (incoming) {
8589                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8590                        callingUid);
8591                if (perms == null) {
8592                    Slog.w(TAG, "No permission grants found for " + packageName);
8593                } else {
8594                    for (UriPermission perm : perms.values()) {
8595                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8596                            result.add(perm.buildPersistedPublicApiObject());
8597                        }
8598                    }
8599                }
8600            } else {
8601                final int size = mGrantedUriPermissions.size();
8602                for (int i = 0; i < size; i++) {
8603                    final ArrayMap<GrantUri, UriPermission> perms =
8604                            mGrantedUriPermissions.valueAt(i);
8605                    for (UriPermission perm : perms.values()) {
8606                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8607                            result.add(perm.buildPersistedPublicApiObject());
8608                        }
8609                    }
8610                }
8611            }
8612        }
8613        return new ParceledListSlice<android.content.UriPermission>(result);
8614    }
8615
8616    @Override
8617    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8618            String packageName, int userId) {
8619        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8620                "getGrantedUriPermissions");
8621
8622        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8623        synchronized (this) {
8624            final int size = mGrantedUriPermissions.size();
8625            for (int i = 0; i < size; i++) {
8626                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8627                for (UriPermission perm : perms.values()) {
8628                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8629                            && perm.persistedModeFlags != 0) {
8630                        result.add(perm.buildPersistedPublicApiObject());
8631                    }
8632                }
8633            }
8634        }
8635        return new ParceledListSlice<android.content.UriPermission>(result);
8636    }
8637
8638    @Override
8639    public void clearGrantedUriPermissions(String packageName, int userId) {
8640        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8641                "clearGrantedUriPermissions");
8642        removeUriPermissionsForPackageLocked(packageName, userId, true);
8643    }
8644
8645    @Override
8646    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8647        synchronized (this) {
8648            ProcessRecord app =
8649                who != null ? getRecordForAppLocked(who) : null;
8650            if (app == null) return;
8651
8652            Message msg = Message.obtain();
8653            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8654            msg.obj = app;
8655            msg.arg1 = waiting ? 1 : 0;
8656            mUiHandler.sendMessage(msg);
8657        }
8658    }
8659
8660    @Override
8661    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8662        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8663        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8664        outInfo.availMem = Process.getFreeMemory();
8665        outInfo.totalMem = Process.getTotalMemory();
8666        outInfo.threshold = homeAppMem;
8667        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8668        outInfo.hiddenAppThreshold = cachedAppMem;
8669        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8670                ProcessList.SERVICE_ADJ);
8671        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8672                ProcessList.VISIBLE_APP_ADJ);
8673        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8674                ProcessList.FOREGROUND_APP_ADJ);
8675    }
8676
8677    // =========================================================
8678    // TASK MANAGEMENT
8679    // =========================================================
8680
8681    @Override
8682    public List<IAppTask> getAppTasks(String callingPackage) {
8683        int callingUid = Binder.getCallingUid();
8684        long ident = Binder.clearCallingIdentity();
8685
8686        synchronized(this) {
8687            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8688            try {
8689                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8690
8691                final int N = mRecentTasks.size();
8692                for (int i = 0; i < N; i++) {
8693                    TaskRecord tr = mRecentTasks.get(i);
8694                    // Skip tasks that do not match the caller.  We don't need to verify
8695                    // callingPackage, because we are also limiting to callingUid and know
8696                    // that will limit to the correct security sandbox.
8697                    if (tr.effectiveUid != callingUid) {
8698                        continue;
8699                    }
8700                    Intent intent = tr.getBaseIntent();
8701                    if (intent == null ||
8702                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8703                        continue;
8704                    }
8705                    ActivityManager.RecentTaskInfo taskInfo =
8706                            createRecentTaskInfoFromTaskRecord(tr);
8707                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8708                    list.add(taskImpl);
8709                }
8710            } finally {
8711                Binder.restoreCallingIdentity(ident);
8712            }
8713            return list;
8714        }
8715    }
8716
8717    @Override
8718    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8719        final int callingUid = Binder.getCallingUid();
8720        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8721
8722        synchronized(this) {
8723            if (DEBUG_ALL) Slog.v(
8724                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8725
8726            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8727                    callingUid);
8728
8729            // TODO: Improve with MRU list from all ActivityStacks.
8730            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8731        }
8732
8733        return list;
8734    }
8735
8736    /**
8737     * Creates a new RecentTaskInfo from a TaskRecord.
8738     */
8739    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8740        // Update the task description to reflect any changes in the task stack
8741        tr.updateTaskDescription();
8742
8743        // Compose the recent task info
8744        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8745        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8746        rti.persistentId = tr.taskId;
8747        rti.baseIntent = new Intent(tr.getBaseIntent());
8748        rti.origActivity = tr.origActivity;
8749        rti.realActivity = tr.realActivity;
8750        rti.description = tr.lastDescription;
8751        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8752        rti.userId = tr.userId;
8753        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8754        rti.firstActiveTime = tr.firstActiveTime;
8755        rti.lastActiveTime = tr.lastActiveTime;
8756        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8757        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8758        rti.numActivities = 0;
8759        if (tr.mBounds != null) {
8760            rti.bounds = new Rect(tr.mBounds);
8761        }
8762        rti.isDockable = tr.canGoInDockedStack();
8763
8764        ActivityRecord base = null;
8765        ActivityRecord top = null;
8766        ActivityRecord tmp;
8767
8768        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8769            tmp = tr.mActivities.get(i);
8770            if (tmp.finishing) {
8771                continue;
8772            }
8773            base = tmp;
8774            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8775                top = base;
8776            }
8777            rti.numActivities++;
8778        }
8779
8780        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8781        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8782
8783        return rti;
8784    }
8785
8786    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8787        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8788                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8789        if (!allowed) {
8790            if (checkPermission(android.Manifest.permission.GET_TASKS,
8791                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8792                // Temporary compatibility: some existing apps on the system image may
8793                // still be requesting the old permission and not switched to the new
8794                // one; if so, we'll still allow them full access.  This means we need
8795                // to see if they are holding the old permission and are a system app.
8796                try {
8797                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8798                        allowed = true;
8799                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8800                                + " is using old GET_TASKS but privileged; allowing");
8801                    }
8802                } catch (RemoteException e) {
8803                }
8804            }
8805        }
8806        if (!allowed) {
8807            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8808                    + " does not hold REAL_GET_TASKS; limiting output");
8809        }
8810        return allowed;
8811    }
8812
8813    @Override
8814    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8815        final int callingUid = Binder.getCallingUid();
8816        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8817                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8818
8819        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8820        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8821        synchronized (this) {
8822            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8823                    callingUid);
8824            final boolean detailed = checkCallingPermission(
8825                    android.Manifest.permission.GET_DETAILED_TASKS)
8826                    == PackageManager.PERMISSION_GRANTED;
8827
8828            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8829                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8830                return Collections.emptyList();
8831            }
8832            mRecentTasks.loadUserRecentsLocked(userId);
8833
8834            final int recentsCount = mRecentTasks.size();
8835            ArrayList<ActivityManager.RecentTaskInfo> res =
8836                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8837
8838            final Set<Integer> includedUsers;
8839            if (includeProfiles) {
8840                includedUsers = mUserController.getProfileIds(userId);
8841            } else {
8842                includedUsers = new HashSet<>();
8843            }
8844            includedUsers.add(Integer.valueOf(userId));
8845
8846            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8847                TaskRecord tr = mRecentTasks.get(i);
8848                // Only add calling user or related users recent tasks
8849                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8850                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8851                    continue;
8852                }
8853
8854                if (tr.realActivitySuspended) {
8855                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8856                    continue;
8857                }
8858
8859                // Return the entry if desired by the caller.  We always return
8860                // the first entry, because callers always expect this to be the
8861                // foreground app.  We may filter others if the caller has
8862                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8863                // we should exclude the entry.
8864
8865                if (i == 0
8866                        || withExcluded
8867                        || (tr.intent == null)
8868                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8869                                == 0)) {
8870                    if (!allowed) {
8871                        // If the caller doesn't have the GET_TASKS permission, then only
8872                        // allow them to see a small subset of tasks -- their own and home.
8873                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8874                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8875                            continue;
8876                        }
8877                    }
8878                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8879                        if (tr.stack != null && tr.stack.isHomeStack()) {
8880                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8881                                    "Skipping, home stack task: " + tr);
8882                            continue;
8883                        }
8884                    }
8885                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TASKS) != 0) {
8886                        if (tr.stack != null && tr.stack.isDockedStack()) {
8887                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8888                                    "Skipping, docked stack task: " + tr);
8889                            continue;
8890                        }
8891                    }
8892                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8893                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8894                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8895                                    "Skipping, pinned stack task: " + tr);
8896                            continue;
8897                        }
8898                    }
8899                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8900                        // Don't include auto remove tasks that are finished or finishing.
8901                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8902                                "Skipping, auto-remove without activity: " + tr);
8903                        continue;
8904                    }
8905                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8906                            && !tr.isAvailable) {
8907                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8908                                "Skipping, unavail real act: " + tr);
8909                        continue;
8910                    }
8911
8912                    if (!tr.mUserSetupComplete) {
8913                        // Don't include task launched while user is not done setting-up.
8914                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8915                                "Skipping, user setup not complete: " + tr);
8916                        continue;
8917                    }
8918
8919                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8920                    if (!detailed) {
8921                        rti.baseIntent.replaceExtras((Bundle)null);
8922                    }
8923
8924                    res.add(rti);
8925                    maxNum--;
8926                }
8927            }
8928            return res;
8929        }
8930    }
8931
8932    @Override
8933    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8934        synchronized (this) {
8935            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8936                    "getTaskThumbnail()");
8937            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8938                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8939            if (tr != null) {
8940                return tr.getTaskThumbnailLocked();
8941            }
8942        }
8943        return null;
8944    }
8945
8946    @Override
8947    public int addAppTask(IBinder activityToken, Intent intent,
8948            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8949        final int callingUid = Binder.getCallingUid();
8950        final long callingIdent = Binder.clearCallingIdentity();
8951
8952        try {
8953            synchronized (this) {
8954                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8955                if (r == null) {
8956                    throw new IllegalArgumentException("Activity does not exist; token="
8957                            + activityToken);
8958                }
8959                ComponentName comp = intent.getComponent();
8960                if (comp == null) {
8961                    throw new IllegalArgumentException("Intent " + intent
8962                            + " must specify explicit component");
8963                }
8964                if (thumbnail.getWidth() != mThumbnailWidth
8965                        || thumbnail.getHeight() != mThumbnailHeight) {
8966                    throw new IllegalArgumentException("Bad thumbnail size: got "
8967                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8968                            + mThumbnailWidth + "x" + mThumbnailHeight);
8969                }
8970                if (intent.getSelector() != null) {
8971                    intent.setSelector(null);
8972                }
8973                if (intent.getSourceBounds() != null) {
8974                    intent.setSourceBounds(null);
8975                }
8976                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8977                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8978                        // The caller has added this as an auto-remove task...  that makes no
8979                        // sense, so turn off auto-remove.
8980                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8981                    }
8982                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8983                    // Must be a new task.
8984                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8985                }
8986                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8987                    mLastAddedTaskActivity = null;
8988                }
8989                ActivityInfo ainfo = mLastAddedTaskActivity;
8990                if (ainfo == null) {
8991                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8992                            comp, 0, UserHandle.getUserId(callingUid));
8993                    if (ainfo.applicationInfo.uid != callingUid) {
8994                        throw new SecurityException(
8995                                "Can't add task for another application: target uid="
8996                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8997                    }
8998                }
8999
9000                // Use the full screen as the context for the task thumbnail
9001                final Point displaySize = new Point();
9002                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9003                r.task.stack.getDisplaySize(displaySize);
9004                thumbnailInfo.taskWidth = displaySize.x;
9005                thumbnailInfo.taskHeight = displaySize.y;
9006                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9007
9008                TaskRecord task = new TaskRecord(this,
9009                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9010                        ainfo, intent, description, thumbnailInfo);
9011
9012                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9013                if (trimIdx >= 0) {
9014                    // If this would have caused a trim, then we'll abort because that
9015                    // means it would be added at the end of the list but then just removed.
9016                    return INVALID_TASK_ID;
9017                }
9018
9019                final int N = mRecentTasks.size();
9020                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9021                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9022                    tr.removedFromRecents();
9023                }
9024
9025                task.inRecents = true;
9026                mRecentTasks.add(task);
9027                r.task.stack.addTask(task, false, "addAppTask");
9028
9029                task.setLastThumbnailLocked(thumbnail);
9030                task.freeLastThumbnail();
9031
9032                return task.taskId;
9033            }
9034        } finally {
9035            Binder.restoreCallingIdentity(callingIdent);
9036        }
9037    }
9038
9039    @Override
9040    public Point getAppTaskThumbnailSize() {
9041        synchronized (this) {
9042            return new Point(mThumbnailWidth,  mThumbnailHeight);
9043        }
9044    }
9045
9046    @Override
9047    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9048        synchronized (this) {
9049            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9050            if (r != null) {
9051                r.setTaskDescription(td);
9052                r.task.updateTaskDescription();
9053            }
9054        }
9055    }
9056
9057    @Override
9058    public void setTaskResizeable(int taskId, int resizeableMode) {
9059        synchronized (this) {
9060            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9061                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9062            if (task == null) {
9063                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9064                return;
9065            }
9066            if (task.mResizeMode != resizeableMode) {
9067                task.mResizeMode = resizeableMode;
9068                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9069                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9070                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9071            }
9072        }
9073    }
9074
9075    @Override
9076    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9077        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9078        long ident = Binder.clearCallingIdentity();
9079        try {
9080            synchronized (this) {
9081                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9082                if (task == null) {
9083                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9084                    return;
9085                }
9086                int stackId = task.stack.mStackId;
9087                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9088                // in crop windows resize mode or if the task size is affected by the docked stack
9089                // changing size. No need to update configuration.
9090                if (bounds != null && task.inCropWindowsResizeMode()
9091                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9092                    mWindowManager.scrollTask(task.taskId, bounds);
9093                    return;
9094                }
9095
9096                // Place the task in the right stack if it isn't there already based on
9097                // the requested bounds.
9098                // The stack transition logic is:
9099                // - a null bounds on a freeform task moves that task to fullscreen
9100                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9101                //   that task to freeform
9102                // - otherwise the task is not moved
9103                if (!StackId.isTaskResizeAllowed(stackId)) {
9104                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9105                }
9106                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9107                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9108                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9109                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9110                }
9111                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9112                if (stackId != task.stack.mStackId) {
9113                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9114                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9115                    preserveWindow = false;
9116                }
9117
9118                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9119                        false /* deferResume */);
9120            }
9121        } finally {
9122            Binder.restoreCallingIdentity(ident);
9123        }
9124    }
9125
9126    @Override
9127    public Rect getTaskBounds(int taskId) {
9128        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9129        long ident = Binder.clearCallingIdentity();
9130        Rect rect = new Rect();
9131        try {
9132            synchronized (this) {
9133                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9134                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9135                if (task == null) {
9136                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9137                    return rect;
9138                }
9139                if (task.stack != null) {
9140                    // Return the bounds from window manager since it will be adjusted for various
9141                    // things like the presense of a docked stack for tasks that aren't resizeable.
9142                    mWindowManager.getTaskBounds(task.taskId, rect);
9143                } else {
9144                    // Task isn't in window manager yet since it isn't associated with a stack.
9145                    // Return the persist value from activity manager
9146                    if (task.mBounds != null) {
9147                        rect.set(task.mBounds);
9148                    } else if (task.mLastNonFullscreenBounds != null) {
9149                        rect.set(task.mLastNonFullscreenBounds);
9150                    }
9151                }
9152            }
9153        } finally {
9154            Binder.restoreCallingIdentity(ident);
9155        }
9156        return rect;
9157    }
9158
9159    @Override
9160    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9161        if (userId != UserHandle.getCallingUserId()) {
9162            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9163                    "getTaskDescriptionIcon");
9164        }
9165        final File passedIconFile = new File(filePath);
9166        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9167                passedIconFile.getName());
9168        if (!legitIconFile.getPath().equals(filePath)
9169                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9170            throw new IllegalArgumentException("Bad file path: " + filePath
9171                    + " passed for userId " + userId);
9172        }
9173        return mRecentTasks.getTaskDescriptionIcon(filePath);
9174    }
9175
9176    @Override
9177    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9178            throws RemoteException {
9179        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9180                opts.getCustomInPlaceResId() == 0) {
9181            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9182                    "with valid animation");
9183        }
9184        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9185        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9186                opts.getCustomInPlaceResId());
9187        mWindowManager.executeAppTransition();
9188    }
9189
9190    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9191            boolean removeFromRecents) {
9192        if (removeFromRecents) {
9193            mRecentTasks.remove(tr);
9194            tr.removedFromRecents();
9195        }
9196        ComponentName component = tr.getBaseIntent().getComponent();
9197        if (component == null) {
9198            Slog.w(TAG, "No component for base intent of task: " + tr);
9199            return;
9200        }
9201
9202        // Find any running services associated with this app and stop if needed.
9203        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9204
9205        if (!killProcess) {
9206            return;
9207        }
9208
9209        // Determine if the process(es) for this task should be killed.
9210        final String pkg = component.getPackageName();
9211        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9212        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9213        for (int i = 0; i < pmap.size(); i++) {
9214
9215            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9216            for (int j = 0; j < uids.size(); j++) {
9217                ProcessRecord proc = uids.valueAt(j);
9218                if (proc.userId != tr.userId) {
9219                    // Don't kill process for a different user.
9220                    continue;
9221                }
9222                if (proc == mHomeProcess) {
9223                    // Don't kill the home process along with tasks from the same package.
9224                    continue;
9225                }
9226                if (!proc.pkgList.containsKey(pkg)) {
9227                    // Don't kill process that is not associated with this task.
9228                    continue;
9229                }
9230
9231                for (int k = 0; k < proc.activities.size(); k++) {
9232                    TaskRecord otherTask = proc.activities.get(k).task;
9233                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9234                        // Don't kill process(es) that has an activity in a different task that is
9235                        // also in recents.
9236                        return;
9237                    }
9238                }
9239
9240                if (proc.foregroundServices) {
9241                    // Don't kill process(es) with foreground service.
9242                    return;
9243                }
9244
9245                // Add process to kill list.
9246                procsToKill.add(proc);
9247            }
9248        }
9249
9250        // Kill the running processes.
9251        for (int i = 0; i < procsToKill.size(); i++) {
9252            ProcessRecord pr = procsToKill.get(i);
9253            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9254                    && pr.curReceiver == null) {
9255                pr.kill("remove task", true);
9256            } else {
9257                // We delay killing processes that are not in the background or running a receiver.
9258                pr.waitingToKill = "remove task";
9259            }
9260        }
9261    }
9262
9263    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9264        // Remove all tasks with activities in the specified package from the list of recent tasks
9265        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9266            TaskRecord tr = mRecentTasks.get(i);
9267            if (tr.userId != userId) continue;
9268
9269            ComponentName cn = tr.intent.getComponent();
9270            if (cn != null && cn.getPackageName().equals(packageName)) {
9271                // If the package name matches, remove the task.
9272                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9273            }
9274        }
9275    }
9276
9277    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9278            int userId) {
9279
9280        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9281            TaskRecord tr = mRecentTasks.get(i);
9282            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9283                continue;
9284            }
9285
9286            ComponentName cn = tr.intent.getComponent();
9287            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9288                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9289            if (sameComponent) {
9290                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9291            }
9292        }
9293    }
9294
9295    /**
9296     * Removes the task with the specified task id.
9297     *
9298     * @param taskId Identifier of the task to be removed.
9299     * @param killProcess Kill any process associated with the task if possible.
9300     * @param removeFromRecents Whether to also remove the task from recents.
9301     * @return Returns true if the given task was found and removed.
9302     */
9303    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9304            boolean removeFromRecents) {
9305        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9306                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9307        if (tr != null) {
9308            tr.removeTaskActivitiesLocked();
9309            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9310            if (tr.isPersistable) {
9311                notifyTaskPersisterLocked(null, true);
9312            }
9313            return true;
9314        }
9315        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9316        return false;
9317    }
9318
9319    @Override
9320    public void removeStack(int stackId) {
9321        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9322        if (stackId == HOME_STACK_ID) {
9323            throw new IllegalArgumentException("Removing home stack is not allowed.");
9324        }
9325
9326        synchronized (this) {
9327            final long ident = Binder.clearCallingIdentity();
9328            try {
9329                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9330                if (stack == null) {
9331                    return;
9332                }
9333                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9334                for (int i = tasks.size() - 1; i >= 0; i--) {
9335                    removeTaskByIdLocked(
9336                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9337                }
9338            } finally {
9339                Binder.restoreCallingIdentity(ident);
9340            }
9341        }
9342    }
9343
9344    @Override
9345    public boolean removeTask(int taskId) {
9346        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9347        synchronized (this) {
9348            final long ident = Binder.clearCallingIdentity();
9349            try {
9350                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9351            } finally {
9352                Binder.restoreCallingIdentity(ident);
9353            }
9354        }
9355    }
9356
9357    /**
9358     * TODO: Add mController hook
9359     */
9360    @Override
9361    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9362        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9363
9364        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9365        synchronized(this) {
9366            moveTaskToFrontLocked(taskId, flags, bOptions);
9367        }
9368    }
9369
9370    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9371        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9372
9373        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9374                Binder.getCallingUid(), -1, -1, "Task to front")) {
9375            ActivityOptions.abort(options);
9376            return;
9377        }
9378        final long origId = Binder.clearCallingIdentity();
9379        try {
9380            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9381            if (task == null) {
9382                Slog.d(TAG, "Could not find task for id: "+ taskId);
9383                return;
9384            }
9385            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9386                mStackSupervisor.showLockTaskToast();
9387                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9388                return;
9389            }
9390            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9391            if (prev != null && prev.isRecentsActivity()) {
9392                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9393            }
9394            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
9395        } finally {
9396            Binder.restoreCallingIdentity(origId);
9397        }
9398        ActivityOptions.abort(options);
9399    }
9400
9401    /**
9402     * Moves an activity, and all of the other activities within the same task, to the bottom
9403     * of the history stack.  The activity's order within the task is unchanged.
9404     *
9405     * @param token A reference to the activity we wish to move
9406     * @param nonRoot If false then this only works if the activity is the root
9407     *                of a task; if true it will work for any activity in a task.
9408     * @return Returns true if the move completed, false if not.
9409     */
9410    @Override
9411    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9412        enforceNotIsolatedCaller("moveActivityTaskToBack");
9413        synchronized(this) {
9414            final long origId = Binder.clearCallingIdentity();
9415            try {
9416                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9417                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9418                if (task != null) {
9419                    if (mStackSupervisor.isLockedTask(task)) {
9420                        mStackSupervisor.showLockTaskToast();
9421                        return false;
9422                    }
9423                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9424                }
9425            } finally {
9426                Binder.restoreCallingIdentity(origId);
9427            }
9428        }
9429        return false;
9430    }
9431
9432    @Override
9433    public void moveTaskBackwards(int task) {
9434        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9435                "moveTaskBackwards()");
9436
9437        synchronized(this) {
9438            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9439                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9440                return;
9441            }
9442            final long origId = Binder.clearCallingIdentity();
9443            moveTaskBackwardsLocked(task);
9444            Binder.restoreCallingIdentity(origId);
9445        }
9446    }
9447
9448    private final void moveTaskBackwardsLocked(int task) {
9449        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9450    }
9451
9452    @Override
9453    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9454            IActivityContainerCallback callback) throws RemoteException {
9455        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9456        synchronized (this) {
9457            if (parentActivityToken == null) {
9458                throw new IllegalArgumentException("parent token must not be null");
9459            }
9460            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9461            if (r == null) {
9462                return null;
9463            }
9464            if (callback == null) {
9465                throw new IllegalArgumentException("callback must not be null");
9466            }
9467            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9468        }
9469    }
9470
9471    @Override
9472    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9473        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9474        synchronized (this) {
9475            mStackSupervisor.deleteActivityContainer(container);
9476        }
9477    }
9478
9479    @Override
9480    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9481        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9482        synchronized (this) {
9483            final int stackId = mStackSupervisor.getNextStackId();
9484            final ActivityStack stack =
9485                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9486            if (stack == null) {
9487                return null;
9488            }
9489            return stack.mActivityContainer;
9490        }
9491    }
9492
9493    @Override
9494    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9495        synchronized (this) {
9496            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9497            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9498                return stack.mActivityContainer.getDisplayId();
9499            }
9500            return Display.DEFAULT_DISPLAY;
9501        }
9502    }
9503
9504    @Override
9505    public int getActivityStackId(IBinder token) throws RemoteException {
9506        synchronized (this) {
9507            ActivityStack stack = ActivityRecord.getStackLocked(token);
9508            if (stack == null) {
9509                return INVALID_STACK_ID;
9510            }
9511            return stack.mStackId;
9512        }
9513    }
9514
9515    @Override
9516    public void exitFreeformMode(IBinder token) throws RemoteException {
9517        synchronized (this) {
9518            long ident = Binder.clearCallingIdentity();
9519            try {
9520                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9521                if (r == null) {
9522                    throw new IllegalArgumentException(
9523                            "exitFreeformMode: No activity record matching token=" + token);
9524                }
9525                final ActivityStack stack = r.getStackLocked(token);
9526                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9527                    throw new IllegalStateException(
9528                            "exitFreeformMode: You can only go fullscreen from freeform.");
9529                }
9530                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9531                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9532                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9533            } finally {
9534                Binder.restoreCallingIdentity(ident);
9535            }
9536        }
9537    }
9538
9539    @Override
9540    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9541        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9542        if (stackId == HOME_STACK_ID) {
9543            throw new IllegalArgumentException(
9544                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9545        }
9546        synchronized (this) {
9547            long ident = Binder.clearCallingIdentity();
9548            try {
9549                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9550                        + " to stackId=" + stackId + " toTop=" + toTop);
9551                if (stackId == DOCKED_STACK_ID) {
9552                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9553                            null /* initialBounds */);
9554                }
9555                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9556                        "moveTaskToStack", ANIMATE);
9557            } finally {
9558                Binder.restoreCallingIdentity(ident);
9559            }
9560        }
9561    }
9562
9563    @Override
9564    public void swapDockedAndFullscreenStack() throws RemoteException {
9565        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9566        synchronized (this) {
9567            long ident = Binder.clearCallingIdentity();
9568            try {
9569                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9570                        FULLSCREEN_WORKSPACE_STACK_ID);
9571                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9572                        : null;
9573                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9574                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9575                        : null;
9576                if (topTask == null || tasks == null || tasks.size() == 0) {
9577                    Slog.w(TAG,
9578                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9579                    return;
9580                }
9581
9582                // TODO: App transition
9583                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9584
9585                // Defer the resume so resume/pausing while moving stacks is dangerous.
9586                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9587                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9588                        ANIMATE, true /* deferResume */);
9589                final int size = tasks.size();
9590                for (int i = 0; i < size; i++) {
9591                    final int id = tasks.get(i).taskId;
9592                    if (id == topTask.taskId) {
9593                        continue;
9594                    }
9595                    mStackSupervisor.moveTaskToStackLocked(id,
9596                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9597                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9598                }
9599
9600                // Because we deferred the resume, to avoid conflicts with stack switches while
9601                // resuming, we need to do it after all the tasks are moved.
9602                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9603                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9604
9605                mWindowManager.executeAppTransition();
9606            } finally {
9607                Binder.restoreCallingIdentity(ident);
9608            }
9609        }
9610    }
9611
9612    /**
9613     * Moves the input task to the docked stack.
9614     *
9615     * @param taskId Id of task to move.
9616     * @param createMode The mode the docked stack should be created in if it doesn't exist
9617     *                   already. See
9618     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9619     *                   and
9620     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9621     * @param toTop If the task and stack should be moved to the top.
9622     * @param animate Whether we should play an animation for the moving the task
9623     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9624     *                      docked stack. Pass {@code null} to use default bounds.
9625     */
9626    @Override
9627    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9628            Rect initialBounds) {
9629        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9630        synchronized (this) {
9631            long ident = Binder.clearCallingIdentity();
9632            try {
9633                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9634                        + " to createMode=" + createMode + " toTop=" + toTop);
9635                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9636                return mStackSupervisor.moveTaskToStackLocked(
9637                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9638                        "moveTaskToDockedStack", animate);
9639            } finally {
9640                Binder.restoreCallingIdentity(ident);
9641            }
9642        }
9643    }
9644
9645    /**
9646     * Moves the top activity in the input stackId to the pinned stack.
9647     *
9648     * @param stackId Id of stack to move the top activity to pinned stack.
9649     * @param bounds Bounds to use for pinned stack.
9650     *
9651     * @return True if the top activity of the input stack was successfully moved to the pinned
9652     *          stack.
9653     */
9654    @Override
9655    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9656        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9657        synchronized (this) {
9658            if (!mSupportsPictureInPicture) {
9659                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9660                        + "Device doesn't support picture-in-pciture mode");
9661            }
9662
9663            long ident = Binder.clearCallingIdentity();
9664            try {
9665                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9666            } finally {
9667                Binder.restoreCallingIdentity(ident);
9668            }
9669        }
9670    }
9671
9672    @Override
9673    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9674            boolean preserveWindows, boolean animate) {
9675        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9676        long ident = Binder.clearCallingIdentity();
9677        try {
9678            synchronized (this) {
9679                if (animate) {
9680                    if (stackId == PINNED_STACK_ID) {
9681                        mWindowManager.animateResizePinnedStack(bounds);
9682                    } else {
9683                        throw new IllegalArgumentException("Stack: " + stackId
9684                                + " doesn't support animated resize.");
9685                    }
9686                } else {
9687                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9688                            null /* tempTaskInsetBounds */, preserveWindows,
9689                            allowResizeInDockedMode);
9690                }
9691            }
9692        } finally {
9693            Binder.restoreCallingIdentity(ident);
9694        }
9695    }
9696
9697    @Override
9698    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9699            Rect tempDockedTaskInsetBounds,
9700            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9701        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9702                "resizeDockedStack()");
9703        long ident = Binder.clearCallingIdentity();
9704        try {
9705            synchronized (this) {
9706                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9707                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9708                        PRESERVE_WINDOWS);
9709            }
9710        } finally {
9711            Binder.restoreCallingIdentity(ident);
9712        }
9713    }
9714
9715    @Override
9716    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9717        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9718                "resizePinnedStack()");
9719        final long ident = Binder.clearCallingIdentity();
9720        try {
9721            synchronized (this) {
9722                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9723            }
9724        } finally {
9725            Binder.restoreCallingIdentity(ident);
9726        }
9727    }
9728
9729    @Override
9730    public void positionTaskInStack(int taskId, int stackId, int position) {
9731        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9732        if (stackId == HOME_STACK_ID) {
9733            throw new IllegalArgumentException(
9734                    "positionTaskInStack: Attempt to change the position of task "
9735                    + taskId + " in/to home stack");
9736        }
9737        synchronized (this) {
9738            long ident = Binder.clearCallingIdentity();
9739            try {
9740                if (DEBUG_STACK) Slog.d(TAG_STACK,
9741                        "positionTaskInStack: positioning task=" + taskId
9742                        + " in stackId=" + stackId + " at position=" + position);
9743                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9744            } finally {
9745                Binder.restoreCallingIdentity(ident);
9746            }
9747        }
9748    }
9749
9750    @Override
9751    public List<StackInfo> getAllStackInfos() {
9752        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9753        long ident = Binder.clearCallingIdentity();
9754        try {
9755            synchronized (this) {
9756                return mStackSupervisor.getAllStackInfosLocked();
9757            }
9758        } finally {
9759            Binder.restoreCallingIdentity(ident);
9760        }
9761    }
9762
9763    @Override
9764    public StackInfo getStackInfo(int stackId) {
9765        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9766        long ident = Binder.clearCallingIdentity();
9767        try {
9768            synchronized (this) {
9769                return mStackSupervisor.getStackInfoLocked(stackId);
9770            }
9771        } finally {
9772            Binder.restoreCallingIdentity(ident);
9773        }
9774    }
9775
9776    @Override
9777    public boolean isInHomeStack(int taskId) {
9778        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9779        long ident = Binder.clearCallingIdentity();
9780        try {
9781            synchronized (this) {
9782                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9783                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9784                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9785            }
9786        } finally {
9787            Binder.restoreCallingIdentity(ident);
9788        }
9789    }
9790
9791    @Override
9792    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9793        synchronized(this) {
9794            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9795        }
9796    }
9797
9798    @Override
9799    public void updateDeviceOwner(String packageName) {
9800        final int callingUid = Binder.getCallingUid();
9801        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9802            throw new SecurityException("updateDeviceOwner called from non-system process");
9803        }
9804        synchronized (this) {
9805            mDeviceOwnerName = packageName;
9806        }
9807    }
9808
9809    @Override
9810    public void updateLockTaskPackages(int userId, String[] packages) {
9811        final int callingUid = Binder.getCallingUid();
9812        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9813            throw new SecurityException("updateLockTaskPackage called from non-system process");
9814        }
9815        synchronized (this) {
9816            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9817                    Arrays.toString(packages));
9818            mLockTaskPackages.put(userId, packages);
9819            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9820        }
9821    }
9822
9823
9824    void startLockTaskModeLocked(TaskRecord task) {
9825        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9826        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9827            return;
9828        }
9829
9830        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9831        // is initiated by system after the pinning request was shown and locked mode is initiated
9832        // by an authorized app directly
9833        final int callingUid = Binder.getCallingUid();
9834        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9835        long ident = Binder.clearCallingIdentity();
9836        try {
9837            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9838            if (!isSystemInitiated) {
9839                task.mLockTaskUid = callingUid;
9840                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9841                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9842                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9843                    StatusBarManagerInternal statusBarManager =
9844                            LocalServices.getService(StatusBarManagerInternal.class);
9845                    if (statusBarManager != null) {
9846                        statusBarManager.showScreenPinningRequest();
9847                    }
9848                    return;
9849                }
9850
9851                if (stack == null || task != stack.topTask()) {
9852                    throw new IllegalArgumentException("Invalid task, not in foreground");
9853                }
9854            }
9855            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9856                    "Locking fully");
9857            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9858                    ActivityManager.LOCK_TASK_MODE_PINNED :
9859                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9860                    "startLockTask", true);
9861        } finally {
9862            Binder.restoreCallingIdentity(ident);
9863        }
9864    }
9865
9866    @Override
9867    public void startLockTaskMode(int taskId) {
9868        synchronized (this) {
9869            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9870            if (task != null) {
9871                startLockTaskModeLocked(task);
9872            }
9873        }
9874    }
9875
9876    @Override
9877    public void startLockTaskMode(IBinder token) {
9878        synchronized (this) {
9879            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9880            if (r == null) {
9881                return;
9882            }
9883            final TaskRecord task = r.task;
9884            if (task != null) {
9885                startLockTaskModeLocked(task);
9886            }
9887        }
9888    }
9889
9890    @Override
9891    public void startLockTaskModeOnCurrent() throws RemoteException {
9892        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startLockTaskModeOnCurrent");
9893        long ident = Binder.clearCallingIdentity();
9894        try {
9895            synchronized (this) {
9896                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9897                if (r != null) {
9898                    startLockTaskModeLocked(r.task);
9899                }
9900            }
9901        } finally {
9902            Binder.restoreCallingIdentity(ident);
9903        }
9904    }
9905
9906    @Override
9907    public void stopLockTaskMode() {
9908        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9909        if (lockTask == null) {
9910            // Our work here is done.
9911            return;
9912        }
9913
9914        final int callingUid = Binder.getCallingUid();
9915        final int lockTaskUid = lockTask.mLockTaskUid;
9916        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9917        // It is possible lockTaskMode was started by the system process because
9918        // android:lockTaskMode is set to a locking value in the application manifest instead of
9919        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9920        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9921        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9922                callingUid != lockTaskUid
9923                && (lockTaskUid != 0
9924                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9925            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9926                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9927        }
9928
9929        long ident = Binder.clearCallingIdentity();
9930        try {
9931            Log.d(TAG, "stopLockTaskMode");
9932            // Stop lock task
9933            synchronized (this) {
9934                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9935                        "stopLockTask", true);
9936            }
9937        } finally {
9938            Binder.restoreCallingIdentity(ident);
9939        }
9940    }
9941
9942    @Override
9943    public void stopLockTaskModeOnCurrent() throws RemoteException {
9944        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopLockTaskModeOnCurrent");
9945        long ident = Binder.clearCallingIdentity();
9946        try {
9947            stopLockTaskMode();
9948        } finally {
9949            Binder.restoreCallingIdentity(ident);
9950        }
9951    }
9952
9953    @Override
9954    public boolean isInLockTaskMode() {
9955        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9956    }
9957
9958    @Override
9959    public int getLockTaskModeState() {
9960        synchronized (this) {
9961            return mStackSupervisor.getLockTaskModeState();
9962        }
9963    }
9964
9965    @Override
9966    public void showLockTaskEscapeMessage(IBinder token) {
9967        synchronized (this) {
9968            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9969            if (r == null) {
9970                return;
9971            }
9972            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9973        }
9974    }
9975
9976    // =========================================================
9977    // CONTENT PROVIDERS
9978    // =========================================================
9979
9980    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9981        List<ProviderInfo> providers = null;
9982        try {
9983            providers = AppGlobals.getPackageManager()
9984                    .queryContentProviders(app.processName, app.uid,
9985                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
9986                                    | MATCH_DEBUG_TRIAGED_MISSING)
9987                    .getList();
9988        } catch (RemoteException ex) {
9989        }
9990        if (DEBUG_MU) Slog.v(TAG_MU,
9991                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9992        int userId = app.userId;
9993        if (providers != null) {
9994            int N = providers.size();
9995            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9996            for (int i=0; i<N; i++) {
9997                ProviderInfo cpi =
9998                    (ProviderInfo)providers.get(i);
9999                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10000                        cpi.name, cpi.flags);
10001                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10002                    // This is a singleton provider, but a user besides the
10003                    // default user is asking to initialize a process it runs
10004                    // in...  well, no, it doesn't actually run in this process,
10005                    // it runs in the process of the default user.  Get rid of it.
10006                    providers.remove(i);
10007                    N--;
10008                    i--;
10009                    continue;
10010                }
10011
10012                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10013                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10014                if (cpr == null) {
10015                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10016                    mProviderMap.putProviderByClass(comp, cpr);
10017                }
10018                if (DEBUG_MU) Slog.v(TAG_MU,
10019                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10020                app.pubProviders.put(cpi.name, cpr);
10021                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10022                    // Don't add this if it is a platform component that is marked
10023                    // to run in multiple processes, because this is actually
10024                    // part of the framework so doesn't make sense to track as a
10025                    // separate apk in the process.
10026                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10027                            mProcessStats);
10028                }
10029                notifyPackageUse(cpi.applicationInfo.packageName);
10030            }
10031        }
10032        return providers;
10033    }
10034
10035    /**
10036     * Check if {@link ProcessRecord} has a possible chance at accessing the
10037     * given {@link ProviderInfo}. Final permission checking is always done
10038     * in {@link ContentProvider}.
10039     */
10040    private final String checkContentProviderPermissionLocked(
10041            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10042        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10043        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10044        boolean checkedGrants = false;
10045        if (checkUser) {
10046            // Looking for cross-user grants before enforcing the typical cross-users permissions
10047            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10048            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10049                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10050                    return null;
10051                }
10052                checkedGrants = true;
10053            }
10054            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10055                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10056            if (userId != tmpTargetUserId) {
10057                // When we actually went to determine the final targer user ID, this ended
10058                // up different than our initial check for the authority.  This is because
10059                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10060                // SELF.  So we need to re-check the grants again.
10061                checkedGrants = false;
10062            }
10063        }
10064        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10065                cpi.applicationInfo.uid, cpi.exported)
10066                == PackageManager.PERMISSION_GRANTED) {
10067            return null;
10068        }
10069        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10070                cpi.applicationInfo.uid, cpi.exported)
10071                == PackageManager.PERMISSION_GRANTED) {
10072            return null;
10073        }
10074
10075        PathPermission[] pps = cpi.pathPermissions;
10076        if (pps != null) {
10077            int i = pps.length;
10078            while (i > 0) {
10079                i--;
10080                PathPermission pp = pps[i];
10081                String pprperm = pp.getReadPermission();
10082                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10083                        cpi.applicationInfo.uid, cpi.exported)
10084                        == PackageManager.PERMISSION_GRANTED) {
10085                    return null;
10086                }
10087                String ppwperm = pp.getWritePermission();
10088                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10089                        cpi.applicationInfo.uid, cpi.exported)
10090                        == PackageManager.PERMISSION_GRANTED) {
10091                    return null;
10092                }
10093            }
10094        }
10095        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10096            return null;
10097        }
10098
10099        String msg;
10100        if (!cpi.exported) {
10101            msg = "Permission Denial: opening provider " + cpi.name
10102                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10103                    + ", uid=" + callingUid + ") that is not exported from uid "
10104                    + cpi.applicationInfo.uid;
10105        } else {
10106            msg = "Permission Denial: opening provider " + cpi.name
10107                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10108                    + ", uid=" + callingUid + ") requires "
10109                    + cpi.readPermission + " or " + cpi.writePermission;
10110        }
10111        Slog.w(TAG, msg);
10112        return msg;
10113    }
10114
10115    /**
10116     * Returns if the ContentProvider has granted a uri to callingUid
10117     */
10118    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10119        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10120        if (perms != null) {
10121            for (int i=perms.size()-1; i>=0; i--) {
10122                GrantUri grantUri = perms.keyAt(i);
10123                if (grantUri.sourceUserId == userId || !checkUser) {
10124                    if (matchesProvider(grantUri.uri, cpi)) {
10125                        return true;
10126                    }
10127                }
10128            }
10129        }
10130        return false;
10131    }
10132
10133    /**
10134     * Returns true if the uri authority is one of the authorities specified in the provider.
10135     */
10136    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10137        String uriAuth = uri.getAuthority();
10138        String cpiAuth = cpi.authority;
10139        if (cpiAuth.indexOf(';') == -1) {
10140            return cpiAuth.equals(uriAuth);
10141        }
10142        String[] cpiAuths = cpiAuth.split(";");
10143        int length = cpiAuths.length;
10144        for (int i = 0; i < length; i++) {
10145            if (cpiAuths[i].equals(uriAuth)) return true;
10146        }
10147        return false;
10148    }
10149
10150    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10151            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10152        if (r != null) {
10153            for (int i=0; i<r.conProviders.size(); i++) {
10154                ContentProviderConnection conn = r.conProviders.get(i);
10155                if (conn.provider == cpr) {
10156                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10157                            "Adding provider requested by "
10158                            + r.processName + " from process "
10159                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10160                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10161                    if (stable) {
10162                        conn.stableCount++;
10163                        conn.numStableIncs++;
10164                    } else {
10165                        conn.unstableCount++;
10166                        conn.numUnstableIncs++;
10167                    }
10168                    return conn;
10169                }
10170            }
10171            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10172            if (stable) {
10173                conn.stableCount = 1;
10174                conn.numStableIncs = 1;
10175            } else {
10176                conn.unstableCount = 1;
10177                conn.numUnstableIncs = 1;
10178            }
10179            cpr.connections.add(conn);
10180            r.conProviders.add(conn);
10181            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
10182            return conn;
10183        }
10184        cpr.addExternalProcessHandleLocked(externalProcessToken);
10185        return null;
10186    }
10187
10188    boolean decProviderCountLocked(ContentProviderConnection conn,
10189            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10190        if (conn != null) {
10191            cpr = conn.provider;
10192            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10193                    "Removing provider requested by "
10194                    + conn.client.processName + " from process "
10195                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10196                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10197            if (stable) {
10198                conn.stableCount--;
10199            } else {
10200                conn.unstableCount--;
10201            }
10202            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10203                cpr.connections.remove(conn);
10204                conn.client.conProviders.remove(conn);
10205                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10206                    // The client is more important than last activity -- note the time this
10207                    // is happening, so we keep the old provider process around a bit as last
10208                    // activity to avoid thrashing it.
10209                    if (cpr.proc != null) {
10210                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10211                    }
10212                }
10213                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10214                return true;
10215            }
10216            return false;
10217        }
10218        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10219        return false;
10220    }
10221
10222    private void checkTime(long startTime, String where) {
10223        long now = SystemClock.elapsedRealtime();
10224        if ((now-startTime) > 1000) {
10225            // If we are taking more than a second, log about it.
10226            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10227        }
10228    }
10229
10230    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10231            String name, IBinder token, boolean stable, int userId) {
10232        ContentProviderRecord cpr;
10233        ContentProviderConnection conn = null;
10234        ProviderInfo cpi = null;
10235
10236        synchronized(this) {
10237            long startTime = SystemClock.elapsedRealtime();
10238
10239            ProcessRecord r = null;
10240            if (caller != null) {
10241                r = getRecordForAppLocked(caller);
10242                if (r == null) {
10243                    throw new SecurityException(
10244                            "Unable to find app for caller " + caller
10245                          + " (pid=" + Binder.getCallingPid()
10246                          + ") when getting content provider " + name);
10247                }
10248            }
10249
10250            boolean checkCrossUser = true;
10251
10252            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10253
10254            // First check if this content provider has been published...
10255            cpr = mProviderMap.getProviderByName(name, userId);
10256            // If that didn't work, check if it exists for user 0 and then
10257            // verify that it's a singleton provider before using it.
10258            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10259                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10260                if (cpr != null) {
10261                    cpi = cpr.info;
10262                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10263                            cpi.name, cpi.flags)
10264                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10265                        userId = UserHandle.USER_SYSTEM;
10266                        checkCrossUser = false;
10267                    } else {
10268                        cpr = null;
10269                        cpi = null;
10270                    }
10271                }
10272            }
10273
10274            boolean providerRunning = cpr != null;
10275            if (providerRunning) {
10276                cpi = cpr.info;
10277                String msg;
10278                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10279                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10280                        != null) {
10281                    throw new SecurityException(msg);
10282                }
10283                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10284
10285                if (r != null && cpr.canRunHere(r)) {
10286                    // This provider has been published or is in the process
10287                    // of being published...  but it is also allowed to run
10288                    // in the caller's process, so don't make a connection
10289                    // and just let the caller instantiate its own instance.
10290                    ContentProviderHolder holder = cpr.newHolder(null);
10291                    // don't give caller the provider object, it needs
10292                    // to make its own.
10293                    holder.provider = null;
10294                    return holder;
10295                }
10296
10297                final long origId = Binder.clearCallingIdentity();
10298
10299                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10300
10301                // In this case the provider instance already exists, so we can
10302                // return it right away.
10303                conn = incProviderCountLocked(r, cpr, token, stable);
10304                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10305                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10306                        // If this is a perceptible app accessing the provider,
10307                        // make sure to count it as being accessed and thus
10308                        // back up on the LRU list.  This is good because
10309                        // content providers are often expensive to start.
10310                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10311                        updateLruProcessLocked(cpr.proc, false, null);
10312                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10313                    }
10314                }
10315
10316                if (cpr.proc != null) {
10317                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10318                    boolean success = updateOomAdjLocked(cpr.proc);
10319                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10320                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10321                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10322                    // NOTE: there is still a race here where a signal could be
10323                    // pending on the process even though we managed to update its
10324                    // adj level.  Not sure what to do about this, but at least
10325                    // the race is now smaller.
10326                    if (!success) {
10327                        // Uh oh...  it looks like the provider's process
10328                        // has been killed on us.  We need to wait for a new
10329                        // process to be started, and make sure its death
10330                        // doesn't kill our process.
10331                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10332                                + " is crashing; detaching " + r);
10333                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10334                        checkTime(startTime, "getContentProviderImpl: before appDied");
10335                        appDiedLocked(cpr.proc);
10336                        checkTime(startTime, "getContentProviderImpl: after appDied");
10337                        if (!lastRef) {
10338                            // This wasn't the last ref our process had on
10339                            // the provider...  we have now been killed, bail.
10340                            return null;
10341                        }
10342                        providerRunning = false;
10343                        conn = null;
10344                    }
10345                }
10346
10347                Binder.restoreCallingIdentity(origId);
10348            }
10349
10350            if (!providerRunning) {
10351                try {
10352                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10353                    cpi = AppGlobals.getPackageManager().
10354                        resolveContentProvider(name,
10355                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10356                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10357                } catch (RemoteException ex) {
10358                }
10359                if (cpi == null) {
10360                    return null;
10361                }
10362                // If the provider is a singleton AND
10363                // (it's a call within the same user || the provider is a
10364                // privileged app)
10365                // Then allow connecting to the singleton provider
10366                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10367                        cpi.name, cpi.flags)
10368                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10369                if (singleton) {
10370                    userId = UserHandle.USER_SYSTEM;
10371                }
10372                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10373                checkTime(startTime, "getContentProviderImpl: got app info for user");
10374
10375                String msg;
10376                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10377                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10378                        != null) {
10379                    throw new SecurityException(msg);
10380                }
10381                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10382
10383                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
10384                        && !cpi.processName.equals("system")) {
10385                    // If this content provider does not run in the system
10386                    // process, and the system is not yet ready to run other
10387                    // processes, then fail fast instead of hanging.
10388                    throw new IllegalArgumentException(
10389                            "Attempt to launch content provider before system ready");
10390                }
10391
10392                // Make sure that the user who owns this provider is running.  If not,
10393                // we don't want to allow it to run.
10394                if (!mUserController.isUserRunningLocked(userId, 0)) {
10395                    Slog.w(TAG, "Unable to launch app "
10396                            + cpi.applicationInfo.packageName + "/"
10397                            + cpi.applicationInfo.uid + " for provider "
10398                            + name + ": user " + userId + " is stopped");
10399                    return null;
10400                }
10401
10402                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10403                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10404                cpr = mProviderMap.getProviderByClass(comp, userId);
10405                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10406                final boolean firstClass = cpr == null;
10407                if (firstClass) {
10408                    final long ident = Binder.clearCallingIdentity();
10409
10410                    // If permissions need a review before any of the app components can run,
10411                    // we return no provider and launch a review activity if the calling app
10412                    // is in the foreground.
10413                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10414                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10415                            return null;
10416                        }
10417                    }
10418
10419                    try {
10420                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10421                        ApplicationInfo ai =
10422                            AppGlobals.getPackageManager().
10423                                getApplicationInfo(
10424                                        cpi.applicationInfo.packageName,
10425                                        STOCK_PM_FLAGS, userId);
10426                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10427                        if (ai == null) {
10428                            Slog.w(TAG, "No package info for content provider "
10429                                    + cpi.name);
10430                            return null;
10431                        }
10432                        ai = getAppInfoForUser(ai, userId);
10433                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10434                    } catch (RemoteException ex) {
10435                        // pm is in same process, this will never happen.
10436                    } finally {
10437                        Binder.restoreCallingIdentity(ident);
10438                    }
10439                }
10440
10441                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10442
10443                if (r != null && cpr.canRunHere(r)) {
10444                    // If this is a multiprocess provider, then just return its
10445                    // info and allow the caller to instantiate it.  Only do
10446                    // this if the provider is the same user as the caller's
10447                    // process, or can run as root (so can be in any process).
10448                    return cpr.newHolder(null);
10449                }
10450
10451                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10452                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10453                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10454
10455                // This is single process, and our app is now connecting to it.
10456                // See if we are already in the process of launching this
10457                // provider.
10458                final int N = mLaunchingProviders.size();
10459                int i;
10460                for (i = 0; i < N; i++) {
10461                    if (mLaunchingProviders.get(i) == cpr) {
10462                        break;
10463                    }
10464                }
10465
10466                // If the provider is not already being launched, then get it
10467                // started.
10468                if (i >= N) {
10469                    final long origId = Binder.clearCallingIdentity();
10470
10471                    try {
10472                        // Content provider is now in use, its package can't be stopped.
10473                        try {
10474                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10475                            AppGlobals.getPackageManager().setPackageStoppedState(
10476                                    cpr.appInfo.packageName, false, userId);
10477                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10478                        } catch (RemoteException e) {
10479                        } catch (IllegalArgumentException e) {
10480                            Slog.w(TAG, "Failed trying to unstop package "
10481                                    + cpr.appInfo.packageName + ": " + e);
10482                        }
10483
10484                        // Use existing process if already started
10485                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10486                        ProcessRecord proc = getProcessRecordLocked(
10487                                cpi.processName, cpr.appInfo.uid, false);
10488                        if (proc != null && proc.thread != null) {
10489                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10490                                    "Installing in existing process " + proc);
10491                            if (!proc.pubProviders.containsKey(cpi.name)) {
10492                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10493                                proc.pubProviders.put(cpi.name, cpr);
10494                                try {
10495                                    proc.thread.scheduleInstallProvider(cpi);
10496                                } catch (RemoteException e) {
10497                                }
10498                            }
10499                        } else {
10500                            checkTime(startTime, "getContentProviderImpl: before start process");
10501                            proc = startProcessLocked(cpi.processName,
10502                                    cpr.appInfo, false, 0, "content provider",
10503                                    new ComponentName(cpi.applicationInfo.packageName,
10504                                            cpi.name), false, false, false);
10505                            checkTime(startTime, "getContentProviderImpl: after start process");
10506                            if (proc == null) {
10507                                Slog.w(TAG, "Unable to launch app "
10508                                        + cpi.applicationInfo.packageName + "/"
10509                                        + cpi.applicationInfo.uid + " for provider "
10510                                        + name + ": process is bad");
10511                                return null;
10512                            }
10513                        }
10514                        cpr.launchingApp = proc;
10515                        mLaunchingProviders.add(cpr);
10516                    } finally {
10517                        Binder.restoreCallingIdentity(origId);
10518                    }
10519                }
10520
10521                checkTime(startTime, "getContentProviderImpl: updating data structures");
10522
10523                // Make sure the provider is published (the same provider class
10524                // may be published under multiple names).
10525                if (firstClass) {
10526                    mProviderMap.putProviderByClass(comp, cpr);
10527                }
10528
10529                mProviderMap.putProviderByName(name, cpr);
10530                conn = incProviderCountLocked(r, cpr, token, stable);
10531                if (conn != null) {
10532                    conn.waiting = true;
10533                }
10534            }
10535            checkTime(startTime, "getContentProviderImpl: done!");
10536        }
10537
10538        // Wait for the provider to be published...
10539        synchronized (cpr) {
10540            while (cpr.provider == null) {
10541                if (cpr.launchingApp == null) {
10542                    Slog.w(TAG, "Unable to launch app "
10543                            + cpi.applicationInfo.packageName + "/"
10544                            + cpi.applicationInfo.uid + " for provider "
10545                            + name + ": launching app became null");
10546                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10547                            UserHandle.getUserId(cpi.applicationInfo.uid),
10548                            cpi.applicationInfo.packageName,
10549                            cpi.applicationInfo.uid, name);
10550                    return null;
10551                }
10552                try {
10553                    if (DEBUG_MU) Slog.v(TAG_MU,
10554                            "Waiting to start provider " + cpr
10555                            + " launchingApp=" + cpr.launchingApp);
10556                    if (conn != null) {
10557                        conn.waiting = true;
10558                    }
10559                    cpr.wait();
10560                } catch (InterruptedException ex) {
10561                } finally {
10562                    if (conn != null) {
10563                        conn.waiting = false;
10564                    }
10565                }
10566            }
10567        }
10568        return cpr != null ? cpr.newHolder(conn) : null;
10569    }
10570
10571    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10572            ProcessRecord r, final int userId) {
10573        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10574                cpi.packageName, r.userId)) {
10575
10576            final boolean callerForeground = r != null ? r.setSchedGroup
10577                    != ProcessList.SCHED_GROUP_BACKGROUND : true;
10578
10579            // Show a permission review UI only for starting from a foreground app
10580            if (!callerForeground) {
10581                Slog.w(TAG, "u" + r.userId + " Instantiating a provider in package"
10582                        + cpi.packageName + " requires a permissions review");
10583                return false;
10584            }
10585
10586            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10587            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10588                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10589            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10590
10591            if (DEBUG_PERMISSIONS_REVIEW) {
10592                Slog.i(TAG, "u" + r.userId + " Launching permission review "
10593                        + "for package " + cpi.packageName);
10594            }
10595
10596            final UserHandle userHandle = new UserHandle(userId);
10597            mHandler.post(new Runnable() {
10598                @Override
10599                public void run() {
10600                    mContext.startActivityAsUser(intent, userHandle);
10601                }
10602            });
10603
10604            return false;
10605        }
10606
10607        return true;
10608    }
10609
10610    PackageManagerInternal getPackageManagerInternalLocked() {
10611        if (mPackageManagerInt == null) {
10612            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10613        }
10614        return mPackageManagerInt;
10615    }
10616
10617    @Override
10618    public final ContentProviderHolder getContentProvider(
10619            IApplicationThread caller, String name, int userId, boolean stable) {
10620        enforceNotIsolatedCaller("getContentProvider");
10621        if (caller == null) {
10622            String msg = "null IApplicationThread when getting content provider "
10623                    + name;
10624            Slog.w(TAG, msg);
10625            throw new SecurityException(msg);
10626        }
10627        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10628        // with cross-user grant.
10629        return getContentProviderImpl(caller, name, null, stable, userId);
10630    }
10631
10632    public ContentProviderHolder getContentProviderExternal(
10633            String name, int userId, IBinder token) {
10634        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10635            "Do not have permission in call getContentProviderExternal()");
10636        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10637                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10638        return getContentProviderExternalUnchecked(name, token, userId);
10639    }
10640
10641    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10642            IBinder token, int userId) {
10643        return getContentProviderImpl(null, name, token, true, userId);
10644    }
10645
10646    /**
10647     * Drop a content provider from a ProcessRecord's bookkeeping
10648     */
10649    public void removeContentProvider(IBinder connection, boolean stable) {
10650        enforceNotIsolatedCaller("removeContentProvider");
10651        long ident = Binder.clearCallingIdentity();
10652        try {
10653            synchronized (this) {
10654                ContentProviderConnection conn;
10655                try {
10656                    conn = (ContentProviderConnection)connection;
10657                } catch (ClassCastException e) {
10658                    String msg ="removeContentProvider: " + connection
10659                            + " not a ContentProviderConnection";
10660                    Slog.w(TAG, msg);
10661                    throw new IllegalArgumentException(msg);
10662                }
10663                if (conn == null) {
10664                    throw new NullPointerException("connection is null");
10665                }
10666                if (decProviderCountLocked(conn, null, null, stable)) {
10667                    updateOomAdjLocked();
10668                }
10669            }
10670        } finally {
10671            Binder.restoreCallingIdentity(ident);
10672        }
10673    }
10674
10675    public void removeContentProviderExternal(String name, IBinder token) {
10676        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10677            "Do not have permission in call removeContentProviderExternal()");
10678        int userId = UserHandle.getCallingUserId();
10679        long ident = Binder.clearCallingIdentity();
10680        try {
10681            removeContentProviderExternalUnchecked(name, token, userId);
10682        } finally {
10683            Binder.restoreCallingIdentity(ident);
10684        }
10685    }
10686
10687    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10688        synchronized (this) {
10689            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10690            if(cpr == null) {
10691                //remove from mProvidersByClass
10692                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10693                return;
10694            }
10695
10696            //update content provider record entry info
10697            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10698            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10699            if (localCpr.hasExternalProcessHandles()) {
10700                if (localCpr.removeExternalProcessHandleLocked(token)) {
10701                    updateOomAdjLocked();
10702                } else {
10703                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10704                            + " with no external reference for token: "
10705                            + token + ".");
10706                }
10707            } else {
10708                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10709                        + " with no external references.");
10710            }
10711        }
10712    }
10713
10714    public final void publishContentProviders(IApplicationThread caller,
10715            List<ContentProviderHolder> providers) {
10716        if (providers == null) {
10717            return;
10718        }
10719
10720        enforceNotIsolatedCaller("publishContentProviders");
10721        synchronized (this) {
10722            final ProcessRecord r = getRecordForAppLocked(caller);
10723            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10724            if (r == null) {
10725                throw new SecurityException(
10726                        "Unable to find app for caller " + caller
10727                      + " (pid=" + Binder.getCallingPid()
10728                      + ") when publishing content providers");
10729            }
10730
10731            final long origId = Binder.clearCallingIdentity();
10732
10733            final int N = providers.size();
10734            for (int i = 0; i < N; i++) {
10735                ContentProviderHolder src = providers.get(i);
10736                if (src == null || src.info == null || src.provider == null) {
10737                    continue;
10738                }
10739                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10740                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10741                if (dst != null) {
10742                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10743                    mProviderMap.putProviderByClass(comp, dst);
10744                    String names[] = dst.info.authority.split(";");
10745                    for (int j = 0; j < names.length; j++) {
10746                        mProviderMap.putProviderByName(names[j], dst);
10747                    }
10748
10749                    int launchingCount = mLaunchingProviders.size();
10750                    int j;
10751                    boolean wasInLaunchingProviders = false;
10752                    for (j = 0; j < launchingCount; j++) {
10753                        if (mLaunchingProviders.get(j) == dst) {
10754                            mLaunchingProviders.remove(j);
10755                            wasInLaunchingProviders = true;
10756                            j--;
10757                            launchingCount--;
10758                        }
10759                    }
10760                    if (wasInLaunchingProviders) {
10761                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10762                    }
10763                    synchronized (dst) {
10764                        dst.provider = src.provider;
10765                        dst.proc = r;
10766                        dst.notifyAll();
10767                    }
10768                    updateOomAdjLocked(r);
10769                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10770                            src.info.authority);
10771                }
10772            }
10773
10774            Binder.restoreCallingIdentity(origId);
10775        }
10776    }
10777
10778    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10779        ContentProviderConnection conn;
10780        try {
10781            conn = (ContentProviderConnection)connection;
10782        } catch (ClassCastException e) {
10783            String msg ="refContentProvider: " + connection
10784                    + " not a ContentProviderConnection";
10785            Slog.w(TAG, msg);
10786            throw new IllegalArgumentException(msg);
10787        }
10788        if (conn == null) {
10789            throw new NullPointerException("connection is null");
10790        }
10791
10792        synchronized (this) {
10793            if (stable > 0) {
10794                conn.numStableIncs += stable;
10795            }
10796            stable = conn.stableCount + stable;
10797            if (stable < 0) {
10798                throw new IllegalStateException("stableCount < 0: " + stable);
10799            }
10800
10801            if (unstable > 0) {
10802                conn.numUnstableIncs += unstable;
10803            }
10804            unstable = conn.unstableCount + unstable;
10805            if (unstable < 0) {
10806                throw new IllegalStateException("unstableCount < 0: " + unstable);
10807            }
10808
10809            if ((stable+unstable) <= 0) {
10810                throw new IllegalStateException("ref counts can't go to zero here: stable="
10811                        + stable + " unstable=" + unstable);
10812            }
10813            conn.stableCount = stable;
10814            conn.unstableCount = unstable;
10815            return !conn.dead;
10816        }
10817    }
10818
10819    public void unstableProviderDied(IBinder connection) {
10820        ContentProviderConnection conn;
10821        try {
10822            conn = (ContentProviderConnection)connection;
10823        } catch (ClassCastException e) {
10824            String msg ="refContentProvider: " + connection
10825                    + " not a ContentProviderConnection";
10826            Slog.w(TAG, msg);
10827            throw new IllegalArgumentException(msg);
10828        }
10829        if (conn == null) {
10830            throw new NullPointerException("connection is null");
10831        }
10832
10833        // Safely retrieve the content provider associated with the connection.
10834        IContentProvider provider;
10835        synchronized (this) {
10836            provider = conn.provider.provider;
10837        }
10838
10839        if (provider == null) {
10840            // Um, yeah, we're way ahead of you.
10841            return;
10842        }
10843
10844        // Make sure the caller is being honest with us.
10845        if (provider.asBinder().pingBinder()) {
10846            // Er, no, still looks good to us.
10847            synchronized (this) {
10848                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10849                        + " says " + conn + " died, but we don't agree");
10850                return;
10851            }
10852        }
10853
10854        // Well look at that!  It's dead!
10855        synchronized (this) {
10856            if (conn.provider.provider != provider) {
10857                // But something changed...  good enough.
10858                return;
10859            }
10860
10861            ProcessRecord proc = conn.provider.proc;
10862            if (proc == null || proc.thread == null) {
10863                // Seems like the process is already cleaned up.
10864                return;
10865            }
10866
10867            // As far as we're concerned, this is just like receiving a
10868            // death notification...  just a bit prematurely.
10869            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10870                    + ") early provider death");
10871            final long ident = Binder.clearCallingIdentity();
10872            try {
10873                appDiedLocked(proc);
10874            } finally {
10875                Binder.restoreCallingIdentity(ident);
10876            }
10877        }
10878    }
10879
10880    @Override
10881    public void appNotRespondingViaProvider(IBinder connection) {
10882        enforceCallingPermission(
10883                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10884
10885        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10886        if (conn == null) {
10887            Slog.w(TAG, "ContentProviderConnection is null");
10888            return;
10889        }
10890
10891        final ProcessRecord host = conn.provider.proc;
10892        if (host == null) {
10893            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10894            return;
10895        }
10896
10897        mHandler.post(new Runnable() {
10898            @Override
10899            public void run() {
10900                mAppErrors.appNotResponding(host, null, null, false,
10901                        "ContentProvider not responding");
10902            }
10903        });
10904    }
10905
10906    public final void installSystemProviders() {
10907        List<ProviderInfo> providers;
10908        synchronized (this) {
10909            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10910            providers = generateApplicationProvidersLocked(app);
10911            if (providers != null) {
10912                for (int i=providers.size()-1; i>=0; i--) {
10913                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10914                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10915                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10916                                + ": not system .apk");
10917                        providers.remove(i);
10918                    }
10919                }
10920            }
10921        }
10922        if (providers != null) {
10923            mSystemThread.installSystemProviders(providers);
10924        }
10925
10926        mCoreSettingsObserver = new CoreSettingsObserver(this);
10927        mFontScaleSettingObserver = new FontScaleSettingObserver();
10928
10929        //mUsageStatsService.monitorPackages();
10930    }
10931
10932    private void startPersistentApps(int matchFlags) {
10933        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
10934
10935        synchronized (this) {
10936            try {
10937                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
10938                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
10939                for (ApplicationInfo app : apps) {
10940                    if (!"android".equals(app.packageName)) {
10941                        addAppLocked(app, false, null /* ABI override */);
10942                    }
10943                }
10944            } catch (RemoteException ex) {
10945            }
10946        }
10947    }
10948
10949    /**
10950     * When a user is unlocked, we need to install encryption-unaware providers
10951     * belonging to any running apps.
10952     */
10953    private void installEncryptionUnawareProviders(int userId) {
10954        if (!StorageManager.isFileEncryptedNativeOrEmulated()) {
10955            // TODO: eventually pivot this back to look at current user state,
10956            // similar to the comment in UserManager.isUserUnlocked(), but for
10957            // now, if we started apps when "unlocked" then unaware providers
10958            // have already been spun up.
10959            return;
10960        }
10961
10962        // We're only interested in providers that are encryption unaware, and
10963        // we don't care about uninstalled apps, since there's no way they're
10964        // running at this point.
10965        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
10966
10967        synchronized (this) {
10968            final int NP = mProcessNames.getMap().size();
10969            for (int ip = 0; ip < NP; ip++) {
10970                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10971                final int NA = apps.size();
10972                for (int ia = 0; ia < NA; ia++) {
10973                    final ProcessRecord app = apps.valueAt(ia);
10974                    if (app.userId != userId || app.thread == null) continue;
10975
10976                    final int NG = app.pkgList.size();
10977                    for (int ig = 0; ig < NG; ig++) {
10978                        try {
10979                            final String pkgName = app.pkgList.keyAt(ig);
10980                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
10981                                    .getPackageInfo(pkgName, matchFlags, userId);
10982                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
10983                                for (ProviderInfo provInfo : pkgInfo.providers) {
10984                                    Log.v(TAG, "Installing " + provInfo);
10985                                    app.thread.scheduleInstallProvider(provInfo);
10986                                }
10987                            }
10988                        } catch (RemoteException ignored) {
10989                        }
10990                    }
10991                }
10992            }
10993        }
10994    }
10995
10996    /**
10997     * Allows apps to retrieve the MIME type of a URI.
10998     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10999     * users, then it does not need permission to access the ContentProvider.
11000     * Either, it needs cross-user uri grants.
11001     *
11002     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11003     *
11004     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11005     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11006     */
11007    public String getProviderMimeType(Uri uri, int userId) {
11008        enforceNotIsolatedCaller("getProviderMimeType");
11009        final String name = uri.getAuthority();
11010        int callingUid = Binder.getCallingUid();
11011        int callingPid = Binder.getCallingPid();
11012        long ident = 0;
11013        boolean clearedIdentity = false;
11014        synchronized (this) {
11015            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11016        }
11017        if (canClearIdentity(callingPid, callingUid, userId)) {
11018            clearedIdentity = true;
11019            ident = Binder.clearCallingIdentity();
11020        }
11021        ContentProviderHolder holder = null;
11022        try {
11023            holder = getContentProviderExternalUnchecked(name, null, userId);
11024            if (holder != null) {
11025                return holder.provider.getType(uri);
11026            }
11027        } catch (RemoteException e) {
11028            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11029            return null;
11030        } finally {
11031            // We need to clear the identity to call removeContentProviderExternalUnchecked
11032            if (!clearedIdentity) {
11033                ident = Binder.clearCallingIdentity();
11034            }
11035            try {
11036                if (holder != null) {
11037                    removeContentProviderExternalUnchecked(name, null, userId);
11038                }
11039            } finally {
11040                Binder.restoreCallingIdentity(ident);
11041            }
11042        }
11043
11044        return null;
11045    }
11046
11047    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11048        if (UserHandle.getUserId(callingUid) == userId) {
11049            return true;
11050        }
11051        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11052                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11053                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11054                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11055                return true;
11056        }
11057        return false;
11058    }
11059
11060    // =========================================================
11061    // GLOBAL MANAGEMENT
11062    // =========================================================
11063
11064    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11065            boolean isolated, int isolatedUid) {
11066        String proc = customProcess != null ? customProcess : info.processName;
11067        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11068        final int userId = UserHandle.getUserId(info.uid);
11069        int uid = info.uid;
11070        if (isolated) {
11071            if (isolatedUid == 0) {
11072                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11073                while (true) {
11074                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11075                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11076                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11077                    }
11078                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11079                    mNextIsolatedProcessUid++;
11080                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11081                        // No process for this uid, use it.
11082                        break;
11083                    }
11084                    stepsLeft--;
11085                    if (stepsLeft <= 0) {
11086                        return null;
11087                    }
11088                }
11089            } else {
11090                // Special case for startIsolatedProcess (internal only), where
11091                // the uid of the isolated process is specified by the caller.
11092                uid = isolatedUid;
11093            }
11094        }
11095        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11096        if (!mBooted && !mBooting
11097                && userId == UserHandle.USER_SYSTEM
11098                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11099            r.persistent = true;
11100        }
11101        addProcessNameLocked(r);
11102        return r;
11103    }
11104
11105    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11106            String abiOverride) {
11107        ProcessRecord app;
11108        if (!isolated) {
11109            app = getProcessRecordLocked(info.processName, info.uid, true);
11110        } else {
11111            app = null;
11112        }
11113
11114        if (app == null) {
11115            app = newProcessRecordLocked(info, null, isolated, 0);
11116            updateLruProcessLocked(app, false, null);
11117            updateOomAdjLocked();
11118        }
11119
11120        // This package really, really can not be stopped.
11121        try {
11122            AppGlobals.getPackageManager().setPackageStoppedState(
11123                    info.packageName, false, UserHandle.getUserId(app.uid));
11124        } catch (RemoteException e) {
11125        } catch (IllegalArgumentException e) {
11126            Slog.w(TAG, "Failed trying to unstop package "
11127                    + info.packageName + ": " + e);
11128        }
11129
11130        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11131            app.persistent = true;
11132            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11133        }
11134        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11135            mPersistentStartingProcesses.add(app);
11136            startProcessLocked(app, "added application", app.processName, abiOverride,
11137                    null /* entryPoint */, null /* entryPointArgs */);
11138        }
11139
11140        return app;
11141    }
11142
11143    public void unhandledBack() {
11144        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11145                "unhandledBack()");
11146
11147        synchronized(this) {
11148            final long origId = Binder.clearCallingIdentity();
11149            try {
11150                getFocusedStack().unhandledBackLocked();
11151            } finally {
11152                Binder.restoreCallingIdentity(origId);
11153            }
11154        }
11155    }
11156
11157    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11158        enforceNotIsolatedCaller("openContentUri");
11159        final int userId = UserHandle.getCallingUserId();
11160        String name = uri.getAuthority();
11161        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11162        ParcelFileDescriptor pfd = null;
11163        if (cph != null) {
11164            // We record the binder invoker's uid in thread-local storage before
11165            // going to the content provider to open the file.  Later, in the code
11166            // that handles all permissions checks, we look for this uid and use
11167            // that rather than the Activity Manager's own uid.  The effect is that
11168            // we do the check against the caller's permissions even though it looks
11169            // to the content provider like the Activity Manager itself is making
11170            // the request.
11171            Binder token = new Binder();
11172            sCallerIdentity.set(new Identity(
11173                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11174            try {
11175                pfd = cph.provider.openFile(null, uri, "r", null, token);
11176            } catch (FileNotFoundException e) {
11177                // do nothing; pfd will be returned null
11178            } finally {
11179                // Ensure that whatever happens, we clean up the identity state
11180                sCallerIdentity.remove();
11181                // Ensure we're done with the provider.
11182                removeContentProviderExternalUnchecked(name, null, userId);
11183            }
11184        } else {
11185            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11186        }
11187        return pfd;
11188    }
11189
11190    // Actually is sleeping or shutting down or whatever else in the future
11191    // is an inactive state.
11192    public boolean isSleepingOrShuttingDown() {
11193        return isSleeping() || mShuttingDown;
11194    }
11195
11196    public boolean isSleeping() {
11197        return mSleeping;
11198    }
11199
11200    void onWakefulnessChanged(int wakefulness) {
11201        synchronized(this) {
11202            mWakefulness = wakefulness;
11203            updateSleepIfNeededLocked();
11204        }
11205    }
11206
11207    void finishRunningVoiceLocked() {
11208        if (mRunningVoice != null) {
11209            mRunningVoice = null;
11210            mVoiceWakeLock.release();
11211            updateSleepIfNeededLocked();
11212        }
11213    }
11214
11215    void startTimeTrackingFocusedActivityLocked() {
11216        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11217            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11218        }
11219    }
11220
11221    void updateSleepIfNeededLocked() {
11222        if (mSleeping && !shouldSleepLocked()) {
11223            mSleeping = false;
11224            startTimeTrackingFocusedActivityLocked();
11225            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11226            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11227            updateOomAdjLocked();
11228        } else if (!mSleeping && shouldSleepLocked()) {
11229            mSleeping = true;
11230            if (mCurAppTimeTracker != null) {
11231                mCurAppTimeTracker.stop();
11232            }
11233            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11234            mStackSupervisor.goingToSleepLocked();
11235            updateOomAdjLocked();
11236
11237            // Initialize the wake times of all processes.
11238            checkExcessivePowerUsageLocked(false);
11239            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11240            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11241            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11242        }
11243    }
11244
11245    private boolean shouldSleepLocked() {
11246        // Resume applications while running a voice interactor.
11247        if (mRunningVoice != null) {
11248            return false;
11249        }
11250
11251        // TODO: Transform the lock screen state into a sleep token instead.
11252        switch (mWakefulness) {
11253            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11254            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11255            case PowerManagerInternal.WAKEFULNESS_DOZING:
11256                // Pause applications whenever the lock screen is shown or any sleep
11257                // tokens have been acquired.
11258                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11259            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11260            default:
11261                // If we're asleep then pause applications unconditionally.
11262                return true;
11263        }
11264    }
11265
11266    /** Pokes the task persister. */
11267    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11268        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11269    }
11270
11271    /** Notifies all listeners when the task stack has changed. */
11272    void notifyTaskStackChangedLocked() {
11273        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11274        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11275        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11276        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11277    }
11278
11279    /** Notifies all listeners when an Activity is pinned. */
11280    void notifyActivityPinnedLocked() {
11281        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11282        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11283    }
11284
11285    /**
11286     * Notifies all listeners when an attempt was made to start an an activity that is already
11287     * running in the pinned stack and the activity was not actually started, but the task is
11288     * either brought to the front or a new Intent is delivered to it.
11289     */
11290    void notifyPinnedActivityRestartAttemptLocked() {
11291        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11292        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11293    }
11294
11295    /** Notifies all listeners when the pinned stack animation ends. */
11296    @Override
11297    public void notifyPinnedStackAnimationEnded() {
11298        synchronized (this) {
11299            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11300            mHandler.obtainMessage(
11301                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11302        }
11303    }
11304
11305    @Override
11306    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11307        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11308    }
11309
11310    @Override
11311    public boolean shutdown(int timeout) {
11312        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11313                != PackageManager.PERMISSION_GRANTED) {
11314            throw new SecurityException("Requires permission "
11315                    + android.Manifest.permission.SHUTDOWN);
11316        }
11317
11318        boolean timedout = false;
11319
11320        synchronized(this) {
11321            mShuttingDown = true;
11322            updateEventDispatchingLocked();
11323            timedout = mStackSupervisor.shutdownLocked(timeout);
11324        }
11325
11326        mAppOpsService.shutdown();
11327        if (mUsageStatsService != null) {
11328            mUsageStatsService.prepareShutdown();
11329        }
11330        mBatteryStatsService.shutdown();
11331        synchronized (this) {
11332            mProcessStats.shutdownLocked();
11333            notifyTaskPersisterLocked(null, true);
11334        }
11335
11336        return timedout;
11337    }
11338
11339    public final void activitySlept(IBinder token) {
11340        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11341
11342        final long origId = Binder.clearCallingIdentity();
11343
11344        synchronized (this) {
11345            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11346            if (r != null) {
11347                mStackSupervisor.activitySleptLocked(r);
11348            }
11349        }
11350
11351        Binder.restoreCallingIdentity(origId);
11352    }
11353
11354    private String lockScreenShownToString() {
11355        switch (mLockScreenShown) {
11356            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11357            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11358            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11359            default: return "Unknown=" + mLockScreenShown;
11360        }
11361    }
11362
11363    void logLockScreen(String msg) {
11364        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11365                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11366                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11367                + " mSleeping=" + mSleeping);
11368    }
11369
11370    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11371        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11372        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11373        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11374            boolean wasRunningVoice = mRunningVoice != null;
11375            mRunningVoice = session;
11376            if (!wasRunningVoice) {
11377                mVoiceWakeLock.acquire();
11378                updateSleepIfNeededLocked();
11379            }
11380        }
11381    }
11382
11383    private void updateEventDispatchingLocked() {
11384        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11385    }
11386
11387    public void setLockScreenShown(boolean shown) {
11388        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11389                != PackageManager.PERMISSION_GRANTED) {
11390            throw new SecurityException("Requires permission "
11391                    + android.Manifest.permission.DEVICE_POWER);
11392        }
11393
11394        synchronized(this) {
11395            long ident = Binder.clearCallingIdentity();
11396            try {
11397                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11398                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11399                updateSleepIfNeededLocked();
11400            } finally {
11401                Binder.restoreCallingIdentity(ident);
11402            }
11403        }
11404    }
11405
11406    @Override
11407    public void notifyLockedProfile(@UserIdInt int userId) {
11408        try {
11409            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11410                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11411            }
11412        } catch (RemoteException ex) {
11413            throw new SecurityException("Fail to check is caller a privileged app", ex);
11414        }
11415
11416        synchronized (this) {
11417            if (mStackSupervisor.isFocusedUserLockedProfile()) {
11418                final long ident = Binder.clearCallingIdentity();
11419                try {
11420                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11421                    startHomeActivityLocked(currentUserId, "notifyProfileLocked");
11422                } finally {
11423                    Binder.restoreCallingIdentity(ident);
11424                }
11425            }
11426        }
11427    }
11428
11429    @Override
11430    public void stopAppSwitches() {
11431        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11432                != PackageManager.PERMISSION_GRANTED) {
11433            throw new SecurityException("viewquires permission "
11434                    + android.Manifest.permission.STOP_APP_SWITCHES);
11435        }
11436
11437        synchronized(this) {
11438            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11439                    + APP_SWITCH_DELAY_TIME;
11440            mDidAppSwitch = false;
11441            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11442            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11443            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11444        }
11445    }
11446
11447    public void resumeAppSwitches() {
11448        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11449                != PackageManager.PERMISSION_GRANTED) {
11450            throw new SecurityException("Requires permission "
11451                    + android.Manifest.permission.STOP_APP_SWITCHES);
11452        }
11453
11454        synchronized(this) {
11455            // Note that we don't execute any pending app switches... we will
11456            // let those wait until either the timeout, or the next start
11457            // activity request.
11458            mAppSwitchesAllowedTime = 0;
11459        }
11460    }
11461
11462    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11463            int callingPid, int callingUid, String name) {
11464        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11465            return true;
11466        }
11467
11468        int perm = checkComponentPermission(
11469                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11470                sourceUid, -1, true);
11471        if (perm == PackageManager.PERMISSION_GRANTED) {
11472            return true;
11473        }
11474
11475        // If the actual IPC caller is different from the logical source, then
11476        // also see if they are allowed to control app switches.
11477        if (callingUid != -1 && callingUid != sourceUid) {
11478            perm = checkComponentPermission(
11479                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11480                    callingUid, -1, true);
11481            if (perm == PackageManager.PERMISSION_GRANTED) {
11482                return true;
11483            }
11484        }
11485
11486        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11487        return false;
11488    }
11489
11490    public void setDebugApp(String packageName, boolean waitForDebugger,
11491            boolean persistent) {
11492        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11493                "setDebugApp()");
11494
11495        long ident = Binder.clearCallingIdentity();
11496        try {
11497            // Note that this is not really thread safe if there are multiple
11498            // callers into it at the same time, but that's not a situation we
11499            // care about.
11500            if (persistent) {
11501                final ContentResolver resolver = mContext.getContentResolver();
11502                Settings.Global.putString(
11503                    resolver, Settings.Global.DEBUG_APP,
11504                    packageName);
11505                Settings.Global.putInt(
11506                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11507                    waitForDebugger ? 1 : 0);
11508            }
11509
11510            synchronized (this) {
11511                if (!persistent) {
11512                    mOrigDebugApp = mDebugApp;
11513                    mOrigWaitForDebugger = mWaitForDebugger;
11514                }
11515                mDebugApp = packageName;
11516                mWaitForDebugger = waitForDebugger;
11517                mDebugTransient = !persistent;
11518                if (packageName != null) {
11519                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11520                            false, UserHandle.USER_ALL, "set debug app");
11521                }
11522            }
11523        } finally {
11524            Binder.restoreCallingIdentity(ident);
11525        }
11526    }
11527
11528    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11529        synchronized (this) {
11530            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11531            if (!isDebuggable) {
11532                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11533                    throw new SecurityException("Process not debuggable: " + app.packageName);
11534                }
11535            }
11536
11537            mTrackAllocationApp = processName;
11538        }
11539    }
11540
11541    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11542        synchronized (this) {
11543            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11544            if (!isDebuggable) {
11545                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11546                    throw new SecurityException("Process not debuggable: " + app.packageName);
11547                }
11548            }
11549            mProfileApp = processName;
11550            mProfileFile = profilerInfo.profileFile;
11551            if (mProfileFd != null) {
11552                try {
11553                    mProfileFd.close();
11554                } catch (IOException e) {
11555                }
11556                mProfileFd = null;
11557            }
11558            mProfileFd = profilerInfo.profileFd;
11559            mSamplingInterval = profilerInfo.samplingInterval;
11560            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11561            mProfileType = 0;
11562        }
11563    }
11564
11565    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11566        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11567        if (!isDebuggable) {
11568            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11569                throw new SecurityException("Process not debuggable: " + app.packageName);
11570            }
11571        }
11572        mNativeDebuggingApp = processName;
11573    }
11574
11575    @Override
11576    public void setAlwaysFinish(boolean enabled) {
11577        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11578                "setAlwaysFinish()");
11579
11580        long ident = Binder.clearCallingIdentity();
11581        try {
11582            Settings.Global.putInt(
11583                    mContext.getContentResolver(),
11584                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11585
11586            synchronized (this) {
11587                mAlwaysFinishActivities = enabled;
11588            }
11589        } finally {
11590            Binder.restoreCallingIdentity(ident);
11591        }
11592    }
11593
11594    @Override
11595    public void setLenientBackgroundCheck(boolean enabled) {
11596        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11597                "setLenientBackgroundCheck()");
11598
11599        long ident = Binder.clearCallingIdentity();
11600        try {
11601            Settings.Global.putInt(
11602                    mContext.getContentResolver(),
11603                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11604
11605            synchronized (this) {
11606                mLenientBackgroundCheck = enabled;
11607            }
11608        } finally {
11609            Binder.restoreCallingIdentity(ident);
11610        }
11611    }
11612
11613    @Override
11614    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11615        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11616                "setActivityController()");
11617        synchronized (this) {
11618            mController = controller;
11619            mControllerIsAMonkey = imAMonkey;
11620            Watchdog.getInstance().setActivityController(controller);
11621        }
11622    }
11623
11624    @Override
11625    public void setUserIsMonkey(boolean userIsMonkey) {
11626        synchronized (this) {
11627            synchronized (mPidsSelfLocked) {
11628                final int callingPid = Binder.getCallingPid();
11629                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11630                if (precessRecord == null) {
11631                    throw new SecurityException("Unknown process: " + callingPid);
11632                }
11633                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11634                    throw new SecurityException("Only an instrumentation process "
11635                            + "with a UiAutomation can call setUserIsMonkey");
11636                }
11637            }
11638            mUserIsMonkey = userIsMonkey;
11639        }
11640    }
11641
11642    @Override
11643    public boolean isUserAMonkey() {
11644        synchronized (this) {
11645            // If there is a controller also implies the user is a monkey.
11646            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11647        }
11648    }
11649
11650    public void requestBugReport(int bugreportType) {
11651        String service = null;
11652        switch (bugreportType) {
11653            case ActivityManager.BUGREPORT_OPTION_FULL:
11654                service = "bugreport";
11655                break;
11656            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11657                service = "bugreportplus";
11658                break;
11659            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11660                service = "bugreportremote";
11661                break;
11662        }
11663        if (service == null) {
11664            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11665                    + bugreportType);
11666        }
11667        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11668        SystemProperties.set("ctl.start", service);
11669    }
11670
11671    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11672        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11673    }
11674
11675    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11676        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11677            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11678        }
11679        return KEY_DISPATCHING_TIMEOUT;
11680    }
11681
11682    @Override
11683    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11684        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11685                != PackageManager.PERMISSION_GRANTED) {
11686            throw new SecurityException("Requires permission "
11687                    + android.Manifest.permission.FILTER_EVENTS);
11688        }
11689        ProcessRecord proc;
11690        long timeout;
11691        synchronized (this) {
11692            synchronized (mPidsSelfLocked) {
11693                proc = mPidsSelfLocked.get(pid);
11694            }
11695            timeout = getInputDispatchingTimeoutLocked(proc);
11696        }
11697
11698        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11699            return -1;
11700        }
11701
11702        return timeout;
11703    }
11704
11705    /**
11706     * Handle input dispatching timeouts.
11707     * Returns whether input dispatching should be aborted or not.
11708     */
11709    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11710            final ActivityRecord activity, final ActivityRecord parent,
11711            final boolean aboveSystem, String reason) {
11712        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11713                != PackageManager.PERMISSION_GRANTED) {
11714            throw new SecurityException("Requires permission "
11715                    + android.Manifest.permission.FILTER_EVENTS);
11716        }
11717
11718        final String annotation;
11719        if (reason == null) {
11720            annotation = "Input dispatching timed out";
11721        } else {
11722            annotation = "Input dispatching timed out (" + reason + ")";
11723        }
11724
11725        if (proc != null) {
11726            synchronized (this) {
11727                if (proc.debugging) {
11728                    return false;
11729                }
11730
11731                if (mDidDexOpt) {
11732                    // Give more time since we were dexopting.
11733                    mDidDexOpt = false;
11734                    return false;
11735                }
11736
11737                if (proc.instrumentationClass != null) {
11738                    Bundle info = new Bundle();
11739                    info.putString("shortMsg", "keyDispatchingTimedOut");
11740                    info.putString("longMsg", annotation);
11741                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11742                    return true;
11743                }
11744            }
11745            mHandler.post(new Runnable() {
11746                @Override
11747                public void run() {
11748                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11749                }
11750            });
11751        }
11752
11753        return true;
11754    }
11755
11756    @Override
11757    public Bundle getAssistContextExtras(int requestType) {
11758        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11759                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11760        if (pae == null) {
11761            return null;
11762        }
11763        synchronized (pae) {
11764            while (!pae.haveResult) {
11765                try {
11766                    pae.wait();
11767                } catch (InterruptedException e) {
11768                }
11769            }
11770        }
11771        synchronized (this) {
11772            buildAssistBundleLocked(pae, pae.result);
11773            mPendingAssistExtras.remove(pae);
11774            mUiHandler.removeCallbacks(pae);
11775        }
11776        return pae.extras;
11777    }
11778
11779    @Override
11780    public boolean isAssistDataAllowedOnCurrentActivity() {
11781        int userId;
11782        synchronized (this) {
11783            userId = mUserController.getCurrentUserIdLocked();
11784            ActivityRecord activity = getFocusedStack().topActivity();
11785            if (activity == null) {
11786                return false;
11787            }
11788            userId = activity.userId;
11789        }
11790        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11791                Context.DEVICE_POLICY_SERVICE);
11792        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11793    }
11794
11795    @Override
11796    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11797        long ident = Binder.clearCallingIdentity();
11798        try {
11799            synchronized (this) {
11800                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11801                ActivityRecord top = getFocusedStack().topActivity();
11802                if (top != caller) {
11803                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11804                            + " is not current top " + top);
11805                    return false;
11806                }
11807                if (!top.nowVisible) {
11808                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11809                            + " is not visible");
11810                    return false;
11811                }
11812            }
11813            AssistUtils utils = new AssistUtils(mContext);
11814            return utils.showSessionForActiveService(args,
11815                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11816        } finally {
11817            Binder.restoreCallingIdentity(ident);
11818        }
11819    }
11820
11821    @Override
11822    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11823            IBinder activityToken) {
11824        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11825                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11826    }
11827
11828    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11829            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11830            long timeout) {
11831        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11832                "enqueueAssistContext()");
11833        synchronized (this) {
11834            ActivityRecord activity = getFocusedStack().topActivity();
11835            if (activity == null) {
11836                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11837                return null;
11838            }
11839            if (activity.app == null || activity.app.thread == null) {
11840                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11841                return null;
11842            }
11843            if (activityToken != null) {
11844                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11845                if (activity != caller) {
11846                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11847                            + " is not current top " + activity);
11848                    return null;
11849                }
11850            }
11851            PendingAssistExtras pae;
11852            Bundle extras = new Bundle();
11853            if (args != null) {
11854                extras.putAll(args);
11855            }
11856            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11857            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11858            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11859            try {
11860                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11861                        requestType);
11862                mPendingAssistExtras.add(pae);
11863                mUiHandler.postDelayed(pae, timeout);
11864            } catch (RemoteException e) {
11865                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11866                return null;
11867            }
11868            return pae;
11869        }
11870    }
11871
11872    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11873        IResultReceiver receiver;
11874        synchronized (this) {
11875            mPendingAssistExtras.remove(pae);
11876            receiver = pae.receiver;
11877        }
11878        if (receiver != null) {
11879            // Caller wants result sent back to them.
11880            try {
11881                pae.receiver.send(0, null);
11882            } catch (RemoteException e) {
11883            }
11884        }
11885    }
11886
11887    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11888        if (result != null) {
11889            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11890        }
11891        if (pae.hint != null) {
11892            pae.extras.putBoolean(pae.hint, true);
11893        }
11894    }
11895
11896    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11897            AssistContent content, Uri referrer) {
11898        PendingAssistExtras pae = (PendingAssistExtras)token;
11899        synchronized (pae) {
11900            pae.result = extras;
11901            pae.structure = structure;
11902            pae.content = content;
11903            if (referrer != null) {
11904                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11905            }
11906            pae.haveResult = true;
11907            pae.notifyAll();
11908            if (pae.intent == null && pae.receiver == null) {
11909                // Caller is just waiting for the result.
11910                return;
11911            }
11912        }
11913
11914        // We are now ready to launch the assist activity.
11915        IResultReceiver sendReceiver = null;
11916        Bundle sendBundle = null;
11917        synchronized (this) {
11918            buildAssistBundleLocked(pae, extras);
11919            boolean exists = mPendingAssistExtras.remove(pae);
11920            mUiHandler.removeCallbacks(pae);
11921            if (!exists) {
11922                // Timed out.
11923                return;
11924            }
11925            if ((sendReceiver=pae.receiver) != null) {
11926                // Caller wants result sent back to them.
11927                sendBundle = new Bundle();
11928                sendBundle.putBundle("data", pae.extras);
11929                sendBundle.putParcelable("structure", pae.structure);
11930                sendBundle.putParcelable("content", pae.content);
11931            }
11932        }
11933        if (sendReceiver != null) {
11934            try {
11935                sendReceiver.send(0, sendBundle);
11936            } catch (RemoteException e) {
11937            }
11938            return;
11939        }
11940
11941        long ident = Binder.clearCallingIdentity();
11942        try {
11943            pae.intent.replaceExtras(pae.extras);
11944            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11945                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
11946                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11947            closeSystemDialogs("assist");
11948            try {
11949                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11950            } catch (ActivityNotFoundException e) {
11951                Slog.w(TAG, "No activity to handle assist action.", e);
11952            }
11953        } finally {
11954            Binder.restoreCallingIdentity(ident);
11955        }
11956    }
11957
11958    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
11959            Bundle args) {
11960        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
11961                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
11962    }
11963
11964    public void registerProcessObserver(IProcessObserver observer) {
11965        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11966                "registerProcessObserver()");
11967        synchronized (this) {
11968            mProcessObservers.register(observer);
11969        }
11970    }
11971
11972    @Override
11973    public void unregisterProcessObserver(IProcessObserver observer) {
11974        synchronized (this) {
11975            mProcessObservers.unregister(observer);
11976        }
11977    }
11978
11979    @Override
11980    public void registerUidObserver(IUidObserver observer, int which) {
11981        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11982                "registerUidObserver()");
11983        synchronized (this) {
11984            mUidObservers.register(observer, which);
11985        }
11986    }
11987
11988    @Override
11989    public void unregisterUidObserver(IUidObserver observer) {
11990        synchronized (this) {
11991            mUidObservers.unregister(observer);
11992        }
11993    }
11994
11995    @Override
11996    public boolean convertFromTranslucent(IBinder token) {
11997        final long origId = Binder.clearCallingIdentity();
11998        try {
11999            synchronized (this) {
12000                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12001                if (r == null) {
12002                    return false;
12003                }
12004                final boolean translucentChanged = r.changeWindowTranslucency(true);
12005                if (translucentChanged) {
12006                    r.task.stack.releaseBackgroundResources(r);
12007                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12008                }
12009                mWindowManager.setAppFullscreen(token, true);
12010                return translucentChanged;
12011            }
12012        } finally {
12013            Binder.restoreCallingIdentity(origId);
12014        }
12015    }
12016
12017    @Override
12018    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12019        final long origId = Binder.clearCallingIdentity();
12020        try {
12021            synchronized (this) {
12022                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12023                if (r == null) {
12024                    return false;
12025                }
12026                int index = r.task.mActivities.lastIndexOf(r);
12027                if (index > 0) {
12028                    ActivityRecord under = r.task.mActivities.get(index - 1);
12029                    under.returningOptions = options;
12030                }
12031                final boolean translucentChanged = r.changeWindowTranslucency(false);
12032                if (translucentChanged) {
12033                    r.task.stack.convertActivityToTranslucent(r);
12034                }
12035                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12036                mWindowManager.setAppFullscreen(token, false);
12037                return translucentChanged;
12038            }
12039        } finally {
12040            Binder.restoreCallingIdentity(origId);
12041        }
12042    }
12043
12044    @Override
12045    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12046        final long origId = Binder.clearCallingIdentity();
12047        try {
12048            synchronized (this) {
12049                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12050                if (r != null) {
12051                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12052                }
12053            }
12054            return false;
12055        } finally {
12056            Binder.restoreCallingIdentity(origId);
12057        }
12058    }
12059
12060    @Override
12061    public boolean isBackgroundVisibleBehind(IBinder token) {
12062        final long origId = Binder.clearCallingIdentity();
12063        try {
12064            synchronized (this) {
12065                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12066                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12067                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12068                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12069                return visible;
12070            }
12071        } finally {
12072            Binder.restoreCallingIdentity(origId);
12073        }
12074    }
12075
12076    @Override
12077    public ActivityOptions getActivityOptions(IBinder token) {
12078        final long origId = Binder.clearCallingIdentity();
12079        try {
12080            synchronized (this) {
12081                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12082                if (r != null) {
12083                    final ActivityOptions activityOptions = r.pendingOptions;
12084                    r.pendingOptions = null;
12085                    return activityOptions;
12086                }
12087                return null;
12088            }
12089        } finally {
12090            Binder.restoreCallingIdentity(origId);
12091        }
12092    }
12093
12094    @Override
12095    public void setImmersive(IBinder token, boolean immersive) {
12096        synchronized(this) {
12097            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12098            if (r == null) {
12099                throw new IllegalArgumentException();
12100            }
12101            r.immersive = immersive;
12102
12103            // update associated state if we're frontmost
12104            if (r == mFocusedActivity) {
12105                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12106                applyUpdateLockStateLocked(r);
12107            }
12108        }
12109    }
12110
12111    @Override
12112    public boolean isImmersive(IBinder token) {
12113        synchronized (this) {
12114            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12115            if (r == null) {
12116                throw new IllegalArgumentException();
12117            }
12118            return r.immersive;
12119        }
12120    }
12121
12122    @Override
12123    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12124        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12125            throw new UnsupportedOperationException("VR mode not supported on this device!");
12126        }
12127
12128        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12129
12130        ActivityRecord r;
12131        synchronized (this) {
12132            r = ActivityRecord.isInStackLocked(token);
12133        }
12134
12135        if (r == null) {
12136            throw new IllegalArgumentException();
12137        }
12138
12139        int err;
12140        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12141                VrManagerInternal.NO_ERROR) {
12142            return err;
12143        }
12144
12145        synchronized(this) {
12146            r.requestedVrComponent = (enabled) ? packageName : null;
12147
12148            // Update associated state if this activity is currently focused
12149            if (r == mFocusedActivity) {
12150                applyUpdateVrModeLocked(r);
12151            }
12152            return 0;
12153        }
12154    }
12155
12156    @Override
12157    public boolean isVrModePackageEnabled(ComponentName packageName) {
12158        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12159            throw new UnsupportedOperationException("VR mode not supported on this device!");
12160        }
12161
12162        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12163
12164        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12165                VrManagerInternal.NO_ERROR;
12166    }
12167
12168    public boolean isTopActivityImmersive() {
12169        enforceNotIsolatedCaller("startActivity");
12170        synchronized (this) {
12171            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12172            return (r != null) ? r.immersive : false;
12173        }
12174    }
12175
12176    @Override
12177    public boolean isTopOfTask(IBinder token) {
12178        synchronized (this) {
12179            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12180            if (r == null) {
12181                throw new IllegalArgumentException();
12182            }
12183            return r.task.getTopActivity() == r;
12184        }
12185    }
12186
12187    public final void enterSafeMode() {
12188        synchronized(this) {
12189            // It only makes sense to do this before the system is ready
12190            // and started launching other packages.
12191            if (!mSystemReady) {
12192                try {
12193                    AppGlobals.getPackageManager().enterSafeMode();
12194                } catch (RemoteException e) {
12195                }
12196            }
12197
12198            mSafeMode = true;
12199        }
12200    }
12201
12202    public final void showSafeModeOverlay() {
12203        View v = LayoutInflater.from(mContext).inflate(
12204                com.android.internal.R.layout.safe_mode, null);
12205        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12206        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12207        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12208        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12209        lp.gravity = Gravity.BOTTOM | Gravity.START;
12210        lp.format = v.getBackground().getOpacity();
12211        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12212                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12213        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12214        ((WindowManager)mContext.getSystemService(
12215                Context.WINDOW_SERVICE)).addView(v, lp);
12216    }
12217
12218    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12219        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12220            return;
12221        }
12222        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12223        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12224        synchronized (stats) {
12225            if (mBatteryStatsService.isOnBattery()) {
12226                mBatteryStatsService.enforceCallingPermission();
12227                int MY_UID = Binder.getCallingUid();
12228                final int uid;
12229                if (sender == null) {
12230                    uid = sourceUid;
12231                } else {
12232                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12233                }
12234                BatteryStatsImpl.Uid.Pkg pkg =
12235                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12236                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12237                pkg.noteWakeupAlarmLocked(tag);
12238            }
12239        }
12240    }
12241
12242    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12243        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12244            return;
12245        }
12246        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12247        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12248        synchronized (stats) {
12249            mBatteryStatsService.enforceCallingPermission();
12250            int MY_UID = Binder.getCallingUid();
12251            final int uid;
12252            if (sender == null) {
12253                uid = sourceUid;
12254            } else {
12255                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12256            }
12257            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12258        }
12259    }
12260
12261    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12262        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12263            return;
12264        }
12265        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12266        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12267        synchronized (stats) {
12268            mBatteryStatsService.enforceCallingPermission();
12269            int MY_UID = Binder.getCallingUid();
12270            final int uid;
12271            if (sender == null) {
12272                uid = sourceUid;
12273            } else {
12274                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12275            }
12276            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12277        }
12278    }
12279
12280    public boolean killPids(int[] pids, String pReason, boolean secure) {
12281        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12282            throw new SecurityException("killPids only available to the system");
12283        }
12284        String reason = (pReason == null) ? "Unknown" : pReason;
12285        // XXX Note: don't acquire main activity lock here, because the window
12286        // manager calls in with its locks held.
12287
12288        boolean killed = false;
12289        synchronized (mPidsSelfLocked) {
12290            int worstType = 0;
12291            for (int i=0; i<pids.length; i++) {
12292                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12293                if (proc != null) {
12294                    int type = proc.setAdj;
12295                    if (type > worstType) {
12296                        worstType = type;
12297                    }
12298                }
12299            }
12300
12301            // If the worst oom_adj is somewhere in the cached proc LRU range,
12302            // then constrain it so we will kill all cached procs.
12303            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12304                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12305                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12306            }
12307
12308            // If this is not a secure call, don't let it kill processes that
12309            // are important.
12310            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12311                worstType = ProcessList.SERVICE_ADJ;
12312            }
12313
12314            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12315            for (int i=0; i<pids.length; i++) {
12316                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12317                if (proc == null) {
12318                    continue;
12319                }
12320                int adj = proc.setAdj;
12321                if (adj >= worstType && !proc.killedByAm) {
12322                    proc.kill(reason, true);
12323                    killed = true;
12324                }
12325            }
12326        }
12327        return killed;
12328    }
12329
12330    @Override
12331    public void killUid(int appId, int userId, String reason) {
12332        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12333        synchronized (this) {
12334            final long identity = Binder.clearCallingIdentity();
12335            try {
12336                killPackageProcessesLocked(null, appId, userId,
12337                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12338                        reason != null ? reason : "kill uid");
12339            } finally {
12340                Binder.restoreCallingIdentity(identity);
12341            }
12342        }
12343    }
12344
12345    @Override
12346    public boolean killProcessesBelowForeground(String reason) {
12347        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12348            throw new SecurityException("killProcessesBelowForeground() only available to system");
12349        }
12350
12351        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12352    }
12353
12354    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12355        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12356            throw new SecurityException("killProcessesBelowAdj() only available to system");
12357        }
12358
12359        boolean killed = false;
12360        synchronized (mPidsSelfLocked) {
12361            final int size = mPidsSelfLocked.size();
12362            for (int i = 0; i < size; i++) {
12363                final int pid = mPidsSelfLocked.keyAt(i);
12364                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12365                if (proc == null) continue;
12366
12367                final int adj = proc.setAdj;
12368                if (adj > belowAdj && !proc.killedByAm) {
12369                    proc.kill(reason, true);
12370                    killed = true;
12371                }
12372            }
12373        }
12374        return killed;
12375    }
12376
12377    @Override
12378    public void hang(final IBinder who, boolean allowRestart) {
12379        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12380                != PackageManager.PERMISSION_GRANTED) {
12381            throw new SecurityException("Requires permission "
12382                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12383        }
12384
12385        final IBinder.DeathRecipient death = new DeathRecipient() {
12386            @Override
12387            public void binderDied() {
12388                synchronized (this) {
12389                    notifyAll();
12390                }
12391            }
12392        };
12393
12394        try {
12395            who.linkToDeath(death, 0);
12396        } catch (RemoteException e) {
12397            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12398            return;
12399        }
12400
12401        synchronized (this) {
12402            Watchdog.getInstance().setAllowRestart(allowRestart);
12403            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12404            synchronized (death) {
12405                while (who.isBinderAlive()) {
12406                    try {
12407                        death.wait();
12408                    } catch (InterruptedException e) {
12409                    }
12410                }
12411            }
12412            Watchdog.getInstance().setAllowRestart(true);
12413        }
12414    }
12415
12416    @Override
12417    public void restart() {
12418        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12419                != PackageManager.PERMISSION_GRANTED) {
12420            throw new SecurityException("Requires permission "
12421                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12422        }
12423
12424        Log.i(TAG, "Sending shutdown broadcast...");
12425
12426        BroadcastReceiver br = new BroadcastReceiver() {
12427            @Override public void onReceive(Context context, Intent intent) {
12428                // Now the broadcast is done, finish up the low-level shutdown.
12429                Log.i(TAG, "Shutting down activity manager...");
12430                shutdown(10000);
12431                Log.i(TAG, "Shutdown complete, restarting!");
12432                Process.killProcess(Process.myPid());
12433                System.exit(10);
12434            }
12435        };
12436
12437        // First send the high-level shut down broadcast.
12438        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12439        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12440        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12441        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12442        mContext.sendOrderedBroadcastAsUser(intent,
12443                UserHandle.ALL, null, br, mHandler, 0, null, null);
12444        */
12445        br.onReceive(mContext, intent);
12446    }
12447
12448    private long getLowRamTimeSinceIdle(long now) {
12449        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12450    }
12451
12452    @Override
12453    public void performIdleMaintenance() {
12454        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12455                != PackageManager.PERMISSION_GRANTED) {
12456            throw new SecurityException("Requires permission "
12457                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12458        }
12459
12460        synchronized (this) {
12461            final long now = SystemClock.uptimeMillis();
12462            final long timeSinceLastIdle = now - mLastIdleTime;
12463            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12464            mLastIdleTime = now;
12465            mLowRamTimeSinceLastIdle = 0;
12466            if (mLowRamStartTime != 0) {
12467                mLowRamStartTime = now;
12468            }
12469
12470            StringBuilder sb = new StringBuilder(128);
12471            sb.append("Idle maintenance over ");
12472            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12473            sb.append(" low RAM for ");
12474            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12475            Slog.i(TAG, sb.toString());
12476
12477            // If at least 1/3 of our time since the last idle period has been spent
12478            // with RAM low, then we want to kill processes.
12479            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12480
12481            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12482                ProcessRecord proc = mLruProcesses.get(i);
12483                if (proc.notCachedSinceIdle) {
12484                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12485                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12486                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12487                        if (doKilling && proc.initialIdlePss != 0
12488                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12489                            sb = new StringBuilder(128);
12490                            sb.append("Kill");
12491                            sb.append(proc.processName);
12492                            sb.append(" in idle maint: pss=");
12493                            sb.append(proc.lastPss);
12494                            sb.append(", swapPss=");
12495                            sb.append(proc.lastSwapPss);
12496                            sb.append(", initialPss=");
12497                            sb.append(proc.initialIdlePss);
12498                            sb.append(", period=");
12499                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12500                            sb.append(", lowRamPeriod=");
12501                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12502                            Slog.wtfQuiet(TAG, sb.toString());
12503                            proc.kill("idle maint (pss " + proc.lastPss
12504                                    + " from " + proc.initialIdlePss + ")", true);
12505                        }
12506                    }
12507                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12508                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12509                    proc.notCachedSinceIdle = true;
12510                    proc.initialIdlePss = 0;
12511                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12512                            mTestPssMode, isSleeping(), now);
12513                }
12514            }
12515
12516            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12517            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12518        }
12519    }
12520
12521    private void retrieveSettings() {
12522        final ContentResolver resolver = mContext.getContentResolver();
12523        final boolean freeformWindowManagement =
12524                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12525                        || Settings.Global.getInt(
12526                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12527        final boolean supportsPictureInPicture =
12528                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12529
12530        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12531        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12532        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12533        final boolean alwaysFinishActivities =
12534                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12535        final boolean lenientBackgroundCheck =
12536                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12537        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12538        final boolean forceResizable = Settings.Global.getInt(
12539                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12540        // Transfer any global setting for forcing RTL layout, into a System Property
12541        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12542
12543        final Configuration configuration = new Configuration();
12544        Settings.System.getConfiguration(resolver, configuration);
12545        if (forceRtl) {
12546            // This will take care of setting the correct layout direction flags
12547            configuration.setLayoutDirection(configuration.locale);
12548        }
12549
12550        synchronized (this) {
12551            mDebugApp = mOrigDebugApp = debugApp;
12552            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12553            mAlwaysFinishActivities = alwaysFinishActivities;
12554            mLenientBackgroundCheck = lenientBackgroundCheck;
12555            mForceResizableActivities = forceResizable;
12556            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12557            if (supportsMultiWindow || forceResizable) {
12558                mSupportsMultiWindow = true;
12559                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12560                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12561            } else {
12562                mSupportsMultiWindow = false;
12563                mSupportsFreeformWindowManagement = false;
12564                mSupportsPictureInPicture = false;
12565            }
12566            // This happens before any activities are started, so we can
12567            // change mConfiguration in-place.
12568            updateConfigurationLocked(configuration, null, true);
12569            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12570                    "Initial config: " + mConfiguration);
12571
12572            // Load resources only after the current configuration has been set.
12573            final Resources res = mContext.getResources();
12574            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12575            mThumbnailWidth = res.getDimensionPixelSize(
12576                    com.android.internal.R.dimen.thumbnail_width);
12577            mThumbnailHeight = res.getDimensionPixelSize(
12578                    com.android.internal.R.dimen.thumbnail_height);
12579            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12580                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12581            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12582                    com.android.internal.R.string.config_appsNotReportingCrashes));
12583        }
12584    }
12585
12586    public boolean testIsSystemReady() {
12587        // no need to synchronize(this) just to read & return the value
12588        return mSystemReady;
12589    }
12590
12591    private static File getCalledPreBootReceiversFile() {
12592        File dataDir = Environment.getDataDirectory();
12593        File systemDir = new File(dataDir, "system");
12594        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
12595        return fname;
12596    }
12597
12598    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
12599        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
12600        File file = getCalledPreBootReceiversFile();
12601        FileInputStream fis = null;
12602        try {
12603            fis = new FileInputStream(file);
12604            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
12605            int fvers = dis.readInt();
12606            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
12607                String vers = dis.readUTF();
12608                String codename = dis.readUTF();
12609                String build = dis.readUTF();
12610                if (android.os.Build.VERSION.RELEASE.equals(vers)
12611                        && android.os.Build.VERSION.CODENAME.equals(codename)
12612                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
12613                    int num = dis.readInt();
12614                    while (num > 0) {
12615                        num--;
12616                        String pkg = dis.readUTF();
12617                        String cls = dis.readUTF();
12618                        lastDoneReceivers.add(new ComponentName(pkg, cls));
12619                    }
12620                }
12621            }
12622        } catch (FileNotFoundException e) {
12623        } catch (IOException e) {
12624            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
12625        } finally {
12626            if (fis != null) {
12627                try {
12628                    fis.close();
12629                } catch (IOException e) {
12630                }
12631            }
12632        }
12633        return lastDoneReceivers;
12634    }
12635
12636    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
12637        File file = getCalledPreBootReceiversFile();
12638        FileOutputStream fos = null;
12639        DataOutputStream dos = null;
12640        try {
12641            fos = new FileOutputStream(file);
12642            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
12643            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
12644            dos.writeUTF(android.os.Build.VERSION.RELEASE);
12645            dos.writeUTF(android.os.Build.VERSION.CODENAME);
12646            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
12647            dos.writeInt(list.size());
12648            for (int i=0; i<list.size(); i++) {
12649                dos.writeUTF(list.get(i).getPackageName());
12650                dos.writeUTF(list.get(i).getClassName());
12651            }
12652        } catch (IOException e) {
12653            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
12654            file.delete();
12655        } finally {
12656            FileUtils.sync(fos);
12657            if (dos != null) {
12658                try {
12659                    dos.close();
12660                } catch (IOException e) {
12661                    // TODO Auto-generated catch block
12662                    e.printStackTrace();
12663                }
12664            }
12665        }
12666    }
12667
12668    final class PreBootContinuation extends IIntentReceiver.Stub {
12669        final Intent intent;
12670        final Runnable onFinishCallback;
12671        final ArrayList<ComponentName> doneReceivers;
12672        final List<ResolveInfo> ris;
12673        final int[] users;
12674        int lastRi = -1;
12675        int curRi = 0;
12676        int curUser = 0;
12677
12678        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
12679                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
12680            intent = _intent;
12681            onFinishCallback = _onFinishCallback;
12682            doneReceivers = _doneReceivers;
12683            ris = _ris;
12684            users = _users;
12685        }
12686
12687        void go() {
12688            if (lastRi != curRi) {
12689                ActivityInfo ai = ris.get(curRi).activityInfo;
12690                ComponentName comp = new ComponentName(ai.packageName, ai.name);
12691                intent.setComponent(comp);
12692                doneReceivers.add(comp);
12693                lastRi = curRi;
12694                CharSequence label = ai.loadLabel(mContext.getPackageManager());
12695                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
12696            }
12697            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
12698                    + " for user " + users[curUser]);
12699            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
12700            broadcastIntentLocked(null, null, intent, null, this,
12701                    0, null, null, null, AppOpsManager.OP_NONE,
12702                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
12703        }
12704
12705        public void performReceive(Intent intent, int resultCode,
12706                String data, Bundle extras, boolean ordered,
12707                boolean sticky, int sendingUser) {
12708            curUser++;
12709            if (curUser >= users.length) {
12710                curUser = 0;
12711                curRi++;
12712                if (curRi >= ris.size()) {
12713                    // All done sending broadcasts!
12714                    if (onFinishCallback != null) {
12715                        // The raw IIntentReceiver interface is called
12716                        // with the AM lock held, so redispatch to
12717                        // execute our code without the lock.
12718                        mHandler.post(onFinishCallback);
12719                    }
12720                    return;
12721                }
12722            }
12723            go();
12724        }
12725    }
12726
12727    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
12728            ArrayList<ComponentName> doneReceivers) {
12729        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
12730        List<ResolveInfo> ris = null;
12731        try {
12732            ris = AppGlobals.getPackageManager().queryIntentReceivers(
12733                    intent, null, MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM).getList();
12734        } catch (RemoteException e) {
12735        }
12736        if (ris == null) {
12737            return false;
12738        }
12739        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE | Intent.FLAG_DEBUG_TRIAGED_MISSING);
12740
12741        ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
12742        for (int i=0; i<ris.size(); i++) {
12743            ActivityInfo ai = ris.get(i).activityInfo;
12744            ComponentName comp = new ComponentName(ai.packageName, ai.name);
12745            if (lastDoneReceivers.contains(comp)) {
12746                // We already did the pre boot receiver for this app with the current
12747                // platform version, so don't do it again...
12748                ris.remove(i);
12749                i--;
12750                // ...however, do keep it as one that has been done, so we don't
12751                // forget about it when rewriting the file of last done receivers.
12752                doneReceivers.add(comp);
12753            }
12754        }
12755
12756        if (ris.size() <= 0) {
12757            return false;
12758        }
12759
12760        // TODO: can we still do this with per user encryption?
12761        final int[] users = mUserController.getUsers();
12762        if (users.length <= 0) {
12763            return false;
12764        }
12765
12766        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
12767                ris, users);
12768        cont.go();
12769        return true;
12770    }
12771
12772    public void systemReady(final Runnable goingCallback) {
12773        synchronized(this) {
12774            if (mSystemReady) {
12775                // If we're done calling all the receivers, run the next "boot phase" passed in
12776                // by the SystemServer
12777                if (goingCallback != null) {
12778                    goingCallback.run();
12779                }
12780                return;
12781            }
12782
12783            mLocalDeviceIdleController
12784                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12785
12786            // Make sure we have the current profile info, since it is needed for security checks.
12787            mUserController.onSystemReady();
12788
12789            mRecentTasks.onSystemReadyLocked();
12790            // Check to see if there are any update receivers to run.
12791            if (!mDidUpdate) {
12792                if (mWaitingUpdate) {
12793                    return;
12794                }
12795                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
12796                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
12797                    public void run() {
12798                        synchronized (ActivityManagerService.this) {
12799                            mDidUpdate = true;
12800                        }
12801                        showBootMessage(mContext.getText(
12802                                R.string.android_upgrading_complete),
12803                                false);
12804                        writeLastDonePreBootReceivers(doneReceivers);
12805                        systemReady(goingCallback);
12806                    }
12807                }, doneReceivers);
12808
12809                if (mWaitingUpdate) {
12810                    return;
12811                }
12812                mDidUpdate = true;
12813            }
12814
12815            mAppOpsService.systemReady();
12816            mSystemReady = true;
12817        }
12818
12819        ArrayList<ProcessRecord> procsToKill = null;
12820        synchronized(mPidsSelfLocked) {
12821            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12822                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12823                if (!isAllowedWhileBooting(proc.info)){
12824                    if (procsToKill == null) {
12825                        procsToKill = new ArrayList<ProcessRecord>();
12826                    }
12827                    procsToKill.add(proc);
12828                }
12829            }
12830        }
12831
12832        synchronized(this) {
12833            if (procsToKill != null) {
12834                for (int i=procsToKill.size()-1; i>=0; i--) {
12835                    ProcessRecord proc = procsToKill.get(i);
12836                    Slog.i(TAG, "Removing system update proc: " + proc);
12837                    removeProcessLocked(proc, true, false, "system update done");
12838                }
12839            }
12840
12841            // Now that we have cleaned up any update processes, we
12842            // are ready to start launching real processes and know that
12843            // we won't trample on them any more.
12844            mProcessesReady = true;
12845        }
12846
12847        Slog.i(TAG, "System now ready");
12848        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12849            SystemClock.uptimeMillis());
12850
12851        synchronized(this) {
12852            // Make sure we have no pre-ready processes sitting around.
12853
12854            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12855                ResolveInfo ri = mContext.getPackageManager()
12856                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12857                                STOCK_PM_FLAGS);
12858                CharSequence errorMsg = null;
12859                if (ri != null) {
12860                    ActivityInfo ai = ri.activityInfo;
12861                    ApplicationInfo app = ai.applicationInfo;
12862                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12863                        mTopAction = Intent.ACTION_FACTORY_TEST;
12864                        mTopData = null;
12865                        mTopComponent = new ComponentName(app.packageName,
12866                                ai.name);
12867                    } else {
12868                        errorMsg = mContext.getResources().getText(
12869                                com.android.internal.R.string.factorytest_not_system);
12870                    }
12871                } else {
12872                    errorMsg = mContext.getResources().getText(
12873                            com.android.internal.R.string.factorytest_no_action);
12874                }
12875                if (errorMsg != null) {
12876                    mTopAction = null;
12877                    mTopData = null;
12878                    mTopComponent = null;
12879                    Message msg = Message.obtain();
12880                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12881                    msg.getData().putCharSequence("msg", errorMsg);
12882                    mUiHandler.sendMessage(msg);
12883                }
12884            }
12885        }
12886
12887        retrieveSettings();
12888        final int currentUserId;
12889        synchronized (this) {
12890            currentUserId = mUserController.getCurrentUserIdLocked();
12891            readGrantedUriPermissionsLocked();
12892        }
12893
12894        if (goingCallback != null) goingCallback.run();
12895
12896        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12897                Integer.toString(currentUserId), currentUserId);
12898        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12899                Integer.toString(currentUserId), currentUserId);
12900        mSystemServiceManager.startUser(currentUserId);
12901
12902        synchronized (this) {
12903            // Only start up encryption-aware persistent apps; once user is
12904            // unlocked we'll come back around and start unaware apps
12905            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12906
12907            // Start up initial activity.
12908            mBooting = true;
12909            // Enable home activity for system user, so that the system can always boot
12910            if (UserManager.isSplitSystemUser()) {
12911                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12912                try {
12913                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12914                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12915                            UserHandle.USER_SYSTEM);
12916                } catch (RemoteException e) {
12917                    throw e.rethrowAsRuntimeException();
12918                }
12919            }
12920            startHomeActivityLocked(currentUserId, "systemReady");
12921
12922            try {
12923                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12924                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12925                            + " data partition or your device will be unstable.");
12926                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12927                }
12928            } catch (RemoteException e) {
12929            }
12930
12931            if (!Build.isBuildConsistent()) {
12932                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12933                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12934            }
12935
12936            long ident = Binder.clearCallingIdentity();
12937            try {
12938                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12939                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12940                        | Intent.FLAG_RECEIVER_FOREGROUND);
12941                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12942                broadcastIntentLocked(null, null, intent,
12943                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12944                        null, false, false, MY_PID, Process.SYSTEM_UID,
12945                        currentUserId);
12946                intent = new Intent(Intent.ACTION_USER_STARTING);
12947                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12948                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12949                broadcastIntentLocked(null, null, intent,
12950                        null, new IIntentReceiver.Stub() {
12951                            @Override
12952                            public void performReceive(Intent intent, int resultCode, String data,
12953                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12954                                    throws RemoteException {
12955                            }
12956                        }, 0, null, null,
12957                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12958                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12959            } catch (Throwable t) {
12960                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12961            } finally {
12962                Binder.restoreCallingIdentity(ident);
12963            }
12964            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12965            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12966        }
12967    }
12968
12969    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12970        synchronized (this) {
12971            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12972        }
12973    }
12974
12975    void skipCurrentReceiverLocked(ProcessRecord app) {
12976        for (BroadcastQueue queue : mBroadcastQueues) {
12977            queue.skipCurrentReceiverLocked(app);
12978        }
12979    }
12980
12981    /**
12982     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12983     * The application process will exit immediately after this call returns.
12984     * @param app object of the crashing app, null for the system server
12985     * @param crashInfo describing the exception
12986     */
12987    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12988        ProcessRecord r = findAppProcess(app, "Crash");
12989        final String processName = app == null ? "system_server"
12990                : (r == null ? "unknown" : r.processName);
12991
12992        handleApplicationCrashInner("crash", r, processName, crashInfo);
12993    }
12994
12995    /* Native crash reporting uses this inner version because it needs to be somewhat
12996     * decoupled from the AM-managed cleanup lifecycle
12997     */
12998    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12999            ApplicationErrorReport.CrashInfo crashInfo) {
13000        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13001                UserHandle.getUserId(Binder.getCallingUid()), processName,
13002                r == null ? -1 : r.info.flags,
13003                crashInfo.exceptionClassName,
13004                crashInfo.exceptionMessage,
13005                crashInfo.throwFileName,
13006                crashInfo.throwLineNumber);
13007
13008        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13009
13010        mAppErrors.crashApplication(r, crashInfo);
13011    }
13012
13013    public void handleApplicationStrictModeViolation(
13014            IBinder app,
13015            int violationMask,
13016            StrictMode.ViolationInfo info) {
13017        ProcessRecord r = findAppProcess(app, "StrictMode");
13018        if (r == null) {
13019            return;
13020        }
13021
13022        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13023            Integer stackFingerprint = info.hashCode();
13024            boolean logIt = true;
13025            synchronized (mAlreadyLoggedViolatedStacks) {
13026                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13027                    logIt = false;
13028                    // TODO: sub-sample into EventLog for these, with
13029                    // the info.durationMillis?  Then we'd get
13030                    // the relative pain numbers, without logging all
13031                    // the stack traces repeatedly.  We'd want to do
13032                    // likewise in the client code, which also does
13033                    // dup suppression, before the Binder call.
13034                } else {
13035                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13036                        mAlreadyLoggedViolatedStacks.clear();
13037                    }
13038                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13039                }
13040            }
13041            if (logIt) {
13042                logStrictModeViolationToDropBox(r, info);
13043            }
13044        }
13045
13046        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13047            AppErrorResult result = new AppErrorResult();
13048            synchronized (this) {
13049                final long origId = Binder.clearCallingIdentity();
13050
13051                Message msg = Message.obtain();
13052                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13053                HashMap<String, Object> data = new HashMap<String, Object>();
13054                data.put("result", result);
13055                data.put("app", r);
13056                data.put("violationMask", violationMask);
13057                data.put("info", info);
13058                msg.obj = data;
13059                mUiHandler.sendMessage(msg);
13060
13061                Binder.restoreCallingIdentity(origId);
13062            }
13063            int res = result.get();
13064            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13065        }
13066    }
13067
13068    // Depending on the policy in effect, there could be a bunch of
13069    // these in quick succession so we try to batch these together to
13070    // minimize disk writes, number of dropbox entries, and maximize
13071    // compression, by having more fewer, larger records.
13072    private void logStrictModeViolationToDropBox(
13073            ProcessRecord process,
13074            StrictMode.ViolationInfo info) {
13075        if (info == null) {
13076            return;
13077        }
13078        final boolean isSystemApp = process == null ||
13079                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13080                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13081        final String processName = process == null ? "unknown" : process.processName;
13082        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13083        final DropBoxManager dbox = (DropBoxManager)
13084                mContext.getSystemService(Context.DROPBOX_SERVICE);
13085
13086        // Exit early if the dropbox isn't configured to accept this report type.
13087        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13088
13089        boolean bufferWasEmpty;
13090        boolean needsFlush;
13091        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13092        synchronized (sb) {
13093            bufferWasEmpty = sb.length() == 0;
13094            appendDropBoxProcessHeaders(process, processName, sb);
13095            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13096            sb.append("System-App: ").append(isSystemApp).append("\n");
13097            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13098            if (info.violationNumThisLoop != 0) {
13099                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13100            }
13101            if (info.numAnimationsRunning != 0) {
13102                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13103            }
13104            if (info.broadcastIntentAction != null) {
13105                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13106            }
13107            if (info.durationMillis != -1) {
13108                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13109            }
13110            if (info.numInstances != -1) {
13111                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13112            }
13113            if (info.tags != null) {
13114                for (String tag : info.tags) {
13115                    sb.append("Span-Tag: ").append(tag).append("\n");
13116                }
13117            }
13118            sb.append("\n");
13119            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13120                sb.append(info.crashInfo.stackTrace);
13121                sb.append("\n");
13122            }
13123            if (info.message != null) {
13124                sb.append(info.message);
13125                sb.append("\n");
13126            }
13127
13128            // Only buffer up to ~64k.  Various logging bits truncate
13129            // things at 128k.
13130            needsFlush = (sb.length() > 64 * 1024);
13131        }
13132
13133        // Flush immediately if the buffer's grown too large, or this
13134        // is a non-system app.  Non-system apps are isolated with a
13135        // different tag & policy and not batched.
13136        //
13137        // Batching is useful during internal testing with
13138        // StrictMode settings turned up high.  Without batching,
13139        // thousands of separate files could be created on boot.
13140        if (!isSystemApp || needsFlush) {
13141            new Thread("Error dump: " + dropboxTag) {
13142                @Override
13143                public void run() {
13144                    String report;
13145                    synchronized (sb) {
13146                        report = sb.toString();
13147                        sb.delete(0, sb.length());
13148                        sb.trimToSize();
13149                    }
13150                    if (report.length() != 0) {
13151                        dbox.addText(dropboxTag, report);
13152                    }
13153                }
13154            }.start();
13155            return;
13156        }
13157
13158        // System app batching:
13159        if (!bufferWasEmpty) {
13160            // An existing dropbox-writing thread is outstanding, so
13161            // we don't need to start it up.  The existing thread will
13162            // catch the buffer appends we just did.
13163            return;
13164        }
13165
13166        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13167        // (After this point, we shouldn't access AMS internal data structures.)
13168        new Thread("Error dump: " + dropboxTag) {
13169            @Override
13170            public void run() {
13171                // 5 second sleep to let stacks arrive and be batched together
13172                try {
13173                    Thread.sleep(5000);  // 5 seconds
13174                } catch (InterruptedException e) {}
13175
13176                String errorReport;
13177                synchronized (mStrictModeBuffer) {
13178                    errorReport = mStrictModeBuffer.toString();
13179                    if (errorReport.length() == 0) {
13180                        return;
13181                    }
13182                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13183                    mStrictModeBuffer.trimToSize();
13184                }
13185                dbox.addText(dropboxTag, errorReport);
13186            }
13187        }.start();
13188    }
13189
13190    /**
13191     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13192     * @param app object of the crashing app, null for the system server
13193     * @param tag reported by the caller
13194     * @param system whether this wtf is coming from the system
13195     * @param crashInfo describing the context of the error
13196     * @return true if the process should exit immediately (WTF is fatal)
13197     */
13198    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13199            final ApplicationErrorReport.CrashInfo crashInfo) {
13200        final int callingUid = Binder.getCallingUid();
13201        final int callingPid = Binder.getCallingPid();
13202
13203        if (system) {
13204            // If this is coming from the system, we could very well have low-level
13205            // system locks held, so we want to do this all asynchronously.  And we
13206            // never want this to become fatal, so there is that too.
13207            mHandler.post(new Runnable() {
13208                @Override public void run() {
13209                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13210                }
13211            });
13212            return false;
13213        }
13214
13215        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13216                crashInfo);
13217
13218        if (r != null && r.pid != Process.myPid() &&
13219                Settings.Global.getInt(mContext.getContentResolver(),
13220                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13221            mAppErrors.crashApplication(r, crashInfo);
13222            return true;
13223        } else {
13224            return false;
13225        }
13226    }
13227
13228    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13229            final ApplicationErrorReport.CrashInfo crashInfo) {
13230        final ProcessRecord r = findAppProcess(app, "WTF");
13231        final String processName = app == null ? "system_server"
13232                : (r == null ? "unknown" : r.processName);
13233
13234        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13235                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13236
13237        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13238
13239        return r;
13240    }
13241
13242    /**
13243     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13244     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13245     */
13246    private ProcessRecord findAppProcess(IBinder app, String reason) {
13247        if (app == null) {
13248            return null;
13249        }
13250
13251        synchronized (this) {
13252            final int NP = mProcessNames.getMap().size();
13253            for (int ip=0; ip<NP; ip++) {
13254                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13255                final int NA = apps.size();
13256                for (int ia=0; ia<NA; ia++) {
13257                    ProcessRecord p = apps.valueAt(ia);
13258                    if (p.thread != null && p.thread.asBinder() == app) {
13259                        return p;
13260                    }
13261                }
13262            }
13263
13264            Slog.w(TAG, "Can't find mystery application for " + reason
13265                    + " from pid=" + Binder.getCallingPid()
13266                    + " uid=" + Binder.getCallingUid() + ": " + app);
13267            return null;
13268        }
13269    }
13270
13271    /**
13272     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13273     * to append various headers to the dropbox log text.
13274     */
13275    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13276            StringBuilder sb) {
13277        // Watchdog thread ends up invoking this function (with
13278        // a null ProcessRecord) to add the stack file to dropbox.
13279        // Do not acquire a lock on this (am) in such cases, as it
13280        // could cause a potential deadlock, if and when watchdog
13281        // is invoked due to unavailability of lock on am and it
13282        // would prevent watchdog from killing system_server.
13283        if (process == null) {
13284            sb.append("Process: ").append(processName).append("\n");
13285            return;
13286        }
13287        // Note: ProcessRecord 'process' is guarded by the service
13288        // instance.  (notably process.pkgList, which could otherwise change
13289        // concurrently during execution of this method)
13290        synchronized (this) {
13291            sb.append("Process: ").append(processName).append("\n");
13292            int flags = process.info.flags;
13293            IPackageManager pm = AppGlobals.getPackageManager();
13294            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13295            for (int ip=0; ip<process.pkgList.size(); ip++) {
13296                String pkg = process.pkgList.keyAt(ip);
13297                sb.append("Package: ").append(pkg);
13298                try {
13299                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13300                    if (pi != null) {
13301                        sb.append(" v").append(pi.versionCode);
13302                        if (pi.versionName != null) {
13303                            sb.append(" (").append(pi.versionName).append(")");
13304                        }
13305                    }
13306                } catch (RemoteException e) {
13307                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13308                }
13309                sb.append("\n");
13310            }
13311        }
13312    }
13313
13314    private static String processClass(ProcessRecord process) {
13315        if (process == null || process.pid == MY_PID) {
13316            return "system_server";
13317        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13318            return "system_app";
13319        } else {
13320            return "data_app";
13321        }
13322    }
13323
13324    /**
13325     * Write a description of an error (crash, WTF, ANR) to the drop box.
13326     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13327     * @param process which caused the error, null means the system server
13328     * @param activity which triggered the error, null if unknown
13329     * @param parent activity related to the error, null if unknown
13330     * @param subject line related to the error, null if absent
13331     * @param report in long form describing the error, null if absent
13332     * @param logFile to include in the report, null if none
13333     * @param crashInfo giving an application stack trace, null if absent
13334     */
13335    public void addErrorToDropBox(String eventType,
13336            ProcessRecord process, String processName, ActivityRecord activity,
13337            ActivityRecord parent, String subject,
13338            final String report, final File logFile,
13339            final ApplicationErrorReport.CrashInfo crashInfo) {
13340        // NOTE -- this must never acquire the ActivityManagerService lock,
13341        // otherwise the watchdog may be prevented from resetting the system.
13342
13343        final String dropboxTag = processClass(process) + "_" + eventType;
13344        final DropBoxManager dbox = (DropBoxManager)
13345                mContext.getSystemService(Context.DROPBOX_SERVICE);
13346
13347        // Exit early if the dropbox isn't configured to accept this report type.
13348        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13349
13350        final StringBuilder sb = new StringBuilder(1024);
13351        appendDropBoxProcessHeaders(process, processName, sb);
13352        if (process != null) {
13353            sb.append("Foreground: ")
13354                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13355                    .append("\n");
13356        }
13357        if (activity != null) {
13358            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13359        }
13360        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13361            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13362        }
13363        if (parent != null && parent != activity) {
13364            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13365        }
13366        if (subject != null) {
13367            sb.append("Subject: ").append(subject).append("\n");
13368        }
13369        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13370        if (Debug.isDebuggerConnected()) {
13371            sb.append("Debugger: Connected\n");
13372        }
13373        sb.append("\n");
13374
13375        // Do the rest in a worker thread to avoid blocking the caller on I/O
13376        // (After this point, we shouldn't access AMS internal data structures.)
13377        Thread worker = new Thread("Error dump: " + dropboxTag) {
13378            @Override
13379            public void run() {
13380                if (report != null) {
13381                    sb.append(report);
13382                }
13383                if (logFile != null) {
13384                    try {
13385                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13386                                    "\n\n[[TRUNCATED]]"));
13387                    } catch (IOException e) {
13388                        Slog.e(TAG, "Error reading " + logFile, e);
13389                    }
13390                }
13391                if (crashInfo != null && crashInfo.stackTrace != null) {
13392                    sb.append(crashInfo.stackTrace);
13393                }
13394
13395                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13396                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13397                if (lines > 0) {
13398                    sb.append("\n");
13399
13400                    // Merge several logcat streams, and take the last N lines
13401                    InputStreamReader input = null;
13402                    try {
13403                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
13404                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
13405                                "-b", "crash",
13406                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
13407
13408                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13409                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13410                        input = new InputStreamReader(logcat.getInputStream());
13411
13412                        int num;
13413                        char[] buf = new char[8192];
13414                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13415                    } catch (IOException e) {
13416                        Slog.e(TAG, "Error running logcat", e);
13417                    } finally {
13418                        if (input != null) try { input.close(); } catch (IOException e) {}
13419                    }
13420                }
13421
13422                dbox.addText(dropboxTag, sb.toString());
13423            }
13424        };
13425
13426        if (process == null) {
13427            // If process is null, we are being called from some internal code
13428            // and may be about to die -- run this synchronously.
13429            worker.run();
13430        } else {
13431            worker.start();
13432        }
13433    }
13434
13435    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13436        enforceNotIsolatedCaller("getProcessesInErrorState");
13437        // assume our apps are happy - lazy create the list
13438        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13439
13440        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13441                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13442        int userId = UserHandle.getUserId(Binder.getCallingUid());
13443
13444        synchronized (this) {
13445
13446            // iterate across all processes
13447            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13448                ProcessRecord app = mLruProcesses.get(i);
13449                if (!allUsers && app.userId != userId) {
13450                    continue;
13451                }
13452                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13453                    // This one's in trouble, so we'll generate a report for it
13454                    // crashes are higher priority (in case there's a crash *and* an anr)
13455                    ActivityManager.ProcessErrorStateInfo report = null;
13456                    if (app.crashing) {
13457                        report = app.crashingReport;
13458                    } else if (app.notResponding) {
13459                        report = app.notRespondingReport;
13460                    }
13461
13462                    if (report != null) {
13463                        if (errList == null) {
13464                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13465                        }
13466                        errList.add(report);
13467                    } else {
13468                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13469                                " crashing = " + app.crashing +
13470                                " notResponding = " + app.notResponding);
13471                    }
13472                }
13473            }
13474        }
13475
13476        return errList;
13477    }
13478
13479    static int procStateToImportance(int procState, int memAdj,
13480            ActivityManager.RunningAppProcessInfo currApp) {
13481        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13482        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13483            currApp.lru = memAdj;
13484        } else {
13485            currApp.lru = 0;
13486        }
13487        return imp;
13488    }
13489
13490    private void fillInProcMemInfo(ProcessRecord app,
13491            ActivityManager.RunningAppProcessInfo outInfo) {
13492        outInfo.pid = app.pid;
13493        outInfo.uid = app.info.uid;
13494        if (mHeavyWeightProcess == app) {
13495            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13496        }
13497        if (app.persistent) {
13498            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13499        }
13500        if (app.activities.size() > 0) {
13501            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13502        }
13503        outInfo.lastTrimLevel = app.trimMemoryLevel;
13504        int adj = app.curAdj;
13505        int procState = app.curProcState;
13506        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13507        outInfo.importanceReasonCode = app.adjTypeCode;
13508        outInfo.processState = app.curProcState;
13509    }
13510
13511    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13512        enforceNotIsolatedCaller("getRunningAppProcesses");
13513
13514        final int callingUid = Binder.getCallingUid();
13515
13516        // Lazy instantiation of list
13517        List<ActivityManager.RunningAppProcessInfo> runList = null;
13518        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13519                callingUid) == PackageManager.PERMISSION_GRANTED;
13520        final int userId = UserHandle.getUserId(callingUid);
13521        final boolean allUids = isGetTasksAllowed(
13522                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13523
13524        synchronized (this) {
13525            // Iterate across all processes
13526            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13527                ProcessRecord app = mLruProcesses.get(i);
13528                if ((!allUsers && app.userId != userId)
13529                        || (!allUids && app.uid != callingUid)) {
13530                    continue;
13531                }
13532                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13533                    // Generate process state info for running application
13534                    ActivityManager.RunningAppProcessInfo currApp =
13535                        new ActivityManager.RunningAppProcessInfo(app.processName,
13536                                app.pid, app.getPackageList());
13537                    fillInProcMemInfo(app, currApp);
13538                    if (app.adjSource instanceof ProcessRecord) {
13539                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13540                        currApp.importanceReasonImportance =
13541                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13542                                        app.adjSourceProcState);
13543                    } else if (app.adjSource instanceof ActivityRecord) {
13544                        ActivityRecord r = (ActivityRecord)app.adjSource;
13545                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13546                    }
13547                    if (app.adjTarget instanceof ComponentName) {
13548                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13549                    }
13550                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13551                    //        + " lru=" + currApp.lru);
13552                    if (runList == null) {
13553                        runList = new ArrayList<>();
13554                    }
13555                    runList.add(currApp);
13556                }
13557            }
13558        }
13559        return runList;
13560    }
13561
13562    public List<ApplicationInfo> getRunningExternalApplications() {
13563        enforceNotIsolatedCaller("getRunningExternalApplications");
13564        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13565        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13566        if (runningApps != null && runningApps.size() > 0) {
13567            Set<String> extList = new HashSet<String>();
13568            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13569                if (app.pkgList != null) {
13570                    for (String pkg : app.pkgList) {
13571                        extList.add(pkg);
13572                    }
13573                }
13574            }
13575            IPackageManager pm = AppGlobals.getPackageManager();
13576            for (String pkg : extList) {
13577                try {
13578                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13579                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13580                        retList.add(info);
13581                    }
13582                } catch (RemoteException e) {
13583                }
13584            }
13585        }
13586        return retList;
13587    }
13588
13589    @Override
13590    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13591        enforceNotIsolatedCaller("getMyMemoryState");
13592        synchronized (this) {
13593            ProcessRecord proc;
13594            synchronized (mPidsSelfLocked) {
13595                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13596            }
13597            fillInProcMemInfo(proc, outInfo);
13598        }
13599    }
13600
13601    @Override
13602    public int getMemoryTrimLevel() {
13603        enforceNotIsolatedCaller("getMyMemoryState");
13604        synchronized (this) {
13605            return mLastMemoryLevel;
13606        }
13607    }
13608
13609    @Override
13610    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13611            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13612        (new ActivityManagerShellCommand(this, false)).exec(
13613                this, in, out, err, args, resultReceiver);
13614    }
13615
13616    @Override
13617    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13618        if (checkCallingPermission(android.Manifest.permission.DUMP)
13619                != PackageManager.PERMISSION_GRANTED) {
13620            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13621                    + Binder.getCallingPid()
13622                    + ", uid=" + Binder.getCallingUid()
13623                    + " without permission "
13624                    + android.Manifest.permission.DUMP);
13625            return;
13626        }
13627
13628        boolean dumpAll = false;
13629        boolean dumpClient = false;
13630        String dumpPackage = null;
13631
13632        int opti = 0;
13633        while (opti < args.length) {
13634            String opt = args[opti];
13635            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13636                break;
13637            }
13638            opti++;
13639            if ("-a".equals(opt)) {
13640                dumpAll = true;
13641            } else if ("-c".equals(opt)) {
13642                dumpClient = true;
13643            } else if ("-p".equals(opt)) {
13644                if (opti < args.length) {
13645                    dumpPackage = args[opti];
13646                    opti++;
13647                } else {
13648                    pw.println("Error: -p option requires package argument");
13649                    return;
13650                }
13651                dumpClient = true;
13652            } else if ("-h".equals(opt)) {
13653                ActivityManagerShellCommand.dumpHelp(pw, true);
13654                return;
13655            } else {
13656                pw.println("Unknown argument: " + opt + "; use -h for help");
13657            }
13658        }
13659
13660        long origId = Binder.clearCallingIdentity();
13661        boolean more = false;
13662        // Is the caller requesting to dump a particular piece of data?
13663        if (opti < args.length) {
13664            String cmd = args[opti];
13665            opti++;
13666            if ("activities".equals(cmd) || "a".equals(cmd)) {
13667                synchronized (this) {
13668                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13669                }
13670            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13671                synchronized (this) {
13672                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13673                }
13674            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13675                String[] newArgs;
13676                String name;
13677                if (opti >= args.length) {
13678                    name = null;
13679                    newArgs = EMPTY_STRING_ARRAY;
13680                } else {
13681                    dumpPackage = args[opti];
13682                    opti++;
13683                    newArgs = new String[args.length - opti];
13684                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13685                            args.length - opti);
13686                }
13687                synchronized (this) {
13688                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13689                }
13690            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13691                String[] newArgs;
13692                String name;
13693                if (opti >= args.length) {
13694                    name = null;
13695                    newArgs = EMPTY_STRING_ARRAY;
13696                } else {
13697                    dumpPackage = args[opti];
13698                    opti++;
13699                    newArgs = new String[args.length - opti];
13700                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13701                            args.length - opti);
13702                }
13703                synchronized (this) {
13704                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13705                }
13706            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13707                String[] newArgs;
13708                String name;
13709                if (opti >= args.length) {
13710                    name = null;
13711                    newArgs = EMPTY_STRING_ARRAY;
13712                } else {
13713                    dumpPackage = args[opti];
13714                    opti++;
13715                    newArgs = new String[args.length - opti];
13716                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13717                            args.length - opti);
13718                }
13719                synchronized (this) {
13720                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13721                }
13722            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13723                synchronized (this) {
13724                    dumpOomLocked(fd, pw, args, opti, true);
13725                }
13726            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13727                synchronized (this) {
13728                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13729                }
13730            } else if ("provider".equals(cmd)) {
13731                String[] newArgs;
13732                String name;
13733                if (opti >= args.length) {
13734                    name = null;
13735                    newArgs = EMPTY_STRING_ARRAY;
13736                } else {
13737                    name = args[opti];
13738                    opti++;
13739                    newArgs = new String[args.length - opti];
13740                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13741                }
13742                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13743                    pw.println("No providers match: " + name);
13744                    pw.println("Use -h for help.");
13745                }
13746            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13747                synchronized (this) {
13748                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13749                }
13750            } else if ("service".equals(cmd)) {
13751                String[] newArgs;
13752                String name;
13753                if (opti >= args.length) {
13754                    name = null;
13755                    newArgs = EMPTY_STRING_ARRAY;
13756                } else {
13757                    name = args[opti];
13758                    opti++;
13759                    newArgs = new String[args.length - opti];
13760                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13761                            args.length - opti);
13762                }
13763                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13764                    pw.println("No services match: " + name);
13765                    pw.println("Use -h for help.");
13766                }
13767            } else if ("package".equals(cmd)) {
13768                String[] newArgs;
13769                if (opti >= args.length) {
13770                    pw.println("package: no package name specified");
13771                    pw.println("Use -h for help.");
13772                } else {
13773                    dumpPackage = args[opti];
13774                    opti++;
13775                    newArgs = new String[args.length - opti];
13776                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13777                            args.length - opti);
13778                    args = newArgs;
13779                    opti = 0;
13780                    more = true;
13781                }
13782            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13783                synchronized (this) {
13784                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13785                }
13786            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13787                synchronized (this) {
13788                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13789                }
13790            } else if ("locks".equals(cmd)) {
13791                LockGuard.dump(fd, pw, args);
13792            } else {
13793                // Dumping a single activity?
13794                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13795                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13796                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13797                    if (res < 0) {
13798                        pw.println("Bad activity command, or no activities match: " + cmd);
13799                        pw.println("Use -h for help.");
13800                    }
13801                }
13802            }
13803            if (!more) {
13804                Binder.restoreCallingIdentity(origId);
13805                return;
13806            }
13807        }
13808
13809        // No piece of data specified, dump everything.
13810        synchronized (this) {
13811            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13812            pw.println();
13813            if (dumpAll) {
13814                pw.println("-------------------------------------------------------------------------------");
13815            }
13816            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13817            pw.println();
13818            if (dumpAll) {
13819                pw.println("-------------------------------------------------------------------------------");
13820            }
13821            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13822            pw.println();
13823            if (dumpAll) {
13824                pw.println("-------------------------------------------------------------------------------");
13825            }
13826            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13827            pw.println();
13828            if (dumpAll) {
13829                pw.println("-------------------------------------------------------------------------------");
13830            }
13831            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13832            pw.println();
13833            if (dumpAll) {
13834                pw.println("-------------------------------------------------------------------------------");
13835            }
13836            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13837            pw.println();
13838            if (dumpAll) {
13839                pw.println("-------------------------------------------------------------------------------");
13840            }
13841            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13842            if (mAssociations.size() > 0) {
13843                pw.println();
13844                if (dumpAll) {
13845                    pw.println("-------------------------------------------------------------------------------");
13846                }
13847                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13848            }
13849            pw.println();
13850            if (dumpAll) {
13851                pw.println("-------------------------------------------------------------------------------");
13852            }
13853            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13854        }
13855        Binder.restoreCallingIdentity(origId);
13856    }
13857
13858    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13859            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13860        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13861
13862        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13863                dumpPackage);
13864        boolean needSep = printedAnything;
13865
13866        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13867                dumpPackage, needSep, "  mFocusedActivity: ");
13868        if (printed) {
13869            printedAnything = true;
13870            needSep = false;
13871        }
13872
13873        if (dumpPackage == null) {
13874            if (needSep) {
13875                pw.println();
13876            }
13877            needSep = true;
13878            printedAnything = true;
13879            mStackSupervisor.dump(pw, "  ");
13880        }
13881
13882        if (!printedAnything) {
13883            pw.println("  (nothing)");
13884        }
13885    }
13886
13887    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13888            int opti, boolean dumpAll, String dumpPackage) {
13889        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13890
13891        boolean printedAnything = false;
13892
13893        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13894            boolean printedHeader = false;
13895
13896            final int N = mRecentTasks.size();
13897            for (int i=0; i<N; i++) {
13898                TaskRecord tr = mRecentTasks.get(i);
13899                if (dumpPackage != null) {
13900                    if (tr.realActivity == null ||
13901                            !dumpPackage.equals(tr.realActivity)) {
13902                        continue;
13903                    }
13904                }
13905                if (!printedHeader) {
13906                    pw.println("  Recent tasks:");
13907                    printedHeader = true;
13908                    printedAnything = true;
13909                }
13910                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13911                        pw.println(tr);
13912                if (dumpAll) {
13913                    mRecentTasks.get(i).dump(pw, "    ");
13914                }
13915            }
13916        }
13917
13918        if (!printedAnything) {
13919            pw.println("  (nothing)");
13920        }
13921    }
13922
13923    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13924            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13925        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13926
13927        int dumpUid = 0;
13928        if (dumpPackage != null) {
13929            IPackageManager pm = AppGlobals.getPackageManager();
13930            try {
13931                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13932            } catch (RemoteException e) {
13933            }
13934        }
13935
13936        boolean printedAnything = false;
13937
13938        final long now = SystemClock.uptimeMillis();
13939
13940        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13941            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13942                    = mAssociations.valueAt(i1);
13943            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13944                SparseArray<ArrayMap<String, Association>> sourceUids
13945                        = targetComponents.valueAt(i2);
13946                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13947                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13948                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13949                        Association ass = sourceProcesses.valueAt(i4);
13950                        if (dumpPackage != null) {
13951                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13952                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13953                                continue;
13954                            }
13955                        }
13956                        printedAnything = true;
13957                        pw.print("  ");
13958                        pw.print(ass.mTargetProcess);
13959                        pw.print("/");
13960                        UserHandle.formatUid(pw, ass.mTargetUid);
13961                        pw.print(" <- ");
13962                        pw.print(ass.mSourceProcess);
13963                        pw.print("/");
13964                        UserHandle.formatUid(pw, ass.mSourceUid);
13965                        pw.println();
13966                        pw.print("    via ");
13967                        pw.print(ass.mTargetComponent.flattenToShortString());
13968                        pw.println();
13969                        pw.print("    ");
13970                        long dur = ass.mTime;
13971                        if (ass.mNesting > 0) {
13972                            dur += now - ass.mStartTime;
13973                        }
13974                        TimeUtils.formatDuration(dur, pw);
13975                        pw.print(" (");
13976                        pw.print(ass.mCount);
13977                        pw.println(" times)");
13978                        if (ass.mNesting > 0) {
13979                            pw.print("    ");
13980                            pw.print(" Currently active: ");
13981                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13982                            pw.println();
13983                        }
13984                    }
13985                }
13986            }
13987
13988        }
13989
13990        if (!printedAnything) {
13991            pw.println("  (nothing)");
13992        }
13993    }
13994
13995    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13996            String header, boolean needSep) {
13997        boolean printed = false;
13998        int whichAppId = -1;
13999        if (dumpPackage != null) {
14000            try {
14001                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14002                        dumpPackage, 0);
14003                whichAppId = UserHandle.getAppId(info.uid);
14004            } catch (NameNotFoundException e) {
14005                e.printStackTrace();
14006            }
14007        }
14008        for (int i=0; i<uids.size(); i++) {
14009            UidRecord uidRec = uids.valueAt(i);
14010            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14011                continue;
14012            }
14013            if (!printed) {
14014                printed = true;
14015                if (needSep) {
14016                    pw.println();
14017                }
14018                pw.print("  ");
14019                pw.println(header);
14020                needSep = true;
14021            }
14022            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14023            pw.print(": "); pw.println(uidRec);
14024        }
14025        return printed;
14026    }
14027
14028    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14029            int opti, boolean dumpAll, String dumpPackage) {
14030        boolean needSep = false;
14031        boolean printedAnything = false;
14032        int numPers = 0;
14033
14034        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14035
14036        if (dumpAll) {
14037            final int NP = mProcessNames.getMap().size();
14038            for (int ip=0; ip<NP; ip++) {
14039                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14040                final int NA = procs.size();
14041                for (int ia=0; ia<NA; ia++) {
14042                    ProcessRecord r = procs.valueAt(ia);
14043                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14044                        continue;
14045                    }
14046                    if (!needSep) {
14047                        pw.println("  All known processes:");
14048                        needSep = true;
14049                        printedAnything = true;
14050                    }
14051                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14052                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14053                        pw.print(" "); pw.println(r);
14054                    r.dump(pw, "    ");
14055                    if (r.persistent) {
14056                        numPers++;
14057                    }
14058                }
14059            }
14060        }
14061
14062        if (mIsolatedProcesses.size() > 0) {
14063            boolean printed = false;
14064            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14065                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14066                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14067                    continue;
14068                }
14069                if (!printed) {
14070                    if (needSep) {
14071                        pw.println();
14072                    }
14073                    pw.println("  Isolated process list (sorted by uid):");
14074                    printedAnything = true;
14075                    printed = true;
14076                    needSep = true;
14077                }
14078                pw.println(String.format("%sIsolated #%2d: %s",
14079                        "    ", i, r.toString()));
14080            }
14081        }
14082
14083        if (mActiveUids.size() > 0) {
14084            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14085                printedAnything = needSep = true;
14086            }
14087        }
14088        if (mValidateUids.size() > 0) {
14089            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14090                printedAnything = needSep = true;
14091            }
14092        }
14093
14094        if (mLruProcesses.size() > 0) {
14095            if (needSep) {
14096                pw.println();
14097            }
14098            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14099                    pw.print(" total, non-act at ");
14100                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14101                    pw.print(", non-svc at ");
14102                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14103                    pw.println("):");
14104            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14105            needSep = true;
14106            printedAnything = true;
14107        }
14108
14109        if (dumpAll || dumpPackage != null) {
14110            synchronized (mPidsSelfLocked) {
14111                boolean printed = false;
14112                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14113                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14114                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14115                        continue;
14116                    }
14117                    if (!printed) {
14118                        if (needSep) pw.println();
14119                        needSep = true;
14120                        pw.println("  PID mappings:");
14121                        printed = true;
14122                        printedAnything = true;
14123                    }
14124                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14125                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14126                }
14127            }
14128        }
14129
14130        if (mForegroundProcesses.size() > 0) {
14131            synchronized (mPidsSelfLocked) {
14132                boolean printed = false;
14133                for (int i=0; i<mForegroundProcesses.size(); i++) {
14134                    ProcessRecord r = mPidsSelfLocked.get(
14135                            mForegroundProcesses.valueAt(i).pid);
14136                    if (dumpPackage != null && (r == null
14137                            || !r.pkgList.containsKey(dumpPackage))) {
14138                        continue;
14139                    }
14140                    if (!printed) {
14141                        if (needSep) pw.println();
14142                        needSep = true;
14143                        pw.println("  Foreground Processes:");
14144                        printed = true;
14145                        printedAnything = true;
14146                    }
14147                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14148                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14149                }
14150            }
14151        }
14152
14153        if (mPersistentStartingProcesses.size() > 0) {
14154            if (needSep) pw.println();
14155            needSep = true;
14156            printedAnything = true;
14157            pw.println("  Persisent processes that are starting:");
14158            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14159                    "Starting Norm", "Restarting PERS", dumpPackage);
14160        }
14161
14162        if (mRemovedProcesses.size() > 0) {
14163            if (needSep) pw.println();
14164            needSep = true;
14165            printedAnything = true;
14166            pw.println("  Processes that are being removed:");
14167            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14168                    "Removed Norm", "Removed PERS", dumpPackage);
14169        }
14170
14171        if (mProcessesOnHold.size() > 0) {
14172            if (needSep) pw.println();
14173            needSep = true;
14174            printedAnything = true;
14175            pw.println("  Processes that are on old until the system is ready:");
14176            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14177                    "OnHold Norm", "OnHold PERS", dumpPackage);
14178        }
14179
14180        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14181
14182        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14183        if (needSep) {
14184            printedAnything = true;
14185        }
14186
14187        if (dumpPackage == null) {
14188            pw.println();
14189            needSep = false;
14190            mUserController.dump(pw, dumpAll);
14191        }
14192        if (mHomeProcess != null && (dumpPackage == null
14193                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14194            if (needSep) {
14195                pw.println();
14196                needSep = false;
14197            }
14198            pw.println("  mHomeProcess: " + mHomeProcess);
14199        }
14200        if (mPreviousProcess != null && (dumpPackage == null
14201                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14202            if (needSep) {
14203                pw.println();
14204                needSep = false;
14205            }
14206            pw.println("  mPreviousProcess: " + mPreviousProcess);
14207        }
14208        if (dumpAll) {
14209            StringBuilder sb = new StringBuilder(128);
14210            sb.append("  mPreviousProcessVisibleTime: ");
14211            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14212            pw.println(sb);
14213        }
14214        if (mHeavyWeightProcess != null && (dumpPackage == null
14215                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14216            if (needSep) {
14217                pw.println();
14218                needSep = false;
14219            }
14220            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14221        }
14222        if (dumpPackage == null) {
14223            pw.println("  mConfiguration: " + mConfiguration);
14224        }
14225        if (dumpAll) {
14226            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14227            if (mCompatModePackages.getPackages().size() > 0) {
14228                boolean printed = false;
14229                for (Map.Entry<String, Integer> entry
14230                        : mCompatModePackages.getPackages().entrySet()) {
14231                    String pkg = entry.getKey();
14232                    int mode = entry.getValue();
14233                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14234                        continue;
14235                    }
14236                    if (!printed) {
14237                        pw.println("  mScreenCompatPackages:");
14238                        printed = true;
14239                    }
14240                    pw.print("    "); pw.print(pkg); pw.print(": ");
14241                            pw.print(mode); pw.println();
14242                }
14243            }
14244        }
14245        if (dumpPackage == null) {
14246            pw.println("  mWakefulness="
14247                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14248            pw.println("  mSleepTokens=" + mSleepTokens);
14249            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14250                    + lockScreenShownToString());
14251            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14252            if (mRunningVoice != null) {
14253                pw.println("  mRunningVoice=" + mRunningVoice);
14254                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14255            }
14256        }
14257        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14258                || mOrigWaitForDebugger) {
14259            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14260                    || dumpPackage.equals(mOrigDebugApp)) {
14261                if (needSep) {
14262                    pw.println();
14263                    needSep = false;
14264                }
14265                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14266                        + " mDebugTransient=" + mDebugTransient
14267                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14268            }
14269        }
14270        if (mCurAppTimeTracker != null) {
14271            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14272        }
14273        if (mMemWatchProcesses.getMap().size() > 0) {
14274            pw.println("  Mem watch processes:");
14275            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14276                    = mMemWatchProcesses.getMap();
14277            for (int i=0; i<procs.size(); i++) {
14278                final String proc = procs.keyAt(i);
14279                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14280                for (int j=0; j<uids.size(); j++) {
14281                    if (needSep) {
14282                        pw.println();
14283                        needSep = false;
14284                    }
14285                    StringBuilder sb = new StringBuilder();
14286                    sb.append("    ").append(proc).append('/');
14287                    UserHandle.formatUid(sb, uids.keyAt(j));
14288                    Pair<Long, String> val = uids.valueAt(j);
14289                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14290                    if (val.second != null) {
14291                        sb.append(", report to ").append(val.second);
14292                    }
14293                    pw.println(sb.toString());
14294                }
14295            }
14296            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14297            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14298            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14299                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14300        }
14301        if (mTrackAllocationApp != null) {
14302            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14303                if (needSep) {
14304                    pw.println();
14305                    needSep = false;
14306                }
14307                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14308            }
14309        }
14310        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14311                || mProfileFd != null) {
14312            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14313                if (needSep) {
14314                    pw.println();
14315                    needSep = false;
14316                }
14317                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14318                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14319                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14320                        + mAutoStopProfiler);
14321                pw.println("  mProfileType=" + mProfileType);
14322            }
14323        }
14324        if (mNativeDebuggingApp != null) {
14325            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14326                if (needSep) {
14327                    pw.println();
14328                    needSep = false;
14329                }
14330                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14331            }
14332        }
14333        if (dumpPackage == null) {
14334            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14335                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14336                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14337            }
14338            if (mController != null) {
14339                pw.println("  mController=" + mController
14340                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14341            }
14342            if (dumpAll) {
14343                pw.println("  Total persistent processes: " + numPers);
14344                pw.println("  mProcessesReady=" + mProcessesReady
14345                        + " mSystemReady=" + mSystemReady
14346                        + " mBooted=" + mBooted
14347                        + " mFactoryTest=" + mFactoryTest);
14348                pw.println("  mBooting=" + mBooting
14349                        + " mCallFinishBooting=" + mCallFinishBooting
14350                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14351                pw.print("  mLastPowerCheckRealtime=");
14352                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14353                        pw.println("");
14354                pw.print("  mLastPowerCheckUptime=");
14355                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14356                        pw.println("");
14357                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14358                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14359                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14360                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14361                        + " (" + mLruProcesses.size() + " total)"
14362                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14363                        + " mNumServiceProcs=" + mNumServiceProcs
14364                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14365                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14366                        + " mLastMemoryLevel" + mLastMemoryLevel
14367                        + " mLastNumProcesses" + mLastNumProcesses);
14368                long now = SystemClock.uptimeMillis();
14369                pw.print("  mLastIdleTime=");
14370                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14371                        pw.print(" mLowRamSinceLastIdle=");
14372                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14373                        pw.println();
14374            }
14375        }
14376
14377        if (!printedAnything) {
14378            pw.println("  (nothing)");
14379        }
14380    }
14381
14382    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14383            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14384        if (mProcessesToGc.size() > 0) {
14385            boolean printed = false;
14386            long now = SystemClock.uptimeMillis();
14387            for (int i=0; i<mProcessesToGc.size(); i++) {
14388                ProcessRecord proc = mProcessesToGc.get(i);
14389                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14390                    continue;
14391                }
14392                if (!printed) {
14393                    if (needSep) pw.println();
14394                    needSep = true;
14395                    pw.println("  Processes that are waiting to GC:");
14396                    printed = true;
14397                }
14398                pw.print("    Process "); pw.println(proc);
14399                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14400                        pw.print(", last gced=");
14401                        pw.print(now-proc.lastRequestedGc);
14402                        pw.print(" ms ago, last lowMem=");
14403                        pw.print(now-proc.lastLowMemory);
14404                        pw.println(" ms ago");
14405
14406            }
14407        }
14408        return needSep;
14409    }
14410
14411    void printOomLevel(PrintWriter pw, String name, int adj) {
14412        pw.print("    ");
14413        if (adj >= 0) {
14414            pw.print(' ');
14415            if (adj < 10) pw.print(' ');
14416        } else {
14417            if (adj > -10) pw.print(' ');
14418        }
14419        pw.print(adj);
14420        pw.print(": ");
14421        pw.print(name);
14422        pw.print(" (");
14423        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14424        pw.println(")");
14425    }
14426
14427    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14428            int opti, boolean dumpAll) {
14429        boolean needSep = false;
14430
14431        if (mLruProcesses.size() > 0) {
14432            if (needSep) pw.println();
14433            needSep = true;
14434            pw.println("  OOM levels:");
14435            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14436            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14437            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14438            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14439            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14440            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14441            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14442            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14443            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14444            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14445            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14446            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14447            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14448            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14449
14450            if (needSep) pw.println();
14451            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14452                    pw.print(" total, non-act at ");
14453                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14454                    pw.print(", non-svc at ");
14455                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14456                    pw.println("):");
14457            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14458            needSep = true;
14459        }
14460
14461        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14462
14463        pw.println();
14464        pw.println("  mHomeProcess: " + mHomeProcess);
14465        pw.println("  mPreviousProcess: " + mPreviousProcess);
14466        if (mHeavyWeightProcess != null) {
14467            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14468        }
14469
14470        return true;
14471    }
14472
14473    /**
14474     * There are three ways to call this:
14475     *  - no provider specified: dump all the providers
14476     *  - a flattened component name that matched an existing provider was specified as the
14477     *    first arg: dump that one provider
14478     *  - the first arg isn't the flattened component name of an existing provider:
14479     *    dump all providers whose component contains the first arg as a substring
14480     */
14481    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14482            int opti, boolean dumpAll) {
14483        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14484    }
14485
14486    static class ItemMatcher {
14487        ArrayList<ComponentName> components;
14488        ArrayList<String> strings;
14489        ArrayList<Integer> objects;
14490        boolean all;
14491
14492        ItemMatcher() {
14493            all = true;
14494        }
14495
14496        void build(String name) {
14497            ComponentName componentName = ComponentName.unflattenFromString(name);
14498            if (componentName != null) {
14499                if (components == null) {
14500                    components = new ArrayList<ComponentName>();
14501                }
14502                components.add(componentName);
14503                all = false;
14504            } else {
14505                int objectId = 0;
14506                // Not a '/' separated full component name; maybe an object ID?
14507                try {
14508                    objectId = Integer.parseInt(name, 16);
14509                    if (objects == null) {
14510                        objects = new ArrayList<Integer>();
14511                    }
14512                    objects.add(objectId);
14513                    all = false;
14514                } catch (RuntimeException e) {
14515                    // Not an integer; just do string match.
14516                    if (strings == null) {
14517                        strings = new ArrayList<String>();
14518                    }
14519                    strings.add(name);
14520                    all = false;
14521                }
14522            }
14523        }
14524
14525        int build(String[] args, int opti) {
14526            for (; opti<args.length; opti++) {
14527                String name = args[opti];
14528                if ("--".equals(name)) {
14529                    return opti+1;
14530                }
14531                build(name);
14532            }
14533            return opti;
14534        }
14535
14536        boolean match(Object object, ComponentName comp) {
14537            if (all) {
14538                return true;
14539            }
14540            if (components != null) {
14541                for (int i=0; i<components.size(); i++) {
14542                    if (components.get(i).equals(comp)) {
14543                        return true;
14544                    }
14545                }
14546            }
14547            if (objects != null) {
14548                for (int i=0; i<objects.size(); i++) {
14549                    if (System.identityHashCode(object) == objects.get(i)) {
14550                        return true;
14551                    }
14552                }
14553            }
14554            if (strings != null) {
14555                String flat = comp.flattenToString();
14556                for (int i=0; i<strings.size(); i++) {
14557                    if (flat.contains(strings.get(i))) {
14558                        return true;
14559                    }
14560                }
14561            }
14562            return false;
14563        }
14564    }
14565
14566    /**
14567     * There are three things that cmd can be:
14568     *  - a flattened component name that matches an existing activity
14569     *  - the cmd arg isn't the flattened component name of an existing activity:
14570     *    dump all activity whose component contains the cmd as a substring
14571     *  - A hex number of the ActivityRecord object instance.
14572     */
14573    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14574            int opti, boolean dumpAll) {
14575        ArrayList<ActivityRecord> activities;
14576
14577        synchronized (this) {
14578            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14579        }
14580
14581        if (activities.size() <= 0) {
14582            return false;
14583        }
14584
14585        String[] newArgs = new String[args.length - opti];
14586        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14587
14588        TaskRecord lastTask = null;
14589        boolean needSep = false;
14590        for (int i=activities.size()-1; i>=0; i--) {
14591            ActivityRecord r = activities.get(i);
14592            if (needSep) {
14593                pw.println();
14594            }
14595            needSep = true;
14596            synchronized (this) {
14597                if (lastTask != r.task) {
14598                    lastTask = r.task;
14599                    pw.print("TASK "); pw.print(lastTask.affinity);
14600                            pw.print(" id="); pw.println(lastTask.taskId);
14601                    if (dumpAll) {
14602                        lastTask.dump(pw, "  ");
14603                    }
14604                }
14605            }
14606            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14607        }
14608        return true;
14609    }
14610
14611    /**
14612     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14613     * there is a thread associated with the activity.
14614     */
14615    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14616            final ActivityRecord r, String[] args, boolean dumpAll) {
14617        String innerPrefix = prefix + "  ";
14618        synchronized (this) {
14619            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14620                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14621                    pw.print(" pid=");
14622                    if (r.app != null) pw.println(r.app.pid);
14623                    else pw.println("(not running)");
14624            if (dumpAll) {
14625                r.dump(pw, innerPrefix);
14626            }
14627        }
14628        if (r.app != null && r.app.thread != null) {
14629            // flush anything that is already in the PrintWriter since the thread is going
14630            // to write to the file descriptor directly
14631            pw.flush();
14632            try {
14633                TransferPipe tp = new TransferPipe();
14634                try {
14635                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14636                            r.appToken, innerPrefix, args);
14637                    tp.go(fd);
14638                } finally {
14639                    tp.kill();
14640                }
14641            } catch (IOException e) {
14642                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14643            } catch (RemoteException e) {
14644                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14645            }
14646        }
14647    }
14648
14649    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14650            int opti, boolean dumpAll, String dumpPackage) {
14651        boolean needSep = false;
14652        boolean onlyHistory = false;
14653        boolean printedAnything = false;
14654
14655        if ("history".equals(dumpPackage)) {
14656            if (opti < args.length && "-s".equals(args[opti])) {
14657                dumpAll = false;
14658            }
14659            onlyHistory = true;
14660            dumpPackage = null;
14661        }
14662
14663        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14664        if (!onlyHistory && dumpAll) {
14665            if (mRegisteredReceivers.size() > 0) {
14666                boolean printed = false;
14667                Iterator it = mRegisteredReceivers.values().iterator();
14668                while (it.hasNext()) {
14669                    ReceiverList r = (ReceiverList)it.next();
14670                    if (dumpPackage != null && (r.app == null ||
14671                            !dumpPackage.equals(r.app.info.packageName))) {
14672                        continue;
14673                    }
14674                    if (!printed) {
14675                        pw.println("  Registered Receivers:");
14676                        needSep = true;
14677                        printed = true;
14678                        printedAnything = true;
14679                    }
14680                    pw.print("  * "); pw.println(r);
14681                    r.dump(pw, "    ");
14682                }
14683            }
14684
14685            if (mReceiverResolver.dump(pw, needSep ?
14686                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14687                    "    ", dumpPackage, false, false)) {
14688                needSep = true;
14689                printedAnything = true;
14690            }
14691        }
14692
14693        for (BroadcastQueue q : mBroadcastQueues) {
14694            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14695            printedAnything |= needSep;
14696        }
14697
14698        needSep = true;
14699
14700        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14701            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14702                if (needSep) {
14703                    pw.println();
14704                }
14705                needSep = true;
14706                printedAnything = true;
14707                pw.print("  Sticky broadcasts for user ");
14708                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14709                StringBuilder sb = new StringBuilder(128);
14710                for (Map.Entry<String, ArrayList<Intent>> ent
14711                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14712                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14713                    if (dumpAll) {
14714                        pw.println(":");
14715                        ArrayList<Intent> intents = ent.getValue();
14716                        final int N = intents.size();
14717                        for (int i=0; i<N; i++) {
14718                            sb.setLength(0);
14719                            sb.append("    Intent: ");
14720                            intents.get(i).toShortString(sb, false, true, false, false);
14721                            pw.println(sb.toString());
14722                            Bundle bundle = intents.get(i).getExtras();
14723                            if (bundle != null) {
14724                                pw.print("      ");
14725                                pw.println(bundle.toString());
14726                            }
14727                        }
14728                    } else {
14729                        pw.println("");
14730                    }
14731                }
14732            }
14733        }
14734
14735        if (!onlyHistory && dumpAll) {
14736            pw.println();
14737            for (BroadcastQueue queue : mBroadcastQueues) {
14738                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14739                        + queue.mBroadcastsScheduled);
14740            }
14741            pw.println("  mHandler:");
14742            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14743            needSep = true;
14744            printedAnything = true;
14745        }
14746
14747        if (!printedAnything) {
14748            pw.println("  (nothing)");
14749        }
14750    }
14751
14752    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14753            int opti, boolean dumpAll, String dumpPackage) {
14754        boolean needSep;
14755        boolean printedAnything = false;
14756
14757        ItemMatcher matcher = new ItemMatcher();
14758        matcher.build(args, opti);
14759
14760        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14761
14762        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14763        printedAnything |= needSep;
14764
14765        if (mLaunchingProviders.size() > 0) {
14766            boolean printed = false;
14767            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14768                ContentProviderRecord r = mLaunchingProviders.get(i);
14769                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14770                    continue;
14771                }
14772                if (!printed) {
14773                    if (needSep) pw.println();
14774                    needSep = true;
14775                    pw.println("  Launching content providers:");
14776                    printed = true;
14777                    printedAnything = true;
14778                }
14779                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14780                        pw.println(r);
14781            }
14782        }
14783
14784        if (!printedAnything) {
14785            pw.println("  (nothing)");
14786        }
14787    }
14788
14789    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14790            int opti, boolean dumpAll, String dumpPackage) {
14791        boolean needSep = false;
14792        boolean printedAnything = false;
14793
14794        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14795
14796        if (mGrantedUriPermissions.size() > 0) {
14797            boolean printed = false;
14798            int dumpUid = -2;
14799            if (dumpPackage != null) {
14800                try {
14801                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14802                            MATCH_UNINSTALLED_PACKAGES, 0);
14803                } catch (NameNotFoundException e) {
14804                    dumpUid = -1;
14805                }
14806            }
14807            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14808                int uid = mGrantedUriPermissions.keyAt(i);
14809                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14810                    continue;
14811                }
14812                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14813                if (!printed) {
14814                    if (needSep) pw.println();
14815                    needSep = true;
14816                    pw.println("  Granted Uri Permissions:");
14817                    printed = true;
14818                    printedAnything = true;
14819                }
14820                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14821                for (UriPermission perm : perms.values()) {
14822                    pw.print("    "); pw.println(perm);
14823                    if (dumpAll) {
14824                        perm.dump(pw, "      ");
14825                    }
14826                }
14827            }
14828        }
14829
14830        if (!printedAnything) {
14831            pw.println("  (nothing)");
14832        }
14833    }
14834
14835    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14836            int opti, boolean dumpAll, String dumpPackage) {
14837        boolean printed = false;
14838
14839        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14840
14841        if (mIntentSenderRecords.size() > 0) {
14842            Iterator<WeakReference<PendingIntentRecord>> it
14843                    = mIntentSenderRecords.values().iterator();
14844            while (it.hasNext()) {
14845                WeakReference<PendingIntentRecord> ref = it.next();
14846                PendingIntentRecord rec = ref != null ? ref.get(): null;
14847                if (dumpPackage != null && (rec == null
14848                        || !dumpPackage.equals(rec.key.packageName))) {
14849                    continue;
14850                }
14851                printed = true;
14852                if (rec != null) {
14853                    pw.print("  * "); pw.println(rec);
14854                    if (dumpAll) {
14855                        rec.dump(pw, "    ");
14856                    }
14857                } else {
14858                    pw.print("  * "); pw.println(ref);
14859                }
14860            }
14861        }
14862
14863        if (!printed) {
14864            pw.println("  (nothing)");
14865        }
14866    }
14867
14868    private static final int dumpProcessList(PrintWriter pw,
14869            ActivityManagerService service, List list,
14870            String prefix, String normalLabel, String persistentLabel,
14871            String dumpPackage) {
14872        int numPers = 0;
14873        final int N = list.size()-1;
14874        for (int i=N; i>=0; i--) {
14875            ProcessRecord r = (ProcessRecord)list.get(i);
14876            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14877                continue;
14878            }
14879            pw.println(String.format("%s%s #%2d: %s",
14880                    prefix, (r.persistent ? persistentLabel : normalLabel),
14881                    i, r.toString()));
14882            if (r.persistent) {
14883                numPers++;
14884            }
14885        }
14886        return numPers;
14887    }
14888
14889    private static final boolean dumpProcessOomList(PrintWriter pw,
14890            ActivityManagerService service, List<ProcessRecord> origList,
14891            String prefix, String normalLabel, String persistentLabel,
14892            boolean inclDetails, String dumpPackage) {
14893
14894        ArrayList<Pair<ProcessRecord, Integer>> list
14895                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14896        for (int i=0; i<origList.size(); i++) {
14897            ProcessRecord r = origList.get(i);
14898            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14899                continue;
14900            }
14901            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14902        }
14903
14904        if (list.size() <= 0) {
14905            return false;
14906        }
14907
14908        Comparator<Pair<ProcessRecord, Integer>> comparator
14909                = new Comparator<Pair<ProcessRecord, Integer>>() {
14910            @Override
14911            public int compare(Pair<ProcessRecord, Integer> object1,
14912                    Pair<ProcessRecord, Integer> object2) {
14913                if (object1.first.setAdj != object2.first.setAdj) {
14914                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14915                }
14916                if (object1.first.setProcState != object2.first.setProcState) {
14917                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14918                }
14919                if (object1.second.intValue() != object2.second.intValue()) {
14920                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14921                }
14922                return 0;
14923            }
14924        };
14925
14926        Collections.sort(list, comparator);
14927
14928        final long curRealtime = SystemClock.elapsedRealtime();
14929        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14930        final long curUptime = SystemClock.uptimeMillis();
14931        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14932
14933        for (int i=list.size()-1; i>=0; i--) {
14934            ProcessRecord r = list.get(i).first;
14935            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14936            char schedGroup;
14937            switch (r.setSchedGroup) {
14938                case ProcessList.SCHED_GROUP_BACKGROUND:
14939                    schedGroup = 'B';
14940                    break;
14941                case ProcessList.SCHED_GROUP_DEFAULT:
14942                    schedGroup = 'F';
14943                    break;
14944                case ProcessList.SCHED_GROUP_TOP_APP:
14945                    schedGroup = 'T';
14946                    break;
14947                default:
14948                    schedGroup = '?';
14949                    break;
14950            }
14951            char foreground;
14952            if (r.foregroundActivities) {
14953                foreground = 'A';
14954            } else if (r.foregroundServices) {
14955                foreground = 'S';
14956            } else {
14957                foreground = ' ';
14958            }
14959            String procState = ProcessList.makeProcStateString(r.curProcState);
14960            pw.print(prefix);
14961            pw.print(r.persistent ? persistentLabel : normalLabel);
14962            pw.print(" #");
14963            int num = (origList.size()-1)-list.get(i).second;
14964            if (num < 10) pw.print(' ');
14965            pw.print(num);
14966            pw.print(": ");
14967            pw.print(oomAdj);
14968            pw.print(' ');
14969            pw.print(schedGroup);
14970            pw.print('/');
14971            pw.print(foreground);
14972            pw.print('/');
14973            pw.print(procState);
14974            pw.print(" trm:");
14975            if (r.trimMemoryLevel < 10) pw.print(' ');
14976            pw.print(r.trimMemoryLevel);
14977            pw.print(' ');
14978            pw.print(r.toShortString());
14979            pw.print(" (");
14980            pw.print(r.adjType);
14981            pw.println(')');
14982            if (r.adjSource != null || r.adjTarget != null) {
14983                pw.print(prefix);
14984                pw.print("    ");
14985                if (r.adjTarget instanceof ComponentName) {
14986                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14987                } else if (r.adjTarget != null) {
14988                    pw.print(r.adjTarget.toString());
14989                } else {
14990                    pw.print("{null}");
14991                }
14992                pw.print("<=");
14993                if (r.adjSource instanceof ProcessRecord) {
14994                    pw.print("Proc{");
14995                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14996                    pw.println("}");
14997                } else if (r.adjSource != null) {
14998                    pw.println(r.adjSource.toString());
14999                } else {
15000                    pw.println("{null}");
15001                }
15002            }
15003            if (inclDetails) {
15004                pw.print(prefix);
15005                pw.print("    ");
15006                pw.print("oom: max="); pw.print(r.maxAdj);
15007                pw.print(" curRaw="); pw.print(r.curRawAdj);
15008                pw.print(" setRaw="); pw.print(r.setRawAdj);
15009                pw.print(" cur="); pw.print(r.curAdj);
15010                pw.print(" set="); pw.println(r.setAdj);
15011                pw.print(prefix);
15012                pw.print("    ");
15013                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15014                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15015                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15016                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15017                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15018                pw.println();
15019                pw.print(prefix);
15020                pw.print("    ");
15021                pw.print("cached="); pw.print(r.cached);
15022                pw.print(" empty="); pw.print(r.empty);
15023                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15024
15025                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15026                    if (r.lastWakeTime != 0) {
15027                        long wtime;
15028                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15029                        synchronized (stats) {
15030                            wtime = stats.getProcessWakeTime(r.info.uid,
15031                                    r.pid, curRealtime);
15032                        }
15033                        long timeUsed = wtime - r.lastWakeTime;
15034                        pw.print(prefix);
15035                        pw.print("    ");
15036                        pw.print("keep awake over ");
15037                        TimeUtils.formatDuration(realtimeSince, pw);
15038                        pw.print(" used ");
15039                        TimeUtils.formatDuration(timeUsed, pw);
15040                        pw.print(" (");
15041                        pw.print((timeUsed*100)/realtimeSince);
15042                        pw.println("%)");
15043                    }
15044                    if (r.lastCpuTime != 0) {
15045                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15046                        pw.print(prefix);
15047                        pw.print("    ");
15048                        pw.print("run cpu over ");
15049                        TimeUtils.formatDuration(uptimeSince, pw);
15050                        pw.print(" used ");
15051                        TimeUtils.formatDuration(timeUsed, pw);
15052                        pw.print(" (");
15053                        pw.print((timeUsed*100)/uptimeSince);
15054                        pw.println("%)");
15055                    }
15056                }
15057            }
15058        }
15059        return true;
15060    }
15061
15062    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15063            String[] args) {
15064        ArrayList<ProcessRecord> procs;
15065        synchronized (this) {
15066            if (args != null && args.length > start
15067                    && args[start].charAt(0) != '-') {
15068                procs = new ArrayList<ProcessRecord>();
15069                int pid = -1;
15070                try {
15071                    pid = Integer.parseInt(args[start]);
15072                } catch (NumberFormatException e) {
15073                }
15074                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15075                    ProcessRecord proc = mLruProcesses.get(i);
15076                    if (proc.pid == pid) {
15077                        procs.add(proc);
15078                    } else if (allPkgs && proc.pkgList != null
15079                            && proc.pkgList.containsKey(args[start])) {
15080                        procs.add(proc);
15081                    } else if (proc.processName.equals(args[start])) {
15082                        procs.add(proc);
15083                    }
15084                }
15085                if (procs.size() <= 0) {
15086                    return null;
15087                }
15088            } else {
15089                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15090            }
15091        }
15092        return procs;
15093    }
15094
15095    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15096            PrintWriter pw, String[] args) {
15097        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15098        if (procs == null) {
15099            pw.println("No process found for: " + args[0]);
15100            return;
15101        }
15102
15103        long uptime = SystemClock.uptimeMillis();
15104        long realtime = SystemClock.elapsedRealtime();
15105        pw.println("Applications Graphics Acceleration Info:");
15106        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15107
15108        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15109            ProcessRecord r = procs.get(i);
15110            if (r.thread != null) {
15111                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15112                pw.flush();
15113                try {
15114                    TransferPipe tp = new TransferPipe();
15115                    try {
15116                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15117                        tp.go(fd);
15118                    } finally {
15119                        tp.kill();
15120                    }
15121                } catch (IOException e) {
15122                    pw.println("Failure while dumping the app: " + r);
15123                    pw.flush();
15124                } catch (RemoteException e) {
15125                    pw.println("Got a RemoteException while dumping the app " + r);
15126                    pw.flush();
15127                }
15128            }
15129        }
15130    }
15131
15132    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15133        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15134        if (procs == null) {
15135            pw.println("No process found for: " + args[0]);
15136            return;
15137        }
15138
15139        pw.println("Applications Database Info:");
15140
15141        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15142            ProcessRecord r = procs.get(i);
15143            if (r.thread != null) {
15144                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15145                pw.flush();
15146                try {
15147                    TransferPipe tp = new TransferPipe();
15148                    try {
15149                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15150                        tp.go(fd);
15151                    } finally {
15152                        tp.kill();
15153                    }
15154                } catch (IOException e) {
15155                    pw.println("Failure while dumping the app: " + r);
15156                    pw.flush();
15157                } catch (RemoteException e) {
15158                    pw.println("Got a RemoteException while dumping the app " + r);
15159                    pw.flush();
15160                }
15161            }
15162        }
15163    }
15164
15165    final static class MemItem {
15166        final boolean isProc;
15167        final String label;
15168        final String shortLabel;
15169        final long pss;
15170        final long swapPss;
15171        final int id;
15172        final boolean hasActivities;
15173        ArrayList<MemItem> subitems;
15174
15175        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15176                boolean _hasActivities) {
15177            isProc = true;
15178            label = _label;
15179            shortLabel = _shortLabel;
15180            pss = _pss;
15181            swapPss = _swapPss;
15182            id = _id;
15183            hasActivities = _hasActivities;
15184        }
15185
15186        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15187            isProc = false;
15188            label = _label;
15189            shortLabel = _shortLabel;
15190            pss = _pss;
15191            swapPss = _swapPss;
15192            id = _id;
15193            hasActivities = false;
15194        }
15195    }
15196
15197    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15198            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15199        if (sort && !isCompact) {
15200            Collections.sort(items, new Comparator<MemItem>() {
15201                @Override
15202                public int compare(MemItem lhs, MemItem rhs) {
15203                    if (lhs.pss < rhs.pss) {
15204                        return 1;
15205                    } else if (lhs.pss > rhs.pss) {
15206                        return -1;
15207                    }
15208                    return 0;
15209                }
15210            });
15211        }
15212
15213        for (int i=0; i<items.size(); i++) {
15214            MemItem mi = items.get(i);
15215            if (!isCompact) {
15216                if (dumpSwapPss) {
15217                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15218                            mi.label, stringifyKBSize(mi.swapPss));
15219                } else {
15220                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15221                }
15222            } else if (mi.isProc) {
15223                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15224                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15225                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15226                pw.println(mi.hasActivities ? ",a" : ",e");
15227            } else {
15228                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15229                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15230            }
15231            if (mi.subitems != null) {
15232                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15233                        true, isCompact, dumpSwapPss);
15234            }
15235        }
15236    }
15237
15238    // These are in KB.
15239    static final long[] DUMP_MEM_BUCKETS = new long[] {
15240        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15241        120*1024, 160*1024, 200*1024,
15242        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15243        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15244    };
15245
15246    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15247            boolean stackLike) {
15248        int start = label.lastIndexOf('.');
15249        if (start >= 0) start++;
15250        else start = 0;
15251        int end = label.length();
15252        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15253            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15254                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15255                out.append(bucket);
15256                out.append(stackLike ? "MB." : "MB ");
15257                out.append(label, start, end);
15258                return;
15259            }
15260        }
15261        out.append(memKB/1024);
15262        out.append(stackLike ? "MB." : "MB ");
15263        out.append(label, start, end);
15264    }
15265
15266    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15267            ProcessList.NATIVE_ADJ,
15268            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15269            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15270            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15271            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15272            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15273            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15274    };
15275    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15276            "Native",
15277            "System", "Persistent", "Persistent Service", "Foreground",
15278            "Visible", "Perceptible",
15279            "Heavy Weight", "Backup",
15280            "A Services", "Home",
15281            "Previous", "B Services", "Cached"
15282    };
15283    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15284            "native",
15285            "sys", "pers", "persvc", "fore",
15286            "vis", "percept",
15287            "heavy", "backup",
15288            "servicea", "home",
15289            "prev", "serviceb", "cached"
15290    };
15291
15292    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15293            long realtime, boolean isCheckinRequest, boolean isCompact) {
15294        if (isCompact) {
15295            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15296        }
15297        if (isCheckinRequest || isCompact) {
15298            // short checkin version
15299            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15300        } else {
15301            pw.println("Applications Memory Usage (in Kilobytes):");
15302            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15303        }
15304    }
15305
15306    private static final int KSM_SHARED = 0;
15307    private static final int KSM_SHARING = 1;
15308    private static final int KSM_UNSHARED = 2;
15309    private static final int KSM_VOLATILE = 3;
15310
15311    private final long[] getKsmInfo() {
15312        long[] longOut = new long[4];
15313        final int[] SINGLE_LONG_FORMAT = new int[] {
15314            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15315        };
15316        long[] longTmp = new long[1];
15317        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15318                SINGLE_LONG_FORMAT, null, longTmp, null);
15319        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15320        longTmp[0] = 0;
15321        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15322                SINGLE_LONG_FORMAT, null, longTmp, null);
15323        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15324        longTmp[0] = 0;
15325        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15326                SINGLE_LONG_FORMAT, null, longTmp, null);
15327        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15328        longTmp[0] = 0;
15329        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15330                SINGLE_LONG_FORMAT, null, longTmp, null);
15331        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15332        return longOut;
15333    }
15334
15335    private static String stringifySize(long size, int order) {
15336        Locale locale = Locale.US;
15337        switch (order) {
15338            case 1:
15339                return String.format(locale, "%,13d", size);
15340            case 1024:
15341                return String.format(locale, "%,9dK", size / 1024);
15342            case 1024 * 1024:
15343                return String.format(locale, "%,5dM", size / 1024 / 1024);
15344            case 1024 * 1024 * 1024:
15345                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15346            default:
15347                throw new IllegalArgumentException("Invalid size order");
15348        }
15349    }
15350
15351    private static String stringifyKBSize(long size) {
15352        return stringifySize(size * 1024, 1024);
15353    }
15354
15355    // Update this version number in case you change the 'compact' format
15356    private static final int MEMINFO_COMPACT_VERSION = 1;
15357
15358    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15359            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15360        boolean dumpDetails = false;
15361        boolean dumpFullDetails = false;
15362        boolean dumpDalvik = false;
15363        boolean dumpSummaryOnly = false;
15364        boolean dumpUnreachable = false;
15365        boolean oomOnly = false;
15366        boolean isCompact = false;
15367        boolean localOnly = false;
15368        boolean packages = false;
15369        boolean isCheckinRequest = false;
15370        boolean dumpSwapPss = false;
15371
15372        int opti = 0;
15373        while (opti < args.length) {
15374            String opt = args[opti];
15375            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15376                break;
15377            }
15378            opti++;
15379            if ("-a".equals(opt)) {
15380                dumpDetails = true;
15381                dumpFullDetails = true;
15382                dumpDalvik = true;
15383                dumpSwapPss = true;
15384            } else if ("-d".equals(opt)) {
15385                dumpDalvik = true;
15386            } else if ("-c".equals(opt)) {
15387                isCompact = true;
15388            } else if ("-s".equals(opt)) {
15389                dumpDetails = true;
15390                dumpSummaryOnly = true;
15391            } else if ("-S".equals(opt)) {
15392                dumpSwapPss = true;
15393            } else if ("--unreachable".equals(opt)) {
15394                dumpUnreachable = true;
15395            } else if ("--oom".equals(opt)) {
15396                oomOnly = true;
15397            } else if ("--local".equals(opt)) {
15398                localOnly = true;
15399            } else if ("--package".equals(opt)) {
15400                packages = true;
15401            } else if ("--checkin".equals(opt)) {
15402                isCheckinRequest = true;
15403
15404            } else if ("-h".equals(opt)) {
15405                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15406                pw.println("  -a: include all available information for each process.");
15407                pw.println("  -d: include dalvik details.");
15408                pw.println("  -c: dump in a compact machine-parseable representation.");
15409                pw.println("  -s: dump only summary of application memory usage.");
15410                pw.println("  -S: dump also SwapPss.");
15411                pw.println("  --oom: only show processes organized by oom adj.");
15412                pw.println("  --local: only collect details locally, don't call process.");
15413                pw.println("  --package: interpret process arg as package, dumping all");
15414                pw.println("             processes that have loaded that package.");
15415                pw.println("  --checkin: dump data for a checkin");
15416                pw.println("If [process] is specified it can be the name or ");
15417                pw.println("pid of a specific process to dump.");
15418                return;
15419            } else {
15420                pw.println("Unknown argument: " + opt + "; use -h for help");
15421            }
15422        }
15423
15424        long uptime = SystemClock.uptimeMillis();
15425        long realtime = SystemClock.elapsedRealtime();
15426        final long[] tmpLong = new long[1];
15427
15428        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15429        if (procs == null) {
15430            // No Java processes.  Maybe they want to print a native process.
15431            if (args != null && args.length > opti
15432                    && args[opti].charAt(0) != '-') {
15433                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15434                        = new ArrayList<ProcessCpuTracker.Stats>();
15435                updateCpuStatsNow();
15436                int findPid = -1;
15437                try {
15438                    findPid = Integer.parseInt(args[opti]);
15439                } catch (NumberFormatException e) {
15440                }
15441                synchronized (mProcessCpuTracker) {
15442                    final int N = mProcessCpuTracker.countStats();
15443                    for (int i=0; i<N; i++) {
15444                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15445                        if (st.pid == findPid || (st.baseName != null
15446                                && st.baseName.equals(args[opti]))) {
15447                            nativeProcs.add(st);
15448                        }
15449                    }
15450                }
15451                if (nativeProcs.size() > 0) {
15452                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15453                            isCompact);
15454                    Debug.MemoryInfo mi = null;
15455                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15456                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15457                        final int pid = r.pid;
15458                        if (!isCheckinRequest && dumpDetails) {
15459                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15460                        }
15461                        if (mi == null) {
15462                            mi = new Debug.MemoryInfo();
15463                        }
15464                        if (dumpDetails || (!brief && !oomOnly)) {
15465                            Debug.getMemoryInfo(pid, mi);
15466                        } else {
15467                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15468                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15469                        }
15470                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15471                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15472                        if (isCheckinRequest) {
15473                            pw.println();
15474                        }
15475                    }
15476                    return;
15477                }
15478            }
15479            pw.println("No process found for: " + args[opti]);
15480            return;
15481        }
15482
15483        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15484            dumpDetails = true;
15485        }
15486
15487        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15488
15489        String[] innerArgs = new String[args.length-opti];
15490        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15491
15492        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15493        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15494        long nativePss = 0;
15495        long nativeSwapPss = 0;
15496        long dalvikPss = 0;
15497        long dalvikSwapPss = 0;
15498        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15499                EmptyArray.LONG;
15500        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15501                EmptyArray.LONG;
15502        long otherPss = 0;
15503        long otherSwapPss = 0;
15504        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15505        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15506
15507        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15508        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15509        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15510                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15511
15512        long totalPss = 0;
15513        long totalSwapPss = 0;
15514        long cachedPss = 0;
15515        long cachedSwapPss = 0;
15516        boolean hasSwapPss = false;
15517
15518        Debug.MemoryInfo mi = null;
15519        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15520            final ProcessRecord r = procs.get(i);
15521            final IApplicationThread thread;
15522            final int pid;
15523            final int oomAdj;
15524            final boolean hasActivities;
15525            synchronized (this) {
15526                thread = r.thread;
15527                pid = r.pid;
15528                oomAdj = r.getSetAdjWithServices();
15529                hasActivities = r.activities.size() > 0;
15530            }
15531            if (thread != null) {
15532                if (!isCheckinRequest && dumpDetails) {
15533                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15534                }
15535                if (mi == null) {
15536                    mi = new Debug.MemoryInfo();
15537                }
15538                if (dumpDetails || (!brief && !oomOnly)) {
15539                    Debug.getMemoryInfo(pid, mi);
15540                    hasSwapPss = mi.hasSwappedOutPss;
15541                } else {
15542                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15543                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15544                }
15545                if (dumpDetails) {
15546                    if (localOnly) {
15547                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15548                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15549                        if (isCheckinRequest) {
15550                            pw.println();
15551                        }
15552                    } else {
15553                        try {
15554                            pw.flush();
15555                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15556                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15557                        } catch (RemoteException e) {
15558                            if (!isCheckinRequest) {
15559                                pw.println("Got RemoteException!");
15560                                pw.flush();
15561                            }
15562                        }
15563                    }
15564                }
15565
15566                final long myTotalPss = mi.getTotalPss();
15567                final long myTotalUss = mi.getTotalUss();
15568                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15569
15570                synchronized (this) {
15571                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15572                        // Record this for posterity if the process has been stable.
15573                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15574                    }
15575                }
15576
15577                if (!isCheckinRequest && mi != null) {
15578                    totalPss += myTotalPss;
15579                    totalSwapPss += myTotalSwapPss;
15580                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15581                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15582                            myTotalSwapPss, pid, hasActivities);
15583                    procMems.add(pssItem);
15584                    procMemsMap.put(pid, pssItem);
15585
15586                    nativePss += mi.nativePss;
15587                    nativeSwapPss += mi.nativeSwappedOutPss;
15588                    dalvikPss += mi.dalvikPss;
15589                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15590                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15591                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15592                        dalvikSubitemSwapPss[j] +=
15593                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15594                    }
15595                    otherPss += mi.otherPss;
15596                    otherSwapPss += mi.otherSwappedOutPss;
15597                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15598                        long mem = mi.getOtherPss(j);
15599                        miscPss[j] += mem;
15600                        otherPss -= mem;
15601                        mem = mi.getOtherSwappedOutPss(j);
15602                        miscSwapPss[j] += mem;
15603                        otherSwapPss -= mem;
15604                    }
15605
15606                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15607                        cachedPss += myTotalPss;
15608                        cachedSwapPss += myTotalSwapPss;
15609                    }
15610
15611                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15612                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
15613                                || oomIndex == (oomPss.length-1)) {
15614                            oomPss[oomIndex] += myTotalPss;
15615                            oomSwapPss[oomIndex] += myTotalSwapPss;
15616                            if (oomProcs[oomIndex] == null) {
15617                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15618                            }
15619                            oomProcs[oomIndex].add(pssItem);
15620                            break;
15621                        }
15622                    }
15623                }
15624            }
15625        }
15626
15627        long nativeProcTotalPss = 0;
15628
15629        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15630            // If we are showing aggregations, also look for native processes to
15631            // include so that our aggregations are more accurate.
15632            updateCpuStatsNow();
15633            mi = null;
15634            synchronized (mProcessCpuTracker) {
15635                final int N = mProcessCpuTracker.countStats();
15636                for (int i=0; i<N; i++) {
15637                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15638                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15639                        if (mi == null) {
15640                            mi = new Debug.MemoryInfo();
15641                        }
15642                        if (!brief && !oomOnly) {
15643                            Debug.getMemoryInfo(st.pid, mi);
15644                        } else {
15645                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15646                            mi.nativePrivateDirty = (int)tmpLong[0];
15647                        }
15648
15649                        final long myTotalPss = mi.getTotalPss();
15650                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15651                        totalPss += myTotalPss;
15652                        nativeProcTotalPss += myTotalPss;
15653
15654                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15655                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15656                        procMems.add(pssItem);
15657
15658                        nativePss += mi.nativePss;
15659                        nativeSwapPss += mi.nativeSwappedOutPss;
15660                        dalvikPss += mi.dalvikPss;
15661                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15662                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15663                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15664                            dalvikSubitemSwapPss[j] +=
15665                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15666                        }
15667                        otherPss += mi.otherPss;
15668                        otherSwapPss += mi.otherSwappedOutPss;
15669                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15670                            long mem = mi.getOtherPss(j);
15671                            miscPss[j] += mem;
15672                            otherPss -= mem;
15673                            mem = mi.getOtherSwappedOutPss(j);
15674                            miscSwapPss[j] += mem;
15675                            otherSwapPss -= mem;
15676                        }
15677                        oomPss[0] += myTotalPss;
15678                        oomSwapPss[0] += myTotalSwapPss;
15679                        if (oomProcs[0] == null) {
15680                            oomProcs[0] = new ArrayList<MemItem>();
15681                        }
15682                        oomProcs[0].add(pssItem);
15683                    }
15684                }
15685            }
15686
15687            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15688
15689            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15690            final MemItem dalvikItem =
15691                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15692            if (dalvikSubitemPss.length > 0) {
15693                dalvikItem.subitems = new ArrayList<MemItem>();
15694                for (int j=0; j<dalvikSubitemPss.length; j++) {
15695                    final String name = Debug.MemoryInfo.getOtherLabel(
15696                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15697                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15698                                    dalvikSubitemSwapPss[j], j));
15699                }
15700            }
15701            catMems.add(dalvikItem);
15702            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15703            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15704                String label = Debug.MemoryInfo.getOtherLabel(j);
15705                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15706            }
15707
15708            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15709            for (int j=0; j<oomPss.length; j++) {
15710                if (oomPss[j] != 0) {
15711                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15712                            : DUMP_MEM_OOM_LABEL[j];
15713                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15714                            DUMP_MEM_OOM_ADJ[j]);
15715                    item.subitems = oomProcs[j];
15716                    oomMems.add(item);
15717                }
15718            }
15719
15720            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15721            if (!brief && !oomOnly && !isCompact) {
15722                pw.println();
15723                pw.println("Total PSS by process:");
15724                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15725                pw.println();
15726            }
15727            if (!isCompact) {
15728                pw.println("Total PSS by OOM adjustment:");
15729            }
15730            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15731            if (!brief && !oomOnly) {
15732                PrintWriter out = categoryPw != null ? categoryPw : pw;
15733                if (!isCompact) {
15734                    out.println();
15735                    out.println("Total PSS by category:");
15736                }
15737                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15738            }
15739            if (!isCompact) {
15740                pw.println();
15741            }
15742            MemInfoReader memInfo = new MemInfoReader();
15743            memInfo.readMemInfo();
15744            if (nativeProcTotalPss > 0) {
15745                synchronized (this) {
15746                    final long cachedKb = memInfo.getCachedSizeKb();
15747                    final long freeKb = memInfo.getFreeSizeKb();
15748                    final long zramKb = memInfo.getZramTotalSizeKb();
15749                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15750                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15751                            kernelKb*1024, nativeProcTotalPss*1024);
15752                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15753                            nativeProcTotalPss);
15754                }
15755            }
15756            if (!brief) {
15757                if (!isCompact) {
15758                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15759                    pw.print(" (status ");
15760                    switch (mLastMemoryLevel) {
15761                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15762                            pw.println("normal)");
15763                            break;
15764                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15765                            pw.println("moderate)");
15766                            break;
15767                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15768                            pw.println("low)");
15769                            break;
15770                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15771                            pw.println("critical)");
15772                            break;
15773                        default:
15774                            pw.print(mLastMemoryLevel);
15775                            pw.println(")");
15776                            break;
15777                    }
15778                    pw.print(" Free RAM: ");
15779                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15780                            + memInfo.getFreeSizeKb()));
15781                    pw.print(" (");
15782                    pw.print(stringifyKBSize(cachedPss));
15783                    pw.print(" cached pss + ");
15784                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15785                    pw.print(" cached kernel + ");
15786                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15787                    pw.println(" free)");
15788                } else {
15789                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15790                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15791                            + memInfo.getFreeSizeKb()); pw.print(",");
15792                    pw.println(totalPss - cachedPss);
15793                }
15794            }
15795            long lostRAM = memInfo.getTotalSizeKb()
15796                    - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15797                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15798            if (!isCompact) {
15799                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15800                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15801                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15802                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15803                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15804            } else {
15805                pw.print("lostram,"); pw.println(lostRAM);
15806            }
15807            if (!brief) {
15808                if (memInfo.getZramTotalSizeKb() != 0) {
15809                    if (!isCompact) {
15810                        pw.print("     ZRAM: ");
15811                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15812                                pw.print(" physical used for ");
15813                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15814                                        - memInfo.getSwapFreeSizeKb()));
15815                                pw.print(" in swap (");
15816                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15817                                pw.println(" total swap)");
15818                    } else {
15819                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15820                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15821                                pw.println(memInfo.getSwapFreeSizeKb());
15822                    }
15823                }
15824                final long[] ksm = getKsmInfo();
15825                if (!isCompact) {
15826                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15827                            || ksm[KSM_VOLATILE] != 0) {
15828                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15829                                pw.print(" saved from shared ");
15830                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15831                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15832                                pw.print(" unshared; ");
15833                                pw.print(stringifyKBSize(
15834                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15835                    }
15836                    pw.print("   Tuning: ");
15837                    pw.print(ActivityManager.staticGetMemoryClass());
15838                    pw.print(" (large ");
15839                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15840                    pw.print("), oom ");
15841                    pw.print(stringifySize(
15842                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15843                    pw.print(", restore limit ");
15844                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15845                    if (ActivityManager.isLowRamDeviceStatic()) {
15846                        pw.print(" (low-ram)");
15847                    }
15848                    if (ActivityManager.isHighEndGfx()) {
15849                        pw.print(" (high-end-gfx)");
15850                    }
15851                    pw.println();
15852                } else {
15853                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15854                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15855                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15856                    pw.print("tuning,");
15857                    pw.print(ActivityManager.staticGetMemoryClass());
15858                    pw.print(',');
15859                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15860                    pw.print(',');
15861                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15862                    if (ActivityManager.isLowRamDeviceStatic()) {
15863                        pw.print(",low-ram");
15864                    }
15865                    if (ActivityManager.isHighEndGfx()) {
15866                        pw.print(",high-end-gfx");
15867                    }
15868                    pw.println();
15869                }
15870            }
15871        }
15872    }
15873
15874    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15875            long memtrack, String name) {
15876        sb.append("  ");
15877        sb.append(ProcessList.makeOomAdjString(oomAdj));
15878        sb.append(' ');
15879        sb.append(ProcessList.makeProcStateString(procState));
15880        sb.append(' ');
15881        ProcessList.appendRamKb(sb, pss);
15882        sb.append(": ");
15883        sb.append(name);
15884        if (memtrack > 0) {
15885            sb.append(" (");
15886            sb.append(stringifyKBSize(memtrack));
15887            sb.append(" memtrack)");
15888        }
15889    }
15890
15891    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15892        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15893        sb.append(" (pid ");
15894        sb.append(mi.pid);
15895        sb.append(") ");
15896        sb.append(mi.adjType);
15897        sb.append('\n');
15898        if (mi.adjReason != null) {
15899            sb.append("                      ");
15900            sb.append(mi.adjReason);
15901            sb.append('\n');
15902        }
15903    }
15904
15905    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15906        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15907        for (int i=0, N=memInfos.size(); i<N; i++) {
15908            ProcessMemInfo mi = memInfos.get(i);
15909            infoMap.put(mi.pid, mi);
15910        }
15911        updateCpuStatsNow();
15912        long[] memtrackTmp = new long[1];
15913        synchronized (mProcessCpuTracker) {
15914            final int N = mProcessCpuTracker.countStats();
15915            for (int i=0; i<N; i++) {
15916                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15917                if (st.vsize > 0) {
15918                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15919                    if (pss > 0) {
15920                        if (infoMap.indexOfKey(st.pid) < 0) {
15921                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15922                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15923                            mi.pss = pss;
15924                            mi.memtrack = memtrackTmp[0];
15925                            memInfos.add(mi);
15926                        }
15927                    }
15928                }
15929            }
15930        }
15931
15932        long totalPss = 0;
15933        long totalMemtrack = 0;
15934        for (int i=0, N=memInfos.size(); i<N; i++) {
15935            ProcessMemInfo mi = memInfos.get(i);
15936            if (mi.pss == 0) {
15937                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15938                mi.memtrack = memtrackTmp[0];
15939            }
15940            totalPss += mi.pss;
15941            totalMemtrack += mi.memtrack;
15942        }
15943        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15944            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15945                if (lhs.oomAdj != rhs.oomAdj) {
15946                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15947                }
15948                if (lhs.pss != rhs.pss) {
15949                    return lhs.pss < rhs.pss ? 1 : -1;
15950                }
15951                return 0;
15952            }
15953        });
15954
15955        StringBuilder tag = new StringBuilder(128);
15956        StringBuilder stack = new StringBuilder(128);
15957        tag.append("Low on memory -- ");
15958        appendMemBucket(tag, totalPss, "total", false);
15959        appendMemBucket(stack, totalPss, "total", true);
15960
15961        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15962        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15963        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15964
15965        boolean firstLine = true;
15966        int lastOomAdj = Integer.MIN_VALUE;
15967        long extraNativeRam = 0;
15968        long extraNativeMemtrack = 0;
15969        long cachedPss = 0;
15970        for (int i=0, N=memInfos.size(); i<N; i++) {
15971            ProcessMemInfo mi = memInfos.get(i);
15972
15973            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15974                cachedPss += mi.pss;
15975            }
15976
15977            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15978                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15979                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15980                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15981                if (lastOomAdj != mi.oomAdj) {
15982                    lastOomAdj = mi.oomAdj;
15983                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15984                        tag.append(" / ");
15985                    }
15986                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15987                        if (firstLine) {
15988                            stack.append(":");
15989                            firstLine = false;
15990                        }
15991                        stack.append("\n\t at ");
15992                    } else {
15993                        stack.append("$");
15994                    }
15995                } else {
15996                    tag.append(" ");
15997                    stack.append("$");
15998                }
15999                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16000                    appendMemBucket(tag, mi.pss, mi.name, false);
16001                }
16002                appendMemBucket(stack, mi.pss, mi.name, true);
16003                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16004                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16005                    stack.append("(");
16006                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16007                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16008                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16009                            stack.append(":");
16010                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16011                        }
16012                    }
16013                    stack.append(")");
16014                }
16015            }
16016
16017            appendMemInfo(fullNativeBuilder, mi);
16018            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16019                // The short form only has native processes that are >= 512K.
16020                if (mi.pss >= 512) {
16021                    appendMemInfo(shortNativeBuilder, mi);
16022                } else {
16023                    extraNativeRam += mi.pss;
16024                    extraNativeMemtrack += mi.memtrack;
16025                }
16026            } else {
16027                // Short form has all other details, but if we have collected RAM
16028                // from smaller native processes let's dump a summary of that.
16029                if (extraNativeRam > 0) {
16030                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16031                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16032                    shortNativeBuilder.append('\n');
16033                    extraNativeRam = 0;
16034                }
16035                appendMemInfo(fullJavaBuilder, mi);
16036            }
16037        }
16038
16039        fullJavaBuilder.append("           ");
16040        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16041        fullJavaBuilder.append(": TOTAL");
16042        if (totalMemtrack > 0) {
16043            fullJavaBuilder.append(" (");
16044            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16045            fullJavaBuilder.append(" memtrack)");
16046        } else {
16047        }
16048        fullJavaBuilder.append("\n");
16049
16050        MemInfoReader memInfo = new MemInfoReader();
16051        memInfo.readMemInfo();
16052        final long[] infos = memInfo.getRawInfo();
16053
16054        StringBuilder memInfoBuilder = new StringBuilder(1024);
16055        Debug.getMemInfo(infos);
16056        memInfoBuilder.append("  MemInfo: ");
16057        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16058        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16059        memInfoBuilder.append(stringifyKBSize(
16060                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16061        memInfoBuilder.append(stringifyKBSize(
16062                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16063        memInfoBuilder.append(stringifyKBSize(
16064                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16065        memInfoBuilder.append("           ");
16066        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16067        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16068        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16069        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16070        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16071            memInfoBuilder.append("  ZRAM: ");
16072            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16073            memInfoBuilder.append(" RAM, ");
16074            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16075            memInfoBuilder.append(" swap total, ");
16076            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16077            memInfoBuilder.append(" swap free\n");
16078        }
16079        final long[] ksm = getKsmInfo();
16080        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16081                || ksm[KSM_VOLATILE] != 0) {
16082            memInfoBuilder.append("  KSM: ");
16083            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16084            memInfoBuilder.append(" saved from shared ");
16085            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16086            memInfoBuilder.append("\n       ");
16087            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16088            memInfoBuilder.append(" unshared; ");
16089            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16090            memInfoBuilder.append(" volatile\n");
16091        }
16092        memInfoBuilder.append("  Free RAM: ");
16093        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16094                + memInfo.getFreeSizeKb()));
16095        memInfoBuilder.append("\n");
16096        memInfoBuilder.append("  Used RAM: ");
16097        memInfoBuilder.append(stringifyKBSize(
16098                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16099        memInfoBuilder.append("\n");
16100        memInfoBuilder.append("  Lost RAM: ");
16101        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16102                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16103                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16104        memInfoBuilder.append("\n");
16105        Slog.i(TAG, "Low on memory:");
16106        Slog.i(TAG, shortNativeBuilder.toString());
16107        Slog.i(TAG, fullJavaBuilder.toString());
16108        Slog.i(TAG, memInfoBuilder.toString());
16109
16110        StringBuilder dropBuilder = new StringBuilder(1024);
16111        /*
16112        StringWriter oomSw = new StringWriter();
16113        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16114        StringWriter catSw = new StringWriter();
16115        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16116        String[] emptyArgs = new String[] { };
16117        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16118        oomPw.flush();
16119        String oomString = oomSw.toString();
16120        */
16121        dropBuilder.append("Low on memory:");
16122        dropBuilder.append(stack);
16123        dropBuilder.append('\n');
16124        dropBuilder.append(fullNativeBuilder);
16125        dropBuilder.append(fullJavaBuilder);
16126        dropBuilder.append('\n');
16127        dropBuilder.append(memInfoBuilder);
16128        dropBuilder.append('\n');
16129        /*
16130        dropBuilder.append(oomString);
16131        dropBuilder.append('\n');
16132        */
16133        StringWriter catSw = new StringWriter();
16134        synchronized (ActivityManagerService.this) {
16135            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16136            String[] emptyArgs = new String[] { };
16137            catPw.println();
16138            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16139            catPw.println();
16140            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16141                    false, false, null);
16142            catPw.println();
16143            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16144            catPw.flush();
16145        }
16146        dropBuilder.append(catSw.toString());
16147        addErrorToDropBox("lowmem", null, "system_server", null,
16148                null, tag.toString(), dropBuilder.toString(), null, null);
16149        //Slog.i(TAG, "Sent to dropbox:");
16150        //Slog.i(TAG, dropBuilder.toString());
16151        synchronized (ActivityManagerService.this) {
16152            long now = SystemClock.uptimeMillis();
16153            if (mLastMemUsageReportTime < now) {
16154                mLastMemUsageReportTime = now;
16155            }
16156        }
16157    }
16158
16159    /**
16160     * Searches array of arguments for the specified string
16161     * @param args array of argument strings
16162     * @param value value to search for
16163     * @return true if the value is contained in the array
16164     */
16165    private static boolean scanArgs(String[] args, String value) {
16166        if (args != null) {
16167            for (String arg : args) {
16168                if (value.equals(arg)) {
16169                    return true;
16170                }
16171            }
16172        }
16173        return false;
16174    }
16175
16176    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16177            ContentProviderRecord cpr, boolean always) {
16178        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16179
16180        if (!inLaunching || always) {
16181            synchronized (cpr) {
16182                cpr.launchingApp = null;
16183                cpr.notifyAll();
16184            }
16185            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16186            String names[] = cpr.info.authority.split(";");
16187            for (int j = 0; j < names.length; j++) {
16188                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16189            }
16190        }
16191
16192        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16193            ContentProviderConnection conn = cpr.connections.get(i);
16194            if (conn.waiting) {
16195                // If this connection is waiting for the provider, then we don't
16196                // need to mess with its process unless we are always removing
16197                // or for some reason the provider is not currently launching.
16198                if (inLaunching && !always) {
16199                    continue;
16200                }
16201            }
16202            ProcessRecord capp = conn.client;
16203            conn.dead = true;
16204            if (conn.stableCount > 0) {
16205                if (!capp.persistent && capp.thread != null
16206                        && capp.pid != 0
16207                        && capp.pid != MY_PID) {
16208                    capp.kill("depends on provider "
16209                            + cpr.name.flattenToShortString()
16210                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16211                }
16212            } else if (capp.thread != null && conn.provider.provider != null) {
16213                try {
16214                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16215                } catch (RemoteException e) {
16216                }
16217                // In the protocol here, we don't expect the client to correctly
16218                // clean up this connection, we'll just remove it.
16219                cpr.connections.remove(i);
16220                if (conn.client.conProviders.remove(conn)) {
16221                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16222                }
16223            }
16224        }
16225
16226        if (inLaunching && always) {
16227            mLaunchingProviders.remove(cpr);
16228        }
16229        return inLaunching;
16230    }
16231
16232    /**
16233     * Main code for cleaning up a process when it has gone away.  This is
16234     * called both as a result of the process dying, or directly when stopping
16235     * a process when running in single process mode.
16236     *
16237     * @return Returns true if the given process has been restarted, so the
16238     * app that was passed in must remain on the process lists.
16239     */
16240    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16241            boolean restarting, boolean allowRestart, int index) {
16242        if (index >= 0) {
16243            removeLruProcessLocked(app);
16244            ProcessList.remove(app.pid);
16245        }
16246
16247        mProcessesToGc.remove(app);
16248        mPendingPssProcesses.remove(app);
16249
16250        // Dismiss any open dialogs.
16251        if (app.crashDialog != null && !app.forceCrashReport) {
16252            app.crashDialog.dismiss();
16253            app.crashDialog = null;
16254        }
16255        if (app.anrDialog != null) {
16256            app.anrDialog.dismiss();
16257            app.anrDialog = null;
16258        }
16259        if (app.waitDialog != null) {
16260            app.waitDialog.dismiss();
16261            app.waitDialog = null;
16262        }
16263
16264        app.crashing = false;
16265        app.notResponding = false;
16266
16267        app.resetPackageList(mProcessStats);
16268        app.unlinkDeathRecipient();
16269        app.makeInactive(mProcessStats);
16270        app.waitingToKill = null;
16271        app.forcingToForeground = null;
16272        updateProcessForegroundLocked(app, false, false);
16273        app.foregroundActivities = false;
16274        app.hasShownUi = false;
16275        app.treatLikeActivity = false;
16276        app.hasAboveClient = false;
16277        app.hasClientActivities = false;
16278
16279        mServices.killServicesLocked(app, allowRestart);
16280
16281        boolean restart = false;
16282
16283        // Remove published content providers.
16284        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16285            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16286            final boolean always = app.bad || !allowRestart;
16287            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16288            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16289                // We left the provider in the launching list, need to
16290                // restart it.
16291                restart = true;
16292            }
16293
16294            cpr.provider = null;
16295            cpr.proc = null;
16296        }
16297        app.pubProviders.clear();
16298
16299        // Take care of any launching providers waiting for this process.
16300        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16301            restart = true;
16302        }
16303
16304        // Unregister from connected content providers.
16305        if (!app.conProviders.isEmpty()) {
16306            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16307                ContentProviderConnection conn = app.conProviders.get(i);
16308                conn.provider.connections.remove(conn);
16309                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16310                        conn.provider.name);
16311            }
16312            app.conProviders.clear();
16313        }
16314
16315        // At this point there may be remaining entries in mLaunchingProviders
16316        // where we were the only one waiting, so they are no longer of use.
16317        // Look for these and clean up if found.
16318        // XXX Commented out for now.  Trying to figure out a way to reproduce
16319        // the actual situation to identify what is actually going on.
16320        if (false) {
16321            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16322                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16323                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16324                    synchronized (cpr) {
16325                        cpr.launchingApp = null;
16326                        cpr.notifyAll();
16327                    }
16328                }
16329            }
16330        }
16331
16332        skipCurrentReceiverLocked(app);
16333
16334        // Unregister any receivers.
16335        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16336            removeReceiverLocked(app.receivers.valueAt(i));
16337        }
16338        app.receivers.clear();
16339
16340        // If the app is undergoing backup, tell the backup manager about it
16341        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16342            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16343                    + mBackupTarget.appInfo + " died during backup");
16344            try {
16345                IBackupManager bm = IBackupManager.Stub.asInterface(
16346                        ServiceManager.getService(Context.BACKUP_SERVICE));
16347                bm.agentDisconnected(app.info.packageName);
16348            } catch (RemoteException e) {
16349                // can't happen; backup manager is local
16350            }
16351        }
16352
16353        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16354            ProcessChangeItem item = mPendingProcessChanges.get(i);
16355            if (item.pid == app.pid) {
16356                mPendingProcessChanges.remove(i);
16357                mAvailProcessChanges.add(item);
16358            }
16359        }
16360        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16361                null).sendToTarget();
16362
16363        // If the caller is restarting this app, then leave it in its
16364        // current lists and let the caller take care of it.
16365        if (restarting) {
16366            return false;
16367        }
16368
16369        if (!app.persistent || app.isolated) {
16370            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16371                    "Removing non-persistent process during cleanup: " + app);
16372            removeProcessNameLocked(app.processName, app.uid);
16373            if (mHeavyWeightProcess == app) {
16374                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16375                        mHeavyWeightProcess.userId, 0));
16376                mHeavyWeightProcess = null;
16377            }
16378        } else if (!app.removed) {
16379            // This app is persistent, so we need to keep its record around.
16380            // If it is not already on the pending app list, add it there
16381            // and start a new process for it.
16382            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16383                mPersistentStartingProcesses.add(app);
16384                restart = true;
16385            }
16386        }
16387        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16388                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16389        mProcessesOnHold.remove(app);
16390
16391        if (app == mHomeProcess) {
16392            mHomeProcess = null;
16393        }
16394        if (app == mPreviousProcess) {
16395            mPreviousProcess = null;
16396        }
16397
16398        if (restart && !app.isolated) {
16399            // We have components that still need to be running in the
16400            // process, so re-launch it.
16401            if (index < 0) {
16402                ProcessList.remove(app.pid);
16403            }
16404            addProcessNameLocked(app);
16405            startProcessLocked(app, "restart", app.processName);
16406            return true;
16407        } else if (app.pid > 0 && app.pid != MY_PID) {
16408            // Goodbye!
16409            boolean removed;
16410            synchronized (mPidsSelfLocked) {
16411                mPidsSelfLocked.remove(app.pid);
16412                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16413            }
16414            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16415            if (app.isolated) {
16416                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16417            }
16418            app.setPid(0);
16419        }
16420        return false;
16421    }
16422
16423    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16424        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16425            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16426            if (cpr.launchingApp == app) {
16427                return true;
16428            }
16429        }
16430        return false;
16431    }
16432
16433    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16434        // Look through the content providers we are waiting to have launched,
16435        // and if any run in this process then either schedule a restart of
16436        // the process or kill the client waiting for it if this process has
16437        // gone bad.
16438        boolean restart = false;
16439        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16440            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16441            if (cpr.launchingApp == app) {
16442                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16443                    restart = true;
16444                } else {
16445                    removeDyingProviderLocked(app, cpr, true);
16446                }
16447            }
16448        }
16449        return restart;
16450    }
16451
16452    // =========================================================
16453    // SERVICES
16454    // =========================================================
16455
16456    @Override
16457    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16458            int flags) {
16459        enforceNotIsolatedCaller("getServices");
16460        synchronized (this) {
16461            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16462        }
16463    }
16464
16465    @Override
16466    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16467        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16468        synchronized (this) {
16469            return mServices.getRunningServiceControlPanelLocked(name);
16470        }
16471    }
16472
16473    @Override
16474    public ComponentName startService(IApplicationThread caller, Intent service,
16475            String resolvedType, String callingPackage, int userId)
16476            throws TransactionTooLargeException {
16477        enforceNotIsolatedCaller("startService");
16478        // Refuse possible leaked file descriptors
16479        if (service != null && service.hasFileDescriptors() == true) {
16480            throw new IllegalArgumentException("File descriptors passed in Intent");
16481        }
16482
16483        if (callingPackage == null) {
16484            throw new IllegalArgumentException("callingPackage cannot be null");
16485        }
16486
16487        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16488                "startService: " + service + " type=" + resolvedType);
16489        synchronized(this) {
16490            final int callingPid = Binder.getCallingPid();
16491            final int callingUid = Binder.getCallingUid();
16492            final long origId = Binder.clearCallingIdentity();
16493            ComponentName res = mServices.startServiceLocked(caller, service,
16494                    resolvedType, callingPid, callingUid, callingPackage, userId);
16495            Binder.restoreCallingIdentity(origId);
16496            return res;
16497        }
16498    }
16499
16500    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16501            String callingPackage, int userId)
16502            throws TransactionTooLargeException {
16503        synchronized(this) {
16504            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16505                    "startServiceInPackage: " + service + " type=" + resolvedType);
16506            final long origId = Binder.clearCallingIdentity();
16507            ComponentName res = mServices.startServiceLocked(null, service,
16508                    resolvedType, -1, uid, callingPackage, userId);
16509            Binder.restoreCallingIdentity(origId);
16510            return res;
16511        }
16512    }
16513
16514    @Override
16515    public int stopService(IApplicationThread caller, Intent service,
16516            String resolvedType, int userId) {
16517        enforceNotIsolatedCaller("stopService");
16518        // Refuse possible leaked file descriptors
16519        if (service != null && service.hasFileDescriptors() == true) {
16520            throw new IllegalArgumentException("File descriptors passed in Intent");
16521        }
16522
16523        synchronized(this) {
16524            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16525        }
16526    }
16527
16528    @Override
16529    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16530        enforceNotIsolatedCaller("peekService");
16531        // Refuse possible leaked file descriptors
16532        if (service != null && service.hasFileDescriptors() == true) {
16533            throw new IllegalArgumentException("File descriptors passed in Intent");
16534        }
16535
16536        if (callingPackage == null) {
16537            throw new IllegalArgumentException("callingPackage cannot be null");
16538        }
16539
16540        synchronized(this) {
16541            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16542        }
16543    }
16544
16545    @Override
16546    public boolean stopServiceToken(ComponentName className, IBinder token,
16547            int startId) {
16548        synchronized(this) {
16549            return mServices.stopServiceTokenLocked(className, token, startId);
16550        }
16551    }
16552
16553    @Override
16554    public void setServiceForeground(ComponentName className, IBinder token,
16555            int id, Notification notification, boolean removeNotification) {
16556        synchronized(this) {
16557            mServices.setServiceForegroundLocked(className, token, id, notification,
16558                    removeNotification);
16559        }
16560    }
16561
16562    @Override
16563    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16564            boolean requireFull, String name, String callerPackage) {
16565        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16566                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16567    }
16568
16569    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16570            String className, int flags) {
16571        boolean result = false;
16572        // For apps that don't have pre-defined UIDs, check for permission
16573        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16574            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16575                if (ActivityManager.checkUidPermission(
16576                        INTERACT_ACROSS_USERS,
16577                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16578                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16579                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16580                            + " requests FLAG_SINGLE_USER, but app does not hold "
16581                            + INTERACT_ACROSS_USERS;
16582                    Slog.w(TAG, msg);
16583                    throw new SecurityException(msg);
16584                }
16585                // Permission passed
16586                result = true;
16587            }
16588        } else if ("system".equals(componentProcessName)) {
16589            result = true;
16590        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16591            // Phone app and persistent apps are allowed to export singleuser providers.
16592            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16593                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16594        }
16595        if (DEBUG_MU) Slog.v(TAG_MU,
16596                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16597                + Integer.toHexString(flags) + ") = " + result);
16598        return result;
16599    }
16600
16601    /**
16602     * Checks to see if the caller is in the same app as the singleton
16603     * component, or the component is in a special app. It allows special apps
16604     * to export singleton components but prevents exporting singleton
16605     * components for regular apps.
16606     */
16607    boolean isValidSingletonCall(int callingUid, int componentUid) {
16608        int componentAppId = UserHandle.getAppId(componentUid);
16609        return UserHandle.isSameApp(callingUid, componentUid)
16610                || componentAppId == Process.SYSTEM_UID
16611                || componentAppId == Process.PHONE_UID
16612                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16613                        == PackageManager.PERMISSION_GRANTED;
16614    }
16615
16616    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16617            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16618            int userId) throws TransactionTooLargeException {
16619        enforceNotIsolatedCaller("bindService");
16620
16621        // Refuse possible leaked file descriptors
16622        if (service != null && service.hasFileDescriptors() == true) {
16623            throw new IllegalArgumentException("File descriptors passed in Intent");
16624        }
16625
16626        if (callingPackage == null) {
16627            throw new IllegalArgumentException("callingPackage cannot be null");
16628        }
16629
16630        synchronized(this) {
16631            return mServices.bindServiceLocked(caller, token, service,
16632                    resolvedType, connection, flags, callingPackage, userId);
16633        }
16634    }
16635
16636    public boolean unbindService(IServiceConnection connection) {
16637        synchronized (this) {
16638            return mServices.unbindServiceLocked(connection);
16639        }
16640    }
16641
16642    public void publishService(IBinder token, Intent intent, IBinder service) {
16643        // Refuse possible leaked file descriptors
16644        if (intent != null && intent.hasFileDescriptors() == true) {
16645            throw new IllegalArgumentException("File descriptors passed in Intent");
16646        }
16647
16648        synchronized(this) {
16649            if (!(token instanceof ServiceRecord)) {
16650                throw new IllegalArgumentException("Invalid service token");
16651            }
16652            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16653        }
16654    }
16655
16656    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16657        // Refuse possible leaked file descriptors
16658        if (intent != null && intent.hasFileDescriptors() == true) {
16659            throw new IllegalArgumentException("File descriptors passed in Intent");
16660        }
16661
16662        synchronized(this) {
16663            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16664        }
16665    }
16666
16667    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16668        synchronized(this) {
16669            if (!(token instanceof ServiceRecord)) {
16670                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16671                throw new IllegalArgumentException("Invalid service token");
16672            }
16673            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16674        }
16675    }
16676
16677    // =========================================================
16678    // BACKUP AND RESTORE
16679    // =========================================================
16680
16681    // Cause the target app to be launched if necessary and its backup agent
16682    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16683    // activity manager to announce its creation.
16684    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16685        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16686                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16687        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16688
16689        synchronized(this) {
16690            // !!! TODO: currently no check here that we're already bound
16691            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16692            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16693            synchronized (stats) {
16694                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16695            }
16696
16697            // Backup agent is now in use, its package can't be stopped.
16698            try {
16699                AppGlobals.getPackageManager().setPackageStoppedState(
16700                        app.packageName, false, UserHandle.getUserId(app.uid));
16701            } catch (RemoteException e) {
16702            } catch (IllegalArgumentException e) {
16703                Slog.w(TAG, "Failed trying to unstop package "
16704                        + app.packageName + ": " + e);
16705            }
16706
16707            BackupRecord r = new BackupRecord(ss, app, backupMode);
16708            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16709                    ? new ComponentName(app.packageName, app.backupAgentName)
16710                    : new ComponentName("android", "FullBackupAgent");
16711            // startProcessLocked() returns existing proc's record if it's already running
16712            ProcessRecord proc = startProcessLocked(app.processName, app,
16713                    false, 0, "backup", hostingName, false, false, false);
16714            if (proc == null) {
16715                Slog.e(TAG, "Unable to start backup agent process " + r);
16716                return false;
16717            }
16718
16719            r.app = proc;
16720            mBackupTarget = r;
16721            mBackupAppName = app.packageName;
16722
16723            // Try not to kill the process during backup
16724            updateOomAdjLocked(proc);
16725
16726            // If the process is already attached, schedule the creation of the backup agent now.
16727            // If it is not yet live, this will be done when it attaches to the framework.
16728            if (proc.thread != null) {
16729                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16730                try {
16731                    proc.thread.scheduleCreateBackupAgent(app,
16732                            compatibilityInfoForPackageLocked(app), backupMode);
16733                } catch (RemoteException e) {
16734                    // Will time out on the backup manager side
16735                }
16736            } else {
16737                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16738            }
16739            // Invariants: at this point, the target app process exists and the application
16740            // is either already running or in the process of coming up.  mBackupTarget and
16741            // mBackupAppName describe the app, so that when it binds back to the AM we
16742            // know that it's scheduled for a backup-agent operation.
16743        }
16744
16745        return true;
16746    }
16747
16748    @Override
16749    public void clearPendingBackup() {
16750        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16751        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16752
16753        synchronized (this) {
16754            mBackupTarget = null;
16755            mBackupAppName = null;
16756        }
16757    }
16758
16759    // A backup agent has just come up
16760    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16761        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16762                + " = " + agent);
16763
16764        synchronized(this) {
16765            if (!agentPackageName.equals(mBackupAppName)) {
16766                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16767                return;
16768            }
16769        }
16770
16771        long oldIdent = Binder.clearCallingIdentity();
16772        try {
16773            IBackupManager bm = IBackupManager.Stub.asInterface(
16774                    ServiceManager.getService(Context.BACKUP_SERVICE));
16775            bm.agentConnected(agentPackageName, agent);
16776        } catch (RemoteException e) {
16777            // can't happen; the backup manager service is local
16778        } catch (Exception e) {
16779            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16780            e.printStackTrace();
16781        } finally {
16782            Binder.restoreCallingIdentity(oldIdent);
16783        }
16784    }
16785
16786    // done with this agent
16787    public void unbindBackupAgent(ApplicationInfo appInfo) {
16788        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16789        if (appInfo == null) {
16790            Slog.w(TAG, "unbind backup agent for null app");
16791            return;
16792        }
16793
16794        synchronized(this) {
16795            try {
16796                if (mBackupAppName == null) {
16797                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16798                    return;
16799                }
16800
16801                if (!mBackupAppName.equals(appInfo.packageName)) {
16802                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16803                    return;
16804                }
16805
16806                // Not backing this app up any more; reset its OOM adjustment
16807                final ProcessRecord proc = mBackupTarget.app;
16808                updateOomAdjLocked(proc);
16809
16810                // If the app crashed during backup, 'thread' will be null here
16811                if (proc.thread != null) {
16812                    try {
16813                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16814                                compatibilityInfoForPackageLocked(appInfo));
16815                    } catch (Exception e) {
16816                        Slog.e(TAG, "Exception when unbinding backup agent:");
16817                        e.printStackTrace();
16818                    }
16819                }
16820            } finally {
16821                mBackupTarget = null;
16822                mBackupAppName = null;
16823            }
16824        }
16825    }
16826    // =========================================================
16827    // BROADCASTS
16828    // =========================================================
16829
16830    boolean isPendingBroadcastProcessLocked(int pid) {
16831        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16832                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16833    }
16834
16835    void skipPendingBroadcastLocked(int pid) {
16836            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16837            for (BroadcastQueue queue : mBroadcastQueues) {
16838                queue.skipPendingBroadcastLocked(pid);
16839            }
16840    }
16841
16842    // The app just attached; send any pending broadcasts that it should receive
16843    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16844        boolean didSomething = false;
16845        for (BroadcastQueue queue : mBroadcastQueues) {
16846            didSomething |= queue.sendPendingBroadcastsLocked(app);
16847        }
16848        return didSomething;
16849    }
16850
16851    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16852            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16853        enforceNotIsolatedCaller("registerReceiver");
16854        ArrayList<Intent> stickyIntents = null;
16855        ProcessRecord callerApp = null;
16856        int callingUid;
16857        int callingPid;
16858        synchronized(this) {
16859            if (caller != null) {
16860                callerApp = getRecordForAppLocked(caller);
16861                if (callerApp == null) {
16862                    throw new SecurityException(
16863                            "Unable to find app for caller " + caller
16864                            + " (pid=" + Binder.getCallingPid()
16865                            + ") when registering receiver " + receiver);
16866                }
16867                if (callerApp.info.uid != Process.SYSTEM_UID &&
16868                        !callerApp.pkgList.containsKey(callerPackage) &&
16869                        !"android".equals(callerPackage)) {
16870                    throw new SecurityException("Given caller package " + callerPackage
16871                            + " is not running in process " + callerApp);
16872                }
16873                callingUid = callerApp.info.uid;
16874                callingPid = callerApp.pid;
16875            } else {
16876                callerPackage = null;
16877                callingUid = Binder.getCallingUid();
16878                callingPid = Binder.getCallingPid();
16879            }
16880
16881            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16882                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16883
16884            Iterator<String> actions = filter.actionsIterator();
16885            if (actions == null) {
16886                ArrayList<String> noAction = new ArrayList<String>(1);
16887                noAction.add(null);
16888                actions = noAction.iterator();
16889            }
16890
16891            // Collect stickies of users
16892            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16893            while (actions.hasNext()) {
16894                String action = actions.next();
16895                for (int id : userIds) {
16896                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16897                    if (stickies != null) {
16898                        ArrayList<Intent> intents = stickies.get(action);
16899                        if (intents != null) {
16900                            if (stickyIntents == null) {
16901                                stickyIntents = new ArrayList<Intent>();
16902                            }
16903                            stickyIntents.addAll(intents);
16904                        }
16905                    }
16906                }
16907            }
16908        }
16909
16910        ArrayList<Intent> allSticky = null;
16911        if (stickyIntents != null) {
16912            final ContentResolver resolver = mContext.getContentResolver();
16913            // Look for any matching sticky broadcasts...
16914            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16915                Intent intent = stickyIntents.get(i);
16916                // If intent has scheme "content", it will need to acccess
16917                // provider that needs to lock mProviderMap in ActivityThread
16918                // and also it may need to wait application response, so we
16919                // cannot lock ActivityManagerService here.
16920                if (filter.match(resolver, intent, true, TAG) >= 0) {
16921                    if (allSticky == null) {
16922                        allSticky = new ArrayList<Intent>();
16923                    }
16924                    allSticky.add(intent);
16925                }
16926            }
16927        }
16928
16929        // The first sticky in the list is returned directly back to the client.
16930        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16931        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16932        if (receiver == null) {
16933            return sticky;
16934        }
16935
16936        synchronized (this) {
16937            if (callerApp != null && (callerApp.thread == null
16938                    || callerApp.thread.asBinder() != caller.asBinder())) {
16939                // Original caller already died
16940                return null;
16941            }
16942            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16943            if (rl == null) {
16944                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16945                        userId, receiver);
16946                if (rl.app != null) {
16947                    rl.app.receivers.add(rl);
16948                } else {
16949                    try {
16950                        receiver.asBinder().linkToDeath(rl, 0);
16951                    } catch (RemoteException e) {
16952                        return sticky;
16953                    }
16954                    rl.linkedToDeath = true;
16955                }
16956                mRegisteredReceivers.put(receiver.asBinder(), rl);
16957            } else if (rl.uid != callingUid) {
16958                throw new IllegalArgumentException(
16959                        "Receiver requested to register for uid " + callingUid
16960                        + " was previously registered for uid " + rl.uid);
16961            } else if (rl.pid != callingPid) {
16962                throw new IllegalArgumentException(
16963                        "Receiver requested to register for pid " + callingPid
16964                        + " was previously registered for pid " + rl.pid);
16965            } else if (rl.userId != userId) {
16966                throw new IllegalArgumentException(
16967                        "Receiver requested to register for user " + userId
16968                        + " was previously registered for user " + rl.userId);
16969            }
16970            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16971                    permission, callingUid, userId);
16972            rl.add(bf);
16973            if (!bf.debugCheck()) {
16974                Slog.w(TAG, "==> For Dynamic broadcast");
16975            }
16976            mReceiverResolver.addFilter(bf);
16977
16978            // Enqueue broadcasts for all existing stickies that match
16979            // this filter.
16980            if (allSticky != null) {
16981                ArrayList receivers = new ArrayList();
16982                receivers.add(bf);
16983
16984                final int stickyCount = allSticky.size();
16985                for (int i = 0; i < stickyCount; i++) {
16986                    Intent intent = allSticky.get(i);
16987                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16988                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16989                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16990                            null, 0, null, null, false, true, true, -1);
16991                    queue.enqueueParallelBroadcastLocked(r);
16992                    queue.scheduleBroadcastsLocked();
16993                }
16994            }
16995
16996            return sticky;
16997        }
16998    }
16999
17000    public void unregisterReceiver(IIntentReceiver receiver) {
17001        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17002
17003        final long origId = Binder.clearCallingIdentity();
17004        try {
17005            boolean doTrim = false;
17006
17007            synchronized(this) {
17008                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17009                if (rl != null) {
17010                    final BroadcastRecord r = rl.curBroadcast;
17011                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17012                        final boolean doNext = r.queue.finishReceiverLocked(
17013                                r, r.resultCode, r.resultData, r.resultExtras,
17014                                r.resultAbort, false);
17015                        if (doNext) {
17016                            doTrim = true;
17017                            r.queue.processNextBroadcast(false);
17018                        }
17019                    }
17020
17021                    if (rl.app != null) {
17022                        rl.app.receivers.remove(rl);
17023                    }
17024                    removeReceiverLocked(rl);
17025                    if (rl.linkedToDeath) {
17026                        rl.linkedToDeath = false;
17027                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17028                    }
17029                }
17030            }
17031
17032            // If we actually concluded any broadcasts, we might now be able
17033            // to trim the recipients' apps from our working set
17034            if (doTrim) {
17035                trimApplications();
17036                return;
17037            }
17038
17039        } finally {
17040            Binder.restoreCallingIdentity(origId);
17041        }
17042    }
17043
17044    void removeReceiverLocked(ReceiverList rl) {
17045        mRegisteredReceivers.remove(rl.receiver.asBinder());
17046        for (int i = rl.size() - 1; i >= 0; i--) {
17047            mReceiverResolver.removeFilter(rl.get(i));
17048        }
17049    }
17050
17051    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17052        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17053            ProcessRecord r = mLruProcesses.get(i);
17054            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17055                try {
17056                    r.thread.dispatchPackageBroadcast(cmd, packages);
17057                } catch (RemoteException ex) {
17058                }
17059            }
17060        }
17061    }
17062
17063    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17064            int callingUid, int[] users) {
17065        // TODO: come back and remove this assumption to triage all broadcasts
17066        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17067
17068        List<ResolveInfo> receivers = null;
17069        try {
17070            HashSet<ComponentName> singleUserReceivers = null;
17071            boolean scannedFirstReceivers = false;
17072            for (int user : users) {
17073                // Skip users that have Shell restrictions, with exception of always permitted
17074                // Shell broadcasts
17075                if (callingUid == Process.SHELL_UID
17076                        && mUserController.hasUserRestriction(
17077                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17078                        && !isPermittedShellBroadcast(intent)) {
17079                    continue;
17080                }
17081                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17082                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17083                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17084                    // If this is not the system user, we need to check for
17085                    // any receivers that should be filtered out.
17086                    for (int i=0; i<newReceivers.size(); i++) {
17087                        ResolveInfo ri = newReceivers.get(i);
17088                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17089                            newReceivers.remove(i);
17090                            i--;
17091                        }
17092                    }
17093                }
17094                if (newReceivers != null && newReceivers.size() == 0) {
17095                    newReceivers = null;
17096                }
17097                if (receivers == null) {
17098                    receivers = newReceivers;
17099                } else if (newReceivers != null) {
17100                    // We need to concatenate the additional receivers
17101                    // found with what we have do far.  This would be easy,
17102                    // but we also need to de-dup any receivers that are
17103                    // singleUser.
17104                    if (!scannedFirstReceivers) {
17105                        // Collect any single user receivers we had already retrieved.
17106                        scannedFirstReceivers = true;
17107                        for (int i=0; i<receivers.size(); i++) {
17108                            ResolveInfo ri = receivers.get(i);
17109                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17110                                ComponentName cn = new ComponentName(
17111                                        ri.activityInfo.packageName, ri.activityInfo.name);
17112                                if (singleUserReceivers == null) {
17113                                    singleUserReceivers = new HashSet<ComponentName>();
17114                                }
17115                                singleUserReceivers.add(cn);
17116                            }
17117                        }
17118                    }
17119                    // Add the new results to the existing results, tracking
17120                    // and de-dupping single user receivers.
17121                    for (int i=0; i<newReceivers.size(); i++) {
17122                        ResolveInfo ri = newReceivers.get(i);
17123                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17124                            ComponentName cn = new ComponentName(
17125                                    ri.activityInfo.packageName, ri.activityInfo.name);
17126                            if (singleUserReceivers == null) {
17127                                singleUserReceivers = new HashSet<ComponentName>();
17128                            }
17129                            if (!singleUserReceivers.contains(cn)) {
17130                                singleUserReceivers.add(cn);
17131                                receivers.add(ri);
17132                            }
17133                        } else {
17134                            receivers.add(ri);
17135                        }
17136                    }
17137                }
17138            }
17139        } catch (RemoteException ex) {
17140            // pm is in same process, this will never happen.
17141        }
17142        return receivers;
17143    }
17144
17145    private boolean isPermittedShellBroadcast(Intent intent) {
17146        // remote bugreport should always be allowed to be taken
17147        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17148    }
17149
17150    final int broadcastIntentLocked(ProcessRecord callerApp,
17151            String callerPackage, Intent intent, String resolvedType,
17152            IIntentReceiver resultTo, int resultCode, String resultData,
17153            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17154            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17155        intent = new Intent(intent);
17156
17157        // By default broadcasts do not go to stopped apps.
17158        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17159
17160        // If we have not finished booting, don't allow this to launch new processes.
17161        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17162            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17163        }
17164
17165        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17166                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17167                + " ordered=" + ordered + " userid=" + userId);
17168        if ((resultTo != null) && !ordered) {
17169            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17170        }
17171
17172        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17173                ALLOW_NON_FULL, "broadcast", callerPackage);
17174
17175        // Make sure that the user who is receiving this broadcast is running.
17176        // If not, we will just skip it. Make an exception for shutdown broadcasts
17177        // and upgrade steps.
17178
17179        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17180            if ((callingUid != Process.SYSTEM_UID
17181                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17182                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17183                Slog.w(TAG, "Skipping broadcast of " + intent
17184                        + ": user " + userId + " is stopped");
17185                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17186            }
17187        }
17188
17189        BroadcastOptions brOptions = null;
17190        if (bOptions != null) {
17191            brOptions = new BroadcastOptions(bOptions);
17192            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17193                // See if the caller is allowed to do this.  Note we are checking against
17194                // the actual real caller (not whoever provided the operation as say a
17195                // PendingIntent), because that who is actually supplied the arguments.
17196                if (checkComponentPermission(
17197                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17198                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17199                        != PackageManager.PERMISSION_GRANTED) {
17200                    String msg = "Permission Denial: " + intent.getAction()
17201                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17202                            + ", uid=" + callingUid + ")"
17203                            + " requires "
17204                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17205                    Slog.w(TAG, msg);
17206                    throw new SecurityException(msg);
17207                }
17208            }
17209        }
17210
17211        // Verify that protected broadcasts are only being sent by system code,
17212        // and that system code is only sending protected broadcasts.
17213        final String action = intent.getAction();
17214        final boolean isProtectedBroadcast;
17215        try {
17216            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17217        } catch (RemoteException e) {
17218            Slog.w(TAG, "Remote exception", e);
17219            return ActivityManager.BROADCAST_SUCCESS;
17220        }
17221
17222        final boolean isCallerSystem;
17223        switch (UserHandle.getAppId(callingUid)) {
17224            case Process.ROOT_UID:
17225            case Process.SYSTEM_UID:
17226            case Process.PHONE_UID:
17227            case Process.BLUETOOTH_UID:
17228            case Process.NFC_UID:
17229                isCallerSystem = true;
17230                break;
17231            default:
17232                isCallerSystem = (callerApp != null) && callerApp.persistent;
17233                break;
17234        }
17235
17236        if (isCallerSystem) {
17237            if (isProtectedBroadcast
17238                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17239                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17240                    || Intent.ACTION_GET_PERMISSIONS_COUNT.equals(action)
17241                    || Intent.ACTION_GET_PERMISSIONS_PACKAGES.equals(action)
17242                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17243                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17244                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17245                // Broadcast is either protected, or it's a public action that
17246                // we've relaxed, so it's fine for system internals to send.
17247            } else {
17248                // The vast majority of broadcasts sent from system internals
17249                // should be protected to avoid security holes, so yell loudly
17250                // to ensure we examine these cases.
17251                Log.wtf(TAG, "Sending non-protected broadcast " + action
17252                        + " from system", new Throwable());
17253            }
17254
17255        } else {
17256            if (isProtectedBroadcast) {
17257                String msg = "Permission Denial: not allowed to send broadcast "
17258                        + action + " from pid="
17259                        + callingPid + ", uid=" + callingUid;
17260                Slog.w(TAG, msg);
17261                throw new SecurityException(msg);
17262
17263            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17264                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17265                // Special case for compatibility: we don't want apps to send this,
17266                // but historically it has not been protected and apps may be using it
17267                // to poke their own app widget.  So, instead of making it protected,
17268                // just limit it to the caller.
17269                if (callerApp == null) {
17270                    String msg = "Permission Denial: not allowed to send broadcast "
17271                            + action + " from unknown caller.";
17272                    Slog.w(TAG, msg);
17273                    throw new SecurityException(msg);
17274                } else if (intent.getComponent() != null) {
17275                    // They are good enough to send to an explicit component...  verify
17276                    // it is being sent to the calling app.
17277                    if (!intent.getComponent().getPackageName().equals(
17278                            callerApp.info.packageName)) {
17279                        String msg = "Permission Denial: not allowed to send broadcast "
17280                                + action + " to "
17281                                + intent.getComponent().getPackageName() + " from "
17282                                + callerApp.info.packageName;
17283                        Slog.w(TAG, msg);
17284                        throw new SecurityException(msg);
17285                    }
17286                } else {
17287                    // Limit broadcast to their own package.
17288                    intent.setPackage(callerApp.info.packageName);
17289                }
17290            }
17291        }
17292
17293        if (action != null) {
17294            switch (action) {
17295                case Intent.ACTION_UID_REMOVED:
17296                case Intent.ACTION_PACKAGE_REMOVED:
17297                case Intent.ACTION_PACKAGE_CHANGED:
17298                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17299                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17300                case Intent.ACTION_PACKAGES_SUSPENDED:
17301                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17302                    // Handle special intents: if this broadcast is from the package
17303                    // manager about a package being removed, we need to remove all of
17304                    // its activities from the history stack.
17305                    if (checkComponentPermission(
17306                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17307                            callingPid, callingUid, -1, true)
17308                            != PackageManager.PERMISSION_GRANTED) {
17309                        String msg = "Permission Denial: " + intent.getAction()
17310                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17311                                + ", uid=" + callingUid + ")"
17312                                + " requires "
17313                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17314                        Slog.w(TAG, msg);
17315                        throw new SecurityException(msg);
17316                    }
17317                    switch (action) {
17318                        case Intent.ACTION_UID_REMOVED:
17319                            final Bundle intentExtras = intent.getExtras();
17320                            final int uid = intentExtras != null
17321                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17322                            if (uid >= 0) {
17323                                mBatteryStatsService.removeUid(uid);
17324                                mAppOpsService.uidRemoved(uid);
17325                            }
17326                            break;
17327                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17328                            // If resources are unavailable just force stop all those packages
17329                            // and flush the attribute cache as well.
17330                            String list[] =
17331                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17332                            if (list != null && list.length > 0) {
17333                                for (int i = 0; i < list.length; i++) {
17334                                    forceStopPackageLocked(list[i], -1, false, true, true,
17335                                            false, false, userId, "storage unmount");
17336                                }
17337                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17338                                sendPackageBroadcastLocked(
17339                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17340                                        userId);
17341                            }
17342                            break;
17343                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17344                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17345                            break;
17346                        case Intent.ACTION_PACKAGE_REMOVED:
17347                        case Intent.ACTION_PACKAGE_CHANGED:
17348                            Uri data = intent.getData();
17349                            String ssp;
17350                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17351                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17352                                final boolean replacing =
17353                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17354                                final boolean killProcess =
17355                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17356                                final boolean fullUninstall = removed && !replacing;
17357                                if (killProcess) {
17358                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17359                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17360                                            false, true, true, false, fullUninstall, userId,
17361                                            removed ? "pkg removed" : "pkg changed");
17362                                }
17363                                if (removed) {
17364                                    final int cmd = killProcess
17365                                            ? IApplicationThread.PACKAGE_REMOVED
17366                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17367                                    sendPackageBroadcastLocked(cmd,
17368                                            new String[] {ssp}, userId);
17369                                    if (fullUninstall) {
17370                                        mAppOpsService.packageRemoved(
17371                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17372
17373                                        // Remove all permissions granted from/to this package
17374                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17375
17376                                        removeTasksByPackageNameLocked(ssp, userId);
17377                                        mBatteryStatsService.notePackageUninstalled(ssp);
17378                                    }
17379                                } else {
17380                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17381                                            intent.getStringArrayExtra(
17382                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17383                                }
17384                            }
17385                            break;
17386                        case Intent.ACTION_PACKAGES_SUSPENDED:
17387                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17388                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17389                                    intent.getAction());
17390                            final String[] packageNames = intent.getStringArrayExtra(
17391                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17392                            final int userHandle = intent.getIntExtra(
17393                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17394
17395                            synchronized(ActivityManagerService.this) {
17396                                mRecentTasks.onPackagesSuspendedChanged(
17397                                        packageNames, suspended, userHandle);
17398                            }
17399                            break;
17400                    }
17401                    break;
17402                case Intent.ACTION_PACKAGE_REPLACED:
17403                {
17404                    final Uri data = intent.getData();
17405                    final String ssp;
17406                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17407                        final ApplicationInfo aInfo =
17408                                getPackageManagerInternalLocked().getApplicationInfo(
17409                                        ssp,
17410                                        userId);
17411                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17412                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17413                                new String[] {ssp}, userId);
17414                    }
17415                    break;
17416                }
17417                case Intent.ACTION_PACKAGE_ADDED:
17418                {
17419                    // Special case for adding a package: by default turn on compatibility mode.
17420                    Uri data = intent.getData();
17421                    String ssp;
17422                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17423                        final boolean replacing =
17424                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17425                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17426
17427                        try {
17428                            ApplicationInfo ai = AppGlobals.getPackageManager().
17429                                    getApplicationInfo(ssp, 0, 0);
17430                            mBatteryStatsService.notePackageInstalled(ssp,
17431                                    ai != null ? ai.versionCode : 0);
17432                        } catch (RemoteException e) {
17433                        }
17434                    }
17435                    break;
17436                }
17437                case Intent.ACTION_TIMEZONE_CHANGED:
17438                    // If this is the time zone changed action, queue up a message that will reset
17439                    // the timezone of all currently running processes. This message will get
17440                    // queued up before the broadcast happens.
17441                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17442                    break;
17443                case Intent.ACTION_TIME_CHANGED:
17444                    // If the user set the time, let all running processes know.
17445                    final int is24Hour =
17446                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17447                                    : 0;
17448                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17449                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17450                    synchronized (stats) {
17451                        stats.noteCurrentTimeChangedLocked();
17452                    }
17453                    break;
17454                case Intent.ACTION_CLEAR_DNS_CACHE:
17455                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17456                    break;
17457                case Proxy.PROXY_CHANGE_ACTION:
17458                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17459                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17460                    break;
17461                case android.hardware.Camera.ACTION_NEW_PICTURE:
17462                case android.hardware.Camera.ACTION_NEW_VIDEO:
17463                    // These broadcasts are no longer allowed by the system, since they can
17464                    // cause significant thrashing at a crictical point (using the camera).
17465                    // Apps should use JobScehduler to monitor for media provider changes.
17466                    Slog.w(TAG, action + " no longer allowed; dropping from "
17467                            + UserHandle.formatUid(callingUid));
17468                    // Lie; we don't want to crash the app.
17469                    return ActivityManager.BROADCAST_SUCCESS;
17470            }
17471        }
17472
17473        // Add to the sticky list if requested.
17474        if (sticky) {
17475            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17476                    callingPid, callingUid)
17477                    != PackageManager.PERMISSION_GRANTED) {
17478                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17479                        + callingPid + ", uid=" + callingUid
17480                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17481                Slog.w(TAG, msg);
17482                throw new SecurityException(msg);
17483            }
17484            if (requiredPermissions != null && requiredPermissions.length > 0) {
17485                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17486                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17487                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17488            }
17489            if (intent.getComponent() != null) {
17490                throw new SecurityException(
17491                        "Sticky broadcasts can't target a specific component");
17492            }
17493            // We use userId directly here, since the "all" target is maintained
17494            // as a separate set of sticky broadcasts.
17495            if (userId != UserHandle.USER_ALL) {
17496                // But first, if this is not a broadcast to all users, then
17497                // make sure it doesn't conflict with an existing broadcast to
17498                // all users.
17499                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17500                        UserHandle.USER_ALL);
17501                if (stickies != null) {
17502                    ArrayList<Intent> list = stickies.get(intent.getAction());
17503                    if (list != null) {
17504                        int N = list.size();
17505                        int i;
17506                        for (i=0; i<N; i++) {
17507                            if (intent.filterEquals(list.get(i))) {
17508                                throw new IllegalArgumentException(
17509                                        "Sticky broadcast " + intent + " for user "
17510                                        + userId + " conflicts with existing global broadcast");
17511                            }
17512                        }
17513                    }
17514                }
17515            }
17516            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17517            if (stickies == null) {
17518                stickies = new ArrayMap<>();
17519                mStickyBroadcasts.put(userId, stickies);
17520            }
17521            ArrayList<Intent> list = stickies.get(intent.getAction());
17522            if (list == null) {
17523                list = new ArrayList<>();
17524                stickies.put(intent.getAction(), list);
17525            }
17526            final int stickiesCount = list.size();
17527            int i;
17528            for (i = 0; i < stickiesCount; i++) {
17529                if (intent.filterEquals(list.get(i))) {
17530                    // This sticky already exists, replace it.
17531                    list.set(i, new Intent(intent));
17532                    break;
17533                }
17534            }
17535            if (i >= stickiesCount) {
17536                list.add(new Intent(intent));
17537            }
17538        }
17539
17540        int[] users;
17541        if (userId == UserHandle.USER_ALL) {
17542            // Caller wants broadcast to go to all started users.
17543            users = mUserController.getStartedUserArrayLocked();
17544        } else {
17545            // Caller wants broadcast to go to one specific user.
17546            users = new int[] {userId};
17547        }
17548
17549        // Figure out who all will receive this broadcast.
17550        List receivers = null;
17551        List<BroadcastFilter> registeredReceivers = null;
17552        // Need to resolve the intent to interested receivers...
17553        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17554                 == 0) {
17555            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17556        }
17557        if (intent.getComponent() == null) {
17558            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17559                // Query one target user at a time, excluding shell-restricted users
17560                for (int i = 0; i < users.length; i++) {
17561                    if (mUserController.hasUserRestriction(
17562                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17563                        continue;
17564                    }
17565                    List<BroadcastFilter> registeredReceiversForUser =
17566                            mReceiverResolver.queryIntent(intent,
17567                                    resolvedType, false, users[i]);
17568                    if (registeredReceivers == null) {
17569                        registeredReceivers = registeredReceiversForUser;
17570                    } else if (registeredReceiversForUser != null) {
17571                        registeredReceivers.addAll(registeredReceiversForUser);
17572                    }
17573                }
17574            } else {
17575                registeredReceivers = mReceiverResolver.queryIntent(intent,
17576                        resolvedType, false, userId);
17577            }
17578        }
17579
17580        final boolean replacePending =
17581                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17582
17583        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17584                + " replacePending=" + replacePending);
17585
17586        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17587        if (!ordered && NR > 0) {
17588            // If we are not serializing this broadcast, then send the
17589            // registered receivers separately so they don't wait for the
17590            // components to be launched.
17591            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17592            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17593                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17594                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17595                    resultExtras, ordered, sticky, false, userId);
17596            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17597            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17598            if (!replaced) {
17599                queue.enqueueParallelBroadcastLocked(r);
17600                queue.scheduleBroadcastsLocked();
17601            }
17602            registeredReceivers = null;
17603            NR = 0;
17604        }
17605
17606        // Merge into one list.
17607        int ir = 0;
17608        if (receivers != null) {
17609            // A special case for PACKAGE_ADDED: do not allow the package
17610            // being added to see this broadcast.  This prevents them from
17611            // using this as a back door to get run as soon as they are
17612            // installed.  Maybe in the future we want to have a special install
17613            // broadcast or such for apps, but we'd like to deliberately make
17614            // this decision.
17615            String skipPackages[] = null;
17616            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17617                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17618                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17619                Uri data = intent.getData();
17620                if (data != null) {
17621                    String pkgName = data.getSchemeSpecificPart();
17622                    if (pkgName != null) {
17623                        skipPackages = new String[] { pkgName };
17624                    }
17625                }
17626            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17627                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17628            }
17629            if (skipPackages != null && (skipPackages.length > 0)) {
17630                for (String skipPackage : skipPackages) {
17631                    if (skipPackage != null) {
17632                        int NT = receivers.size();
17633                        for (int it=0; it<NT; it++) {
17634                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17635                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17636                                receivers.remove(it);
17637                                it--;
17638                                NT--;
17639                            }
17640                        }
17641                    }
17642                }
17643            }
17644
17645            int NT = receivers != null ? receivers.size() : 0;
17646            int it = 0;
17647            ResolveInfo curt = null;
17648            BroadcastFilter curr = null;
17649            while (it < NT && ir < NR) {
17650                if (curt == null) {
17651                    curt = (ResolveInfo)receivers.get(it);
17652                }
17653                if (curr == null) {
17654                    curr = registeredReceivers.get(ir);
17655                }
17656                if (curr.getPriority() >= curt.priority) {
17657                    // Insert this broadcast record into the final list.
17658                    receivers.add(it, curr);
17659                    ir++;
17660                    curr = null;
17661                    it++;
17662                    NT++;
17663                } else {
17664                    // Skip to the next ResolveInfo in the final list.
17665                    it++;
17666                    curt = null;
17667                }
17668            }
17669        }
17670        while (ir < NR) {
17671            if (receivers == null) {
17672                receivers = new ArrayList();
17673            }
17674            receivers.add(registeredReceivers.get(ir));
17675            ir++;
17676        }
17677
17678        if ((receivers != null && receivers.size() > 0)
17679                || resultTo != null) {
17680            BroadcastQueue queue = broadcastQueueForIntent(intent);
17681            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17682                    callerPackage, callingPid, callingUid, resolvedType,
17683                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17684                    resultData, resultExtras, ordered, sticky, false, userId);
17685
17686            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17687                    + ": prev had " + queue.mOrderedBroadcasts.size());
17688            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17689                    "Enqueueing broadcast " + r.intent.getAction());
17690
17691            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17692            if (!replaced) {
17693                queue.enqueueOrderedBroadcastLocked(r);
17694                queue.scheduleBroadcastsLocked();
17695            }
17696        }
17697
17698        return ActivityManager.BROADCAST_SUCCESS;
17699    }
17700
17701    final Intent verifyBroadcastLocked(Intent intent) {
17702        // Refuse possible leaked file descriptors
17703        if (intent != null && intent.hasFileDescriptors() == true) {
17704            throw new IllegalArgumentException("File descriptors passed in Intent");
17705        }
17706
17707        int flags = intent.getFlags();
17708
17709        if (!mProcessesReady) {
17710            // if the caller really truly claims to know what they're doing, go
17711            // ahead and allow the broadcast without launching any receivers
17712            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17713                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17714            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17715                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17716                        + " before boot completion");
17717                throw new IllegalStateException("Cannot broadcast before boot completed");
17718            }
17719        }
17720
17721        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17722            throw new IllegalArgumentException(
17723                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17724        }
17725
17726        return intent;
17727    }
17728
17729    public final int broadcastIntent(IApplicationThread caller,
17730            Intent intent, String resolvedType, IIntentReceiver resultTo,
17731            int resultCode, String resultData, Bundle resultExtras,
17732            String[] requiredPermissions, int appOp, Bundle bOptions,
17733            boolean serialized, boolean sticky, int userId) {
17734        enforceNotIsolatedCaller("broadcastIntent");
17735        synchronized(this) {
17736            intent = verifyBroadcastLocked(intent);
17737
17738            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17739            final int callingPid = Binder.getCallingPid();
17740            final int callingUid = Binder.getCallingUid();
17741            final long origId = Binder.clearCallingIdentity();
17742            int res = broadcastIntentLocked(callerApp,
17743                    callerApp != null ? callerApp.info.packageName : null,
17744                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17745                    requiredPermissions, appOp, null, serialized, sticky,
17746                    callingPid, callingUid, userId);
17747            Binder.restoreCallingIdentity(origId);
17748            return res;
17749        }
17750    }
17751
17752
17753    int broadcastIntentInPackage(String packageName, int uid,
17754            Intent intent, String resolvedType, IIntentReceiver resultTo,
17755            int resultCode, String resultData, Bundle resultExtras,
17756            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17757            int userId) {
17758        synchronized(this) {
17759            intent = verifyBroadcastLocked(intent);
17760
17761            final long origId = Binder.clearCallingIdentity();
17762            String[] requiredPermissions = requiredPermission == null ? null
17763                    : new String[] {requiredPermission};
17764            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17765                    resultTo, resultCode, resultData, resultExtras,
17766                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17767                    sticky, -1, uid, userId);
17768            Binder.restoreCallingIdentity(origId);
17769            return res;
17770        }
17771    }
17772
17773    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17774        // Refuse possible leaked file descriptors
17775        if (intent != null && intent.hasFileDescriptors() == true) {
17776            throw new IllegalArgumentException("File descriptors passed in Intent");
17777        }
17778
17779        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17780                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17781
17782        synchronized(this) {
17783            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17784                    != PackageManager.PERMISSION_GRANTED) {
17785                String msg = "Permission Denial: unbroadcastIntent() from pid="
17786                        + Binder.getCallingPid()
17787                        + ", uid=" + Binder.getCallingUid()
17788                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17789                Slog.w(TAG, msg);
17790                throw new SecurityException(msg);
17791            }
17792            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17793            if (stickies != null) {
17794                ArrayList<Intent> list = stickies.get(intent.getAction());
17795                if (list != null) {
17796                    int N = list.size();
17797                    int i;
17798                    for (i=0; i<N; i++) {
17799                        if (intent.filterEquals(list.get(i))) {
17800                            list.remove(i);
17801                            break;
17802                        }
17803                    }
17804                    if (list.size() <= 0) {
17805                        stickies.remove(intent.getAction());
17806                    }
17807                }
17808                if (stickies.size() <= 0) {
17809                    mStickyBroadcasts.remove(userId);
17810                }
17811            }
17812        }
17813    }
17814
17815    void backgroundServicesFinishedLocked(int userId) {
17816        for (BroadcastQueue queue : mBroadcastQueues) {
17817            queue.backgroundServicesFinishedLocked(userId);
17818        }
17819    }
17820
17821    public void finishReceiver(IBinder who, int resultCode, String resultData,
17822            Bundle resultExtras, boolean resultAbort, int flags) {
17823        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17824
17825        // Refuse possible leaked file descriptors
17826        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17827            throw new IllegalArgumentException("File descriptors passed in Bundle");
17828        }
17829
17830        final long origId = Binder.clearCallingIdentity();
17831        try {
17832            boolean doNext = false;
17833            BroadcastRecord r;
17834
17835            synchronized(this) {
17836                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17837                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17838                r = queue.getMatchingOrderedReceiver(who);
17839                if (r != null) {
17840                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17841                        resultData, resultExtras, resultAbort, true);
17842                }
17843            }
17844
17845            if (doNext) {
17846                r.queue.processNextBroadcast(false);
17847            }
17848            trimApplications();
17849        } finally {
17850            Binder.restoreCallingIdentity(origId);
17851        }
17852    }
17853
17854    // =========================================================
17855    // INSTRUMENTATION
17856    // =========================================================
17857
17858    public boolean startInstrumentation(ComponentName className,
17859            String profileFile, int flags, Bundle arguments,
17860            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17861            int userId, String abiOverride) {
17862        enforceNotIsolatedCaller("startInstrumentation");
17863        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17864                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17865        // Refuse possible leaked file descriptors
17866        if (arguments != null && arguments.hasFileDescriptors()) {
17867            throw new IllegalArgumentException("File descriptors passed in Bundle");
17868        }
17869
17870        synchronized(this) {
17871            InstrumentationInfo ii = null;
17872            ApplicationInfo ai = null;
17873            try {
17874                ii = mContext.getPackageManager().getInstrumentationInfo(
17875                    className, STOCK_PM_FLAGS);
17876                ai = AppGlobals.getPackageManager().getApplicationInfo(
17877                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17878            } catch (PackageManager.NameNotFoundException e) {
17879            } catch (RemoteException e) {
17880            }
17881            if (ii == null) {
17882                reportStartInstrumentationFailureLocked(watcher, className,
17883                        "Unable to find instrumentation info for: " + className);
17884                return false;
17885            }
17886            if (ai == null) {
17887                reportStartInstrumentationFailureLocked(watcher, className,
17888                        "Unable to find instrumentation target package: " + ii.targetPackage);
17889                return false;
17890            }
17891            if (!ai.hasCode()) {
17892                reportStartInstrumentationFailureLocked(watcher, className,
17893                        "Instrumentation target has no code: " + ii.targetPackage);
17894                return false;
17895            }
17896
17897            int match = mContext.getPackageManager().checkSignatures(
17898                    ii.targetPackage, ii.packageName);
17899            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17900                String msg = "Permission Denial: starting instrumentation "
17901                        + className + " from pid="
17902                        + Binder.getCallingPid()
17903                        + ", uid=" + Binder.getCallingPid()
17904                        + " not allowed because package " + ii.packageName
17905                        + " does not have a signature matching the target "
17906                        + ii.targetPackage;
17907                reportStartInstrumentationFailureLocked(watcher, className, msg);
17908                throw new SecurityException(msg);
17909            }
17910
17911            final long origId = Binder.clearCallingIdentity();
17912            // Instrumentation can kill and relaunch even persistent processes
17913            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17914                    "start instr");
17915            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17916            app.instrumentationClass = className;
17917            app.instrumentationInfo = ai;
17918            app.instrumentationProfileFile = profileFile;
17919            app.instrumentationArguments = arguments;
17920            app.instrumentationWatcher = watcher;
17921            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17922            app.instrumentationResultClass = className;
17923            Binder.restoreCallingIdentity(origId);
17924        }
17925
17926        return true;
17927    }
17928
17929    /**
17930     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17931     * error to the logs, but if somebody is watching, send the report there too.  This enables
17932     * the "am" command to report errors with more information.
17933     *
17934     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17935     * @param cn The component name of the instrumentation.
17936     * @param report The error report.
17937     */
17938    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
17939            ComponentName cn, String report) {
17940        Slog.w(TAG, report);
17941        if (watcher != null) {
17942            Bundle results = new Bundle();
17943            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17944            results.putString("Error", report);
17945            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
17946        }
17947    }
17948
17949    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17950        if (app.instrumentationWatcher != null) {
17951            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
17952                    app.instrumentationClass, resultCode, results);
17953        }
17954
17955        // Can't call out of the system process with a lock held, so post a message.
17956        if (app.instrumentationUiAutomationConnection != null) {
17957            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17958                    app.instrumentationUiAutomationConnection).sendToTarget();
17959        }
17960
17961        app.instrumentationWatcher = null;
17962        app.instrumentationUiAutomationConnection = null;
17963        app.instrumentationClass = null;
17964        app.instrumentationInfo = null;
17965        app.instrumentationProfileFile = null;
17966        app.instrumentationArguments = null;
17967
17968        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17969                "finished inst");
17970    }
17971
17972    public void finishInstrumentation(IApplicationThread target,
17973            int resultCode, Bundle results) {
17974        int userId = UserHandle.getCallingUserId();
17975        // Refuse possible leaked file descriptors
17976        if (results != null && results.hasFileDescriptors()) {
17977            throw new IllegalArgumentException("File descriptors passed in Intent");
17978        }
17979
17980        synchronized(this) {
17981            ProcessRecord app = getRecordForAppLocked(target);
17982            if (app == null) {
17983                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17984                return;
17985            }
17986            final long origId = Binder.clearCallingIdentity();
17987            finishInstrumentationLocked(app, resultCode, results);
17988            Binder.restoreCallingIdentity(origId);
17989        }
17990    }
17991
17992    // =========================================================
17993    // CONFIGURATION
17994    // =========================================================
17995
17996    public ConfigurationInfo getDeviceConfigurationInfo() {
17997        ConfigurationInfo config = new ConfigurationInfo();
17998        synchronized (this) {
17999            config.reqTouchScreen = mConfiguration.touchscreen;
18000            config.reqKeyboardType = mConfiguration.keyboard;
18001            config.reqNavigation = mConfiguration.navigation;
18002            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18003                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18004                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18005            }
18006            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18007                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18008                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18009            }
18010            config.reqGlEsVersion = GL_ES_VERSION;
18011        }
18012        return config;
18013    }
18014
18015    ActivityStack getFocusedStack() {
18016        return mStackSupervisor.getFocusedStack();
18017    }
18018
18019    @Override
18020    public int getFocusedStackId() throws RemoteException {
18021        ActivityStack focusedStack = getFocusedStack();
18022        if (focusedStack != null) {
18023            return focusedStack.getStackId();
18024        }
18025        return -1;
18026    }
18027
18028    public Configuration getConfiguration() {
18029        Configuration ci;
18030        synchronized(this) {
18031            ci = new Configuration(mConfiguration);
18032            ci.userSetLocale = false;
18033        }
18034        return ci;
18035    }
18036
18037    @Override
18038    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18039        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18040        synchronized (this) {
18041            mSuppressResizeConfigChanges = suppress;
18042        }
18043    }
18044
18045    @Override
18046    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18047        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18048        if (fromStackId == HOME_STACK_ID) {
18049            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18050        }
18051        synchronized (this) {
18052            final long origId = Binder.clearCallingIdentity();
18053            final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
18054            if (stack != null) {
18055                mWindowManager.deferSurfaceLayout();
18056                try {
18057                    if (fromStackId == DOCKED_STACK_ID) {
18058
18059                        // We are moving all tasks from the docked stack to the fullscreen stack,
18060                        // which is dismissing the docked stack, so resize all other stacks to
18061                        // fullscreen here already so we don't end up with resize trashing.
18062                        for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
18063                            if (StackId.isResizeableByDockedStack(i)) {
18064                                ActivityStack otherStack = mStackSupervisor.getStack(i);
18065                                if (otherStack != null) {
18066                                    mStackSupervisor.resizeStackLocked(i,
18067                                            null, null, null, PRESERVE_WINDOWS,
18068                                            true /* allowResizeInDockedMode */);
18069                                }
18070                            }
18071                        }
18072                    }
18073                    final ArrayList<TaskRecord> tasks = stack.getAllTasks();
18074                    final int size = tasks.size();
18075                    if (onTop) {
18076                        for (int i = 0; i < size; i++) {
18077                            mStackSupervisor.moveTaskToStackLocked(tasks.get(i).taskId,
18078                                    FULLSCREEN_WORKSPACE_STACK_ID, onTop, !FORCE_FOCUS,
18079                                    "moveTasksToFullscreenStack", ANIMATE);
18080                        }
18081                    } else {
18082                        for (int i = size - 1; i >= 0; i--) {
18083                            mStackSupervisor.positionTaskInStackLocked(tasks.get(i).taskId,
18084                                    FULLSCREEN_WORKSPACE_STACK_ID, 0);
18085                        }
18086                    }
18087                } finally {
18088                    mWindowManager.continueSurfaceLayout();
18089                }
18090
18091            }
18092            Binder.restoreCallingIdentity(origId);
18093        }
18094    }
18095
18096    @Override
18097    public void updatePersistentConfiguration(Configuration values) {
18098        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18099                "updateConfiguration()");
18100        enforceWriteSettingsPermission("updateConfiguration()");
18101        if (values == null) {
18102            throw new NullPointerException("Configuration must not be null");
18103        }
18104
18105        int userId = UserHandle.getCallingUserId();
18106
18107        synchronized(this) {
18108            final long origId = Binder.clearCallingIdentity();
18109            updateConfigurationLocked(values, null, false, true, userId);
18110            Binder.restoreCallingIdentity(origId);
18111        }
18112    }
18113
18114    private void updateFontScaleIfNeeded() {
18115        final int currentUserId;
18116        synchronized(this) {
18117            currentUserId = mUserController.getCurrentUserIdLocked();
18118        }
18119        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18120                FONT_SCALE, 1.0f, currentUserId);
18121        if (mConfiguration.fontScale != scaleFactor) {
18122            final Configuration configuration = mWindowManager.computeNewConfiguration();
18123            configuration.fontScale = scaleFactor;
18124            updatePersistentConfiguration(configuration);
18125        }
18126    }
18127
18128    private void enforceWriteSettingsPermission(String func) {
18129        int uid = Binder.getCallingUid();
18130        if (uid == Process.ROOT_UID) {
18131            return;
18132        }
18133
18134        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18135                Settings.getPackageNameForUid(mContext, uid), false)) {
18136            return;
18137        }
18138
18139        String msg = "Permission Denial: " + func + " from pid="
18140                + Binder.getCallingPid()
18141                + ", uid=" + uid
18142                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18143        Slog.w(TAG, msg);
18144        throw new SecurityException(msg);
18145    }
18146
18147    public void updateConfiguration(Configuration values) {
18148        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18149                "updateConfiguration()");
18150
18151        synchronized(this) {
18152            if (values == null && mWindowManager != null) {
18153                // sentinel: fetch the current configuration from the window manager
18154                values = mWindowManager.computeNewConfiguration();
18155            }
18156
18157            if (mWindowManager != null) {
18158                mProcessList.applyDisplaySize(mWindowManager);
18159            }
18160
18161            final long origId = Binder.clearCallingIdentity();
18162            if (values != null) {
18163                Settings.System.clearConfiguration(values);
18164            }
18165            updateConfigurationLocked(values, null, false);
18166            Binder.restoreCallingIdentity(origId);
18167        }
18168    }
18169
18170    void updateUserConfigurationLocked() {
18171        Configuration configuration = new Configuration(mConfiguration);
18172        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18173                mUserController.getCurrentUserIdLocked());
18174        updateConfigurationLocked(configuration, null, false);
18175    }
18176
18177    boolean updateConfigurationLocked(Configuration values,
18178            ActivityRecord starting, boolean initLocale) {
18179        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18180        return updateConfigurationLocked(values, starting, initLocale, false,
18181                UserHandle.USER_NULL);
18182    }
18183
18184    // To cache the list of supported system locales
18185    private String[] mSupportedSystemLocales = null;
18186
18187    /**
18188     * Do either or both things: (1) change the current configuration, and (2)
18189     * make sure the given activity is running with the (now) current
18190     * configuration.  Returns true if the activity has been left running, or
18191     * false if <var>starting</var> is being destroyed to match the new
18192     * configuration.
18193     *
18194     * @param userId is only used when persistent parameter is set to true to persist configuration
18195     *               for that particular user
18196     */
18197    private boolean updateConfigurationLocked(Configuration values,
18198            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18199        int changes = 0;
18200
18201        if (values != null) {
18202            Configuration newConfig = new Configuration(mConfiguration);
18203            changes = newConfig.updateFrom(values);
18204            if (changes != 0) {
18205                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18206                        "Updating configuration to: " + values);
18207
18208                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18209
18210                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18211                    final Locale locale;
18212                    if (values.getLocales().size() == 1) {
18213                        // This is an optimization to avoid the JNI call when the result of
18214                        // getFirstMatch() does not depend on the supported locales.
18215                        locale = values.getLocales().get(0);
18216                    } else {
18217                        if (mSupportedSystemLocales == null) {
18218                            mSupportedSystemLocales =
18219                                    Resources.getSystem().getAssets().getLocales();
18220                        }
18221                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18222                    }
18223                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18224                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18225                            locale));
18226                }
18227
18228                mConfigurationSeq++;
18229                if (mConfigurationSeq <= 0) {
18230                    mConfigurationSeq = 1;
18231                }
18232                newConfig.seq = mConfigurationSeq;
18233                mConfiguration = newConfig;
18234                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18235                mUsageStatsService.reportConfigurationChange(newConfig,
18236                        mUserController.getCurrentUserIdLocked());
18237                //mUsageStatsService.noteStartConfig(newConfig);
18238
18239                final Configuration configCopy = new Configuration(mConfiguration);
18240
18241                // TODO: If our config changes, should we auto dismiss any currently
18242                // showing dialogs?
18243                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18244
18245                AttributeCache ac = AttributeCache.instance();
18246                if (ac != null) {
18247                    ac.updateConfiguration(configCopy);
18248                }
18249
18250                // Make sure all resources in our process are updated
18251                // right now, so that anyone who is going to retrieve
18252                // resource values after we return will be sure to get
18253                // the new ones.  This is especially important during
18254                // boot, where the first config change needs to guarantee
18255                // all resources have that config before following boot
18256                // code is executed.
18257                mSystemThread.applyConfigurationToResources(configCopy);
18258
18259                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18260                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18261                    msg.obj = new Configuration(configCopy);
18262                    msg.arg1 = userId;
18263                    mHandler.sendMessage(msg);
18264                }
18265
18266                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18267                if (isDensityChange) {
18268                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18269                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18270                }
18271
18272                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18273                    ProcessRecord app = mLruProcesses.get(i);
18274                    try {
18275                        if (app.thread != null) {
18276                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18277                                    + app.processName + " new config " + mConfiguration);
18278                            app.thread.scheduleConfigurationChanged(configCopy);
18279                        }
18280                    } catch (Exception e) {
18281                    }
18282                }
18283                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18284                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18285                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18286                        | Intent.FLAG_RECEIVER_FOREGROUND);
18287                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18288                        null, AppOpsManager.OP_NONE, null, false, false,
18289                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18290                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18291                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18292                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18293                    if (!mProcessesReady) {
18294                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18295                    }
18296                    broadcastIntentLocked(null, null, intent,
18297                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18298                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18299                }
18300            }
18301        }
18302
18303        boolean kept = true;
18304        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18305        // mainStack is null during startup.
18306        if (mainStack != null) {
18307            if (changes != 0 && starting == null) {
18308                // If the configuration changed, and the caller is not already
18309                // in the process of starting an activity, then find the top
18310                // activity to check if its configuration needs to change.
18311                starting = mainStack.topRunningActivityLocked();
18312            }
18313
18314            if (starting != null) {
18315                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18316                // And we need to make sure at this point that all other activities
18317                // are made visible with the correct configuration.
18318                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18319                        !PRESERVE_WINDOWS);
18320            }
18321        }
18322
18323        if (values != null && mWindowManager != null) {
18324            mWindowManager.setNewConfiguration(mConfiguration);
18325        }
18326
18327        return kept;
18328    }
18329
18330    /**
18331     * Decide based on the configuration whether we should shouw the ANR,
18332     * crash, etc dialogs.  The idea is that if there is no affordnace to
18333     * press the on-screen buttons, we shouldn't show the dialog.
18334     *
18335     * A thought: SystemUI might also want to get told about this, the Power
18336     * dialog / global actions also might want different behaviors.
18337     */
18338    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18339        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18340                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18341                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18342        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18343                                    == Configuration.UI_MODE_TYPE_CAR);
18344        return inputMethodExists && uiIsNotCarType && !inVrMode;
18345    }
18346
18347    @Override
18348    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18349        synchronized (this) {
18350            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18351            if (srec != null) {
18352                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18353            }
18354        }
18355        return false;
18356    }
18357
18358    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18359            Intent resultData) {
18360
18361        synchronized (this) {
18362            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18363            if (r != null) {
18364                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18365            }
18366            return false;
18367        }
18368    }
18369
18370    public int getLaunchedFromUid(IBinder activityToken) {
18371        ActivityRecord srec;
18372        synchronized (this) {
18373            srec = ActivityRecord.forTokenLocked(activityToken);
18374        }
18375        if (srec == null) {
18376            return -1;
18377        }
18378        return srec.launchedFromUid;
18379    }
18380
18381    public String getLaunchedFromPackage(IBinder activityToken) {
18382        ActivityRecord srec;
18383        synchronized (this) {
18384            srec = ActivityRecord.forTokenLocked(activityToken);
18385        }
18386        if (srec == null) {
18387            return null;
18388        }
18389        return srec.launchedFromPackage;
18390    }
18391
18392    // =========================================================
18393    // LIFETIME MANAGEMENT
18394    // =========================================================
18395
18396    // Returns which broadcast queue the app is the current [or imminent] receiver
18397    // on, or 'null' if the app is not an active broadcast recipient.
18398    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18399        BroadcastRecord r = app.curReceiver;
18400        if (r != null) {
18401            return r.queue;
18402        }
18403
18404        // It's not the current receiver, but it might be starting up to become one
18405        synchronized (this) {
18406            for (BroadcastQueue queue : mBroadcastQueues) {
18407                r = queue.mPendingBroadcast;
18408                if (r != null && r.curApp == app) {
18409                    // found it; report which queue it's in
18410                    return queue;
18411                }
18412            }
18413        }
18414
18415        return null;
18416    }
18417
18418    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18419            ComponentName targetComponent, String targetProcess) {
18420        if (!mTrackingAssociations) {
18421            return null;
18422        }
18423        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18424                = mAssociations.get(targetUid);
18425        if (components == null) {
18426            components = new ArrayMap<>();
18427            mAssociations.put(targetUid, components);
18428        }
18429        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18430        if (sourceUids == null) {
18431            sourceUids = new SparseArray<>();
18432            components.put(targetComponent, sourceUids);
18433        }
18434        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18435        if (sourceProcesses == null) {
18436            sourceProcesses = new ArrayMap<>();
18437            sourceUids.put(sourceUid, sourceProcesses);
18438        }
18439        Association ass = sourceProcesses.get(sourceProcess);
18440        if (ass == null) {
18441            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18442                    targetProcess);
18443            sourceProcesses.put(sourceProcess, ass);
18444        }
18445        ass.mCount++;
18446        ass.mNesting++;
18447        if (ass.mNesting == 1) {
18448            ass.mStartTime = SystemClock.uptimeMillis();
18449        }
18450        return ass;
18451    }
18452
18453    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18454            ComponentName targetComponent) {
18455        if (!mTrackingAssociations) {
18456            return;
18457        }
18458        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18459                = mAssociations.get(targetUid);
18460        if (components == null) {
18461            return;
18462        }
18463        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18464        if (sourceUids == null) {
18465            return;
18466        }
18467        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18468        if (sourceProcesses == null) {
18469            return;
18470        }
18471        Association ass = sourceProcesses.get(sourceProcess);
18472        if (ass == null || ass.mNesting <= 0) {
18473            return;
18474        }
18475        ass.mNesting--;
18476        if (ass.mNesting == 0) {
18477            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
18478        }
18479    }
18480
18481    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18482            boolean doingAll, long now) {
18483        if (mAdjSeq == app.adjSeq) {
18484            // This adjustment has already been computed.
18485            return app.curRawAdj;
18486        }
18487
18488        if (app.thread == null) {
18489            app.adjSeq = mAdjSeq;
18490            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18491            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18492            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18493        }
18494
18495        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18496        app.adjSource = null;
18497        app.adjTarget = null;
18498        app.empty = false;
18499        app.cached = false;
18500
18501        final int activitiesSize = app.activities.size();
18502
18503        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18504            // The max adjustment doesn't allow this app to be anything
18505            // below foreground, so it is not worth doing work for it.
18506            app.adjType = "fixed";
18507            app.adjSeq = mAdjSeq;
18508            app.curRawAdj = app.maxAdj;
18509            app.foregroundActivities = false;
18510            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18511            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18512            // System processes can do UI, and when they do we want to have
18513            // them trim their memory after the user leaves the UI.  To
18514            // facilitate this, here we need to determine whether or not it
18515            // is currently showing UI.
18516            app.systemNoUi = true;
18517            if (app == TOP_APP) {
18518                app.systemNoUi = false;
18519            } else if (activitiesSize > 0) {
18520                for (int j = 0; j < activitiesSize; j++) {
18521                    final ActivityRecord r = app.activities.get(j);
18522                    if (r.visible) {
18523                        app.systemNoUi = false;
18524                    }
18525                }
18526            }
18527            if (!app.systemNoUi) {
18528                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18529            }
18530            return (app.curAdj=app.maxAdj);
18531        }
18532
18533        app.systemNoUi = false;
18534
18535        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18536
18537        // Determine the importance of the process, starting with most
18538        // important to least, and assign an appropriate OOM adjustment.
18539        int adj;
18540        int schedGroup;
18541        int procState;
18542        boolean foregroundActivities = false;
18543        BroadcastQueue queue;
18544        if (app == TOP_APP) {
18545            // The last app on the list is the foreground app.
18546            adj = ProcessList.FOREGROUND_APP_ADJ;
18547            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18548            app.adjType = "top-activity";
18549            foregroundActivities = true;
18550            procState = PROCESS_STATE_CUR_TOP;
18551        } else if (app.instrumentationClass != null) {
18552            // Don't want to kill running instrumentation.
18553            adj = ProcessList.FOREGROUND_APP_ADJ;
18554            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18555            app.adjType = "instrumentation";
18556            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18557        } else if ((queue = isReceivingBroadcast(app)) != null) {
18558            // An app that is currently receiving a broadcast also
18559            // counts as being in the foreground for OOM killer purposes.
18560            // It's placed in a sched group based on the nature of the
18561            // broadcast as reflected by which queue it's active in.
18562            adj = ProcessList.FOREGROUND_APP_ADJ;
18563            schedGroup = (queue == mFgBroadcastQueue)
18564                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18565            app.adjType = "broadcast";
18566            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18567        } else if (app.executingServices.size() > 0) {
18568            // An app that is currently executing a service callback also
18569            // counts as being in the foreground.
18570            adj = ProcessList.FOREGROUND_APP_ADJ;
18571            schedGroup = app.execServicesFg ?
18572                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18573            app.adjType = "exec-service";
18574            procState = ActivityManager.PROCESS_STATE_SERVICE;
18575            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18576        } else {
18577            // As far as we know the process is empty.  We may change our mind later.
18578            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18579            // At this point we don't actually know the adjustment.  Use the cached adj
18580            // value that the caller wants us to.
18581            adj = cachedAdj;
18582            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18583            app.cached = true;
18584            app.empty = true;
18585            app.adjType = "cch-empty";
18586        }
18587
18588        // Examine all activities if not already foreground.
18589        if (!foregroundActivities && activitiesSize > 0) {
18590            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18591            for (int j = 0; j < activitiesSize; j++) {
18592                final ActivityRecord r = app.activities.get(j);
18593                if (r.app != app) {
18594                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
18595                            + app + "?!? Using " + r.app + " instead.");
18596                    continue;
18597                }
18598                if (r.visible) {
18599                    // App has a visible activity; only upgrade adjustment.
18600                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18601                        adj = ProcessList.VISIBLE_APP_ADJ;
18602                        app.adjType = "visible";
18603                    }
18604                    if (procState > PROCESS_STATE_CUR_TOP) {
18605                        procState = PROCESS_STATE_CUR_TOP;
18606                    }
18607                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18608                    app.cached = false;
18609                    app.empty = false;
18610                    foregroundActivities = true;
18611                    if (r.task != null && minLayer > 0) {
18612                        final int layer = r.task.mLayerRank;
18613                        if (layer >= 0 && minLayer > layer) {
18614                            minLayer = layer;
18615                        }
18616                    }
18617                    break;
18618                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18619                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18620                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18621                        app.adjType = "pausing";
18622                    }
18623                    if (procState > PROCESS_STATE_CUR_TOP) {
18624                        procState = PROCESS_STATE_CUR_TOP;
18625                    }
18626                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18627                    app.cached = false;
18628                    app.empty = false;
18629                    foregroundActivities = true;
18630                } else if (r.state == ActivityState.STOPPING) {
18631                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18632                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18633                        app.adjType = "stopping";
18634                    }
18635                    // For the process state, we will at this point consider the
18636                    // process to be cached.  It will be cached either as an activity
18637                    // or empty depending on whether the activity is finishing.  We do
18638                    // this so that we can treat the process as cached for purposes of
18639                    // memory trimming (determing current memory level, trim command to
18640                    // send to process) since there can be an arbitrary number of stopping
18641                    // processes and they should soon all go into the cached state.
18642                    if (!r.finishing) {
18643                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18644                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18645                        }
18646                    }
18647                    app.cached = false;
18648                    app.empty = false;
18649                    foregroundActivities = true;
18650                } else {
18651                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18652                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18653                        app.adjType = "cch-act";
18654                    }
18655                }
18656            }
18657            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18658                adj += minLayer;
18659            }
18660        }
18661
18662        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18663                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18664            if (app.foregroundServices) {
18665                // The user is aware of this app, so make it visible.
18666                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18667                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18668                app.cached = false;
18669                app.adjType = "fg-service";
18670                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18671            } else if (app.forcingToForeground != null) {
18672                // The user is aware of this app, so make it visible.
18673                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18674                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18675                app.cached = false;
18676                app.adjType = "force-fg";
18677                app.adjSource = app.forcingToForeground;
18678                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18679            }
18680        }
18681
18682        if (app == mHeavyWeightProcess) {
18683            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18684                // We don't want to kill the current heavy-weight process.
18685                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18686                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18687                app.cached = false;
18688                app.adjType = "heavy";
18689            }
18690            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18691                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18692            }
18693        }
18694
18695        if (app == mHomeProcess) {
18696            if (adj > ProcessList.HOME_APP_ADJ) {
18697                // This process is hosting what we currently consider to be the
18698                // home app, so we don't want to let it go into the background.
18699                adj = ProcessList.HOME_APP_ADJ;
18700                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18701                app.cached = false;
18702                app.adjType = "home";
18703            }
18704            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18705                procState = ActivityManager.PROCESS_STATE_HOME;
18706            }
18707        }
18708
18709        if (app == mPreviousProcess && app.activities.size() > 0) {
18710            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18711                // This was the previous process that showed UI to the user.
18712                // We want to try to keep it around more aggressively, to give
18713                // a good experience around switching between two apps.
18714                adj = ProcessList.PREVIOUS_APP_ADJ;
18715                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18716                app.cached = false;
18717                app.adjType = "previous";
18718            }
18719            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18720                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18721            }
18722        }
18723
18724        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18725                + " reason=" + app.adjType);
18726
18727        // By default, we use the computed adjustment.  It may be changed if
18728        // there are applications dependent on our services or providers, but
18729        // this gives us a baseline and makes sure we don't get into an
18730        // infinite recursion.
18731        app.adjSeq = mAdjSeq;
18732        app.curRawAdj = adj;
18733        app.hasStartedServices = false;
18734
18735        if (mBackupTarget != null && app == mBackupTarget.app) {
18736            // If possible we want to avoid killing apps while they're being backed up
18737            if (adj > ProcessList.BACKUP_APP_ADJ) {
18738                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18739                adj = ProcessList.BACKUP_APP_ADJ;
18740                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18741                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18742                }
18743                app.adjType = "backup";
18744                app.cached = false;
18745            }
18746            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18747                procState = ActivityManager.PROCESS_STATE_BACKUP;
18748            }
18749        }
18750
18751        boolean mayBeTop = false;
18752
18753        for (int is = app.services.size()-1;
18754                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18755                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18756                        || procState > ActivityManager.PROCESS_STATE_TOP);
18757                is--) {
18758            ServiceRecord s = app.services.valueAt(is);
18759            if (s.startRequested) {
18760                app.hasStartedServices = true;
18761                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18762                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18763                }
18764                if (app.hasShownUi && app != mHomeProcess) {
18765                    // If this process has shown some UI, let it immediately
18766                    // go to the LRU list because it may be pretty heavy with
18767                    // UI stuff.  We'll tag it with a label just to help
18768                    // debug and understand what is going on.
18769                    if (adj > ProcessList.SERVICE_ADJ) {
18770                        app.adjType = "cch-started-ui-services";
18771                    }
18772                } else {
18773                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18774                        // This service has seen some activity within
18775                        // recent memory, so we will keep its process ahead
18776                        // of the background processes.
18777                        if (adj > ProcessList.SERVICE_ADJ) {
18778                            adj = ProcessList.SERVICE_ADJ;
18779                            app.adjType = "started-services";
18780                            app.cached = false;
18781                        }
18782                    }
18783                    // If we have let the service slide into the background
18784                    // state, still have some text describing what it is doing
18785                    // even though the service no longer has an impact.
18786                    if (adj > ProcessList.SERVICE_ADJ) {
18787                        app.adjType = "cch-started-services";
18788                    }
18789                }
18790            }
18791            for (int conni = s.connections.size()-1;
18792                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18793                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18794                            || procState > ActivityManager.PROCESS_STATE_TOP);
18795                    conni--) {
18796                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18797                for (int i = 0;
18798                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18799                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18800                                || procState > ActivityManager.PROCESS_STATE_TOP);
18801                        i++) {
18802                    // XXX should compute this based on the max of
18803                    // all connected clients.
18804                    ConnectionRecord cr = clist.get(i);
18805                    if (cr.binding.client == app) {
18806                        // Binding to ourself is not interesting.
18807                        continue;
18808                    }
18809                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18810                        ProcessRecord client = cr.binding.client;
18811                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18812                                TOP_APP, doingAll, now);
18813                        int clientProcState = client.curProcState;
18814                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18815                            // If the other app is cached for any reason, for purposes here
18816                            // we are going to consider it empty.  The specific cached state
18817                            // doesn't propagate except under certain conditions.
18818                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18819                        }
18820                        String adjType = null;
18821                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18822                            // Not doing bind OOM management, so treat
18823                            // this guy more like a started service.
18824                            if (app.hasShownUi && app != mHomeProcess) {
18825                                // If this process has shown some UI, let it immediately
18826                                // go to the LRU list because it may be pretty heavy with
18827                                // UI stuff.  We'll tag it with a label just to help
18828                                // debug and understand what is going on.
18829                                if (adj > clientAdj) {
18830                                    adjType = "cch-bound-ui-services";
18831                                }
18832                                app.cached = false;
18833                                clientAdj = adj;
18834                                clientProcState = procState;
18835                            } else {
18836                                if (now >= (s.lastActivity
18837                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18838                                    // This service has not seen activity within
18839                                    // recent memory, so allow it to drop to the
18840                                    // LRU list if there is no other reason to keep
18841                                    // it around.  We'll also tag it with a label just
18842                                    // to help debug and undertand what is going on.
18843                                    if (adj > clientAdj) {
18844                                        adjType = "cch-bound-services";
18845                                    }
18846                                    clientAdj = adj;
18847                                }
18848                            }
18849                        }
18850                        if (adj > clientAdj) {
18851                            // If this process has recently shown UI, and
18852                            // the process that is binding to it is less
18853                            // important than being visible, then we don't
18854                            // care about the binding as much as we care
18855                            // about letting this process get into the LRU
18856                            // list to be killed and restarted if needed for
18857                            // memory.
18858                            if (app.hasShownUi && app != mHomeProcess
18859                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18860                                adjType = "cch-bound-ui-services";
18861                            } else {
18862                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18863                                        |Context.BIND_IMPORTANT)) != 0) {
18864                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18865                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18866                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18867                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18868                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18869                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18870                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18871                                    adj = clientAdj;
18872                                } else {
18873                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18874                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18875                                    }
18876                                }
18877                                if (!client.cached) {
18878                                    app.cached = false;
18879                                }
18880                                adjType = "service";
18881                            }
18882                        }
18883                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18884                            // This will treat important bound services identically to
18885                            // the top app, which may behave differently than generic
18886                            // foreground work.
18887                            if (client.curSchedGroup > schedGroup) {
18888                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18889                                    schedGroup = client.curSchedGroup;
18890                                } else {
18891                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18892                                }
18893                            }
18894                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18895                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18896                                    // Special handling of clients who are in the top state.
18897                                    // We *may* want to consider this process to be in the
18898                                    // top state as well, but only if there is not another
18899                                    // reason for it to be running.  Being on the top is a
18900                                    // special state, meaning you are specifically running
18901                                    // for the current top app.  If the process is already
18902                                    // running in the background for some other reason, it
18903                                    // is more important to continue considering it to be
18904                                    // in the background state.
18905                                    mayBeTop = true;
18906                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18907                                } else {
18908                                    // Special handling for above-top states (persistent
18909                                    // processes).  These should not bring the current process
18910                                    // into the top state, since they are not on top.  Instead
18911                                    // give them the best state after that.
18912                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18913                                        clientProcState =
18914                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18915                                    } else if (mWakefulness
18916                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18917                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18918                                                    != 0) {
18919                                        clientProcState =
18920                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18921                                    } else {
18922                                        clientProcState =
18923                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18924                                    }
18925                                }
18926                            }
18927                        } else {
18928                            if (clientProcState <
18929                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18930                                clientProcState =
18931                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18932                            }
18933                        }
18934                        if (procState > clientProcState) {
18935                            procState = clientProcState;
18936                        }
18937                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18938                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18939                            app.pendingUiClean = true;
18940                        }
18941                        if (adjType != null) {
18942                            app.adjType = adjType;
18943                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18944                                    .REASON_SERVICE_IN_USE;
18945                            app.adjSource = cr.binding.client;
18946                            app.adjSourceProcState = clientProcState;
18947                            app.adjTarget = s.name;
18948                        }
18949                    }
18950                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18951                        app.treatLikeActivity = true;
18952                    }
18953                    final ActivityRecord a = cr.activity;
18954                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18955                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18956                            (a.visible || a.state == ActivityState.RESUMED ||
18957                             a.state == ActivityState.PAUSING)) {
18958                            adj = ProcessList.FOREGROUND_APP_ADJ;
18959                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18960                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18961                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18962                                } else {
18963                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18964                                }
18965                            }
18966                            app.cached = false;
18967                            app.adjType = "service";
18968                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18969                                    .REASON_SERVICE_IN_USE;
18970                            app.adjSource = a;
18971                            app.adjSourceProcState = procState;
18972                            app.adjTarget = s.name;
18973                        }
18974                    }
18975                }
18976            }
18977        }
18978
18979        for (int provi = app.pubProviders.size()-1;
18980                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18981                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18982                        || procState > ActivityManager.PROCESS_STATE_TOP);
18983                provi--) {
18984            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18985            for (int i = cpr.connections.size()-1;
18986                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18987                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18988                            || procState > ActivityManager.PROCESS_STATE_TOP);
18989                    i--) {
18990                ContentProviderConnection conn = cpr.connections.get(i);
18991                ProcessRecord client = conn.client;
18992                if (client == app) {
18993                    // Being our own client is not interesting.
18994                    continue;
18995                }
18996                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18997                int clientProcState = client.curProcState;
18998                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18999                    // If the other app is cached for any reason, for purposes here
19000                    // we are going to consider it empty.
19001                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19002                }
19003                if (adj > clientAdj) {
19004                    if (app.hasShownUi && app != mHomeProcess
19005                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19006                        app.adjType = "cch-ui-provider";
19007                    } else {
19008                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19009                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19010                        app.adjType = "provider";
19011                    }
19012                    app.cached &= client.cached;
19013                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19014                            .REASON_PROVIDER_IN_USE;
19015                    app.adjSource = client;
19016                    app.adjSourceProcState = clientProcState;
19017                    app.adjTarget = cpr.name;
19018                }
19019                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19020                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19021                        // Special handling of clients who are in the top state.
19022                        // We *may* want to consider this process to be in the
19023                        // top state as well, but only if there is not another
19024                        // reason for it to be running.  Being on the top is a
19025                        // special state, meaning you are specifically running
19026                        // for the current top app.  If the process is already
19027                        // running in the background for some other reason, it
19028                        // is more important to continue considering it to be
19029                        // in the background state.
19030                        mayBeTop = true;
19031                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19032                    } else {
19033                        // Special handling for above-top states (persistent
19034                        // processes).  These should not bring the current process
19035                        // into the top state, since they are not on top.  Instead
19036                        // give them the best state after that.
19037                        clientProcState =
19038                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19039                    }
19040                }
19041                if (procState > clientProcState) {
19042                    procState = clientProcState;
19043                }
19044                if (client.curSchedGroup > schedGroup) {
19045                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19046                }
19047            }
19048            // If the provider has external (non-framework) process
19049            // dependencies, ensure that its adjustment is at least
19050            // FOREGROUND_APP_ADJ.
19051            if (cpr.hasExternalProcessHandles()) {
19052                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19053                    adj = ProcessList.FOREGROUND_APP_ADJ;
19054                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19055                    app.cached = false;
19056                    app.adjType = "provider";
19057                    app.adjTarget = cpr.name;
19058                }
19059                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19060                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19061                }
19062            }
19063        }
19064
19065        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19066            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19067                adj = ProcessList.PREVIOUS_APP_ADJ;
19068                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19069                app.cached = false;
19070                app.adjType = "provider";
19071            }
19072            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19073                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19074            }
19075        }
19076
19077        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19078            // A client of one of our services or providers is in the top state.  We
19079            // *may* want to be in the top state, but not if we are already running in
19080            // the background for some other reason.  For the decision here, we are going
19081            // to pick out a few specific states that we want to remain in when a client
19082            // is top (states that tend to be longer-term) and otherwise allow it to go
19083            // to the top state.
19084            switch (procState) {
19085                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19086                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19087                case ActivityManager.PROCESS_STATE_SERVICE:
19088                    // These all are longer-term states, so pull them up to the top
19089                    // of the background states, but not all the way to the top state.
19090                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19091                    break;
19092                default:
19093                    // Otherwise, top is a better choice, so take it.
19094                    procState = ActivityManager.PROCESS_STATE_TOP;
19095                    break;
19096            }
19097        }
19098
19099        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19100            if (app.hasClientActivities) {
19101                // This is a cached process, but with client activities.  Mark it so.
19102                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19103                app.adjType = "cch-client-act";
19104            } else if (app.treatLikeActivity) {
19105                // This is a cached process, but somebody wants us to treat it like it has
19106                // an activity, okay!
19107                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19108                app.adjType = "cch-as-act";
19109            }
19110        }
19111
19112        if (adj == ProcessList.SERVICE_ADJ) {
19113            if (doingAll) {
19114                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19115                mNewNumServiceProcs++;
19116                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19117                if (!app.serviceb) {
19118                    // This service isn't far enough down on the LRU list to
19119                    // normally be a B service, but if we are low on RAM and it
19120                    // is large we want to force it down since we would prefer to
19121                    // keep launcher over it.
19122                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19123                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19124                        app.serviceHighRam = true;
19125                        app.serviceb = true;
19126                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19127                    } else {
19128                        mNewNumAServiceProcs++;
19129                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19130                    }
19131                } else {
19132                    app.serviceHighRam = false;
19133                }
19134            }
19135            if (app.serviceb) {
19136                adj = ProcessList.SERVICE_B_ADJ;
19137            }
19138        }
19139
19140        app.curRawAdj = adj;
19141
19142        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19143        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19144        if (adj > app.maxAdj) {
19145            adj = app.maxAdj;
19146            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19147                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19148            }
19149        }
19150
19151        // Do final modification to adj.  Everything we do between here and applying
19152        // the final setAdj must be done in this function, because we will also use
19153        // it when computing the final cached adj later.  Note that we don't need to
19154        // worry about this for max adj above, since max adj will always be used to
19155        // keep it out of the cached vaues.
19156        app.curAdj = app.modifyRawOomAdj(adj);
19157        app.curSchedGroup = schedGroup;
19158        app.curProcState = procState;
19159        app.foregroundActivities = foregroundActivities;
19160
19161        return app.curRawAdj;
19162    }
19163
19164    /**
19165     * Record new PSS sample for a process.
19166     */
19167    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19168            long now) {
19169        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19170                swapPss * 1024);
19171        proc.lastPssTime = now;
19172        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19173        if (DEBUG_PSS) Slog.d(TAG_PSS,
19174                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19175                + " state=" + ProcessList.makeProcStateString(procState));
19176        if (proc.initialIdlePss == 0) {
19177            proc.initialIdlePss = pss;
19178        }
19179        proc.lastPss = pss;
19180        proc.lastSwapPss = swapPss;
19181        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19182            proc.lastCachedPss = pss;
19183            proc.lastCachedSwapPss = swapPss;
19184        }
19185
19186        final SparseArray<Pair<Long, String>> watchUids
19187                = mMemWatchProcesses.getMap().get(proc.processName);
19188        Long check = null;
19189        if (watchUids != null) {
19190            Pair<Long, String> val = watchUids.get(proc.uid);
19191            if (val == null) {
19192                val = watchUids.get(0);
19193            }
19194            if (val != null) {
19195                check = val.first;
19196            }
19197        }
19198        if (check != null) {
19199            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19200                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19201                if (!isDebuggable) {
19202                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19203                        isDebuggable = true;
19204                    }
19205                }
19206                if (isDebuggable) {
19207                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19208                    final ProcessRecord myProc = proc;
19209                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19210                    mMemWatchDumpProcName = proc.processName;
19211                    mMemWatchDumpFile = heapdumpFile.toString();
19212                    mMemWatchDumpPid = proc.pid;
19213                    mMemWatchDumpUid = proc.uid;
19214                    BackgroundThread.getHandler().post(new Runnable() {
19215                        @Override
19216                        public void run() {
19217                            revokeUriPermission(ActivityThread.currentActivityThread()
19218                                            .getApplicationThread(),
19219                                    DumpHeapActivity.JAVA_URI,
19220                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19221                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19222                                    UserHandle.myUserId());
19223                            ParcelFileDescriptor fd = null;
19224                            try {
19225                                heapdumpFile.delete();
19226                                fd = ParcelFileDescriptor.open(heapdumpFile,
19227                                        ParcelFileDescriptor.MODE_CREATE |
19228                                                ParcelFileDescriptor.MODE_TRUNCATE |
19229                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19230                                                ParcelFileDescriptor.MODE_APPEND);
19231                                IApplicationThread thread = myProc.thread;
19232                                if (thread != null) {
19233                                    try {
19234                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19235                                                "Requesting dump heap from "
19236                                                + myProc + " to " + heapdumpFile);
19237                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19238                                    } catch (RemoteException e) {
19239                                    }
19240                                }
19241                            } catch (FileNotFoundException e) {
19242                                e.printStackTrace();
19243                            } finally {
19244                                if (fd != null) {
19245                                    try {
19246                                        fd.close();
19247                                    } catch (IOException e) {
19248                                    }
19249                                }
19250                            }
19251                        }
19252                    });
19253                } else {
19254                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19255                            + ", but debugging not enabled");
19256                }
19257            }
19258        }
19259    }
19260
19261    /**
19262     * Schedule PSS collection of a process.
19263     */
19264    void requestPssLocked(ProcessRecord proc, int procState) {
19265        if (mPendingPssProcesses.contains(proc)) {
19266            return;
19267        }
19268        if (mPendingPssProcesses.size() == 0) {
19269            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19270        }
19271        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19272        proc.pssProcState = procState;
19273        mPendingPssProcesses.add(proc);
19274    }
19275
19276    /**
19277     * Schedule PSS collection of all processes.
19278     */
19279    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19280        if (!always) {
19281            if (now < (mLastFullPssTime +
19282                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19283                return;
19284            }
19285        }
19286        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19287        mLastFullPssTime = now;
19288        mFullPssPending = true;
19289        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19290        mPendingPssProcesses.clear();
19291        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19292            ProcessRecord app = mLruProcesses.get(i);
19293            if (app.thread == null
19294                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19295                continue;
19296            }
19297            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19298                app.pssProcState = app.setProcState;
19299                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19300                        mTestPssMode, isSleeping(), now);
19301                mPendingPssProcesses.add(app);
19302            }
19303        }
19304        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19305    }
19306
19307    public void setTestPssMode(boolean enabled) {
19308        synchronized (this) {
19309            mTestPssMode = enabled;
19310            if (enabled) {
19311                // Whenever we enable the mode, we want to take a snapshot all of current
19312                // process mem use.
19313                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19314            }
19315        }
19316    }
19317
19318    /**
19319     * Ask a given process to GC right now.
19320     */
19321    final void performAppGcLocked(ProcessRecord app) {
19322        try {
19323            app.lastRequestedGc = SystemClock.uptimeMillis();
19324            if (app.thread != null) {
19325                if (app.reportLowMemory) {
19326                    app.reportLowMemory = false;
19327                    app.thread.scheduleLowMemory();
19328                } else {
19329                    app.thread.processInBackground();
19330                }
19331            }
19332        } catch (Exception e) {
19333            // whatever.
19334        }
19335    }
19336
19337    /**
19338     * Returns true if things are idle enough to perform GCs.
19339     */
19340    private final boolean canGcNowLocked() {
19341        boolean processingBroadcasts = false;
19342        for (BroadcastQueue q : mBroadcastQueues) {
19343            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19344                processingBroadcasts = true;
19345            }
19346        }
19347        return !processingBroadcasts
19348                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19349    }
19350
19351    /**
19352     * Perform GCs on all processes that are waiting for it, but only
19353     * if things are idle.
19354     */
19355    final void performAppGcsLocked() {
19356        final int N = mProcessesToGc.size();
19357        if (N <= 0) {
19358            return;
19359        }
19360        if (canGcNowLocked()) {
19361            while (mProcessesToGc.size() > 0) {
19362                ProcessRecord proc = mProcessesToGc.remove(0);
19363                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19364                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19365                            <= SystemClock.uptimeMillis()) {
19366                        // To avoid spamming the system, we will GC processes one
19367                        // at a time, waiting a few seconds between each.
19368                        performAppGcLocked(proc);
19369                        scheduleAppGcsLocked();
19370                        return;
19371                    } else {
19372                        // It hasn't been long enough since we last GCed this
19373                        // process...  put it in the list to wait for its time.
19374                        addProcessToGcListLocked(proc);
19375                        break;
19376                    }
19377                }
19378            }
19379
19380            scheduleAppGcsLocked();
19381        }
19382    }
19383
19384    /**
19385     * If all looks good, perform GCs on all processes waiting for them.
19386     */
19387    final void performAppGcsIfAppropriateLocked() {
19388        if (canGcNowLocked()) {
19389            performAppGcsLocked();
19390            return;
19391        }
19392        // Still not idle, wait some more.
19393        scheduleAppGcsLocked();
19394    }
19395
19396    /**
19397     * Schedule the execution of all pending app GCs.
19398     */
19399    final void scheduleAppGcsLocked() {
19400        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19401
19402        if (mProcessesToGc.size() > 0) {
19403            // Schedule a GC for the time to the next process.
19404            ProcessRecord proc = mProcessesToGc.get(0);
19405            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19406
19407            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19408            long now = SystemClock.uptimeMillis();
19409            if (when < (now+GC_TIMEOUT)) {
19410                when = now + GC_TIMEOUT;
19411            }
19412            mHandler.sendMessageAtTime(msg, when);
19413        }
19414    }
19415
19416    /**
19417     * Add a process to the array of processes waiting to be GCed.  Keeps the
19418     * list in sorted order by the last GC time.  The process can't already be
19419     * on the list.
19420     */
19421    final void addProcessToGcListLocked(ProcessRecord proc) {
19422        boolean added = false;
19423        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19424            if (mProcessesToGc.get(i).lastRequestedGc <
19425                    proc.lastRequestedGc) {
19426                added = true;
19427                mProcessesToGc.add(i+1, proc);
19428                break;
19429            }
19430        }
19431        if (!added) {
19432            mProcessesToGc.add(0, proc);
19433        }
19434    }
19435
19436    /**
19437     * Set up to ask a process to GC itself.  This will either do it
19438     * immediately, or put it on the list of processes to gc the next
19439     * time things are idle.
19440     */
19441    final void scheduleAppGcLocked(ProcessRecord app) {
19442        long now = SystemClock.uptimeMillis();
19443        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19444            return;
19445        }
19446        if (!mProcessesToGc.contains(app)) {
19447            addProcessToGcListLocked(app);
19448            scheduleAppGcsLocked();
19449        }
19450    }
19451
19452    final void checkExcessivePowerUsageLocked(boolean doKills) {
19453        updateCpuStatsNow();
19454
19455        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19456        boolean doWakeKills = doKills;
19457        boolean doCpuKills = doKills;
19458        if (mLastPowerCheckRealtime == 0) {
19459            doWakeKills = false;
19460        }
19461        if (mLastPowerCheckUptime == 0) {
19462            doCpuKills = false;
19463        }
19464        if (stats.isScreenOn()) {
19465            doWakeKills = false;
19466        }
19467        final long curRealtime = SystemClock.elapsedRealtime();
19468        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19469        final long curUptime = SystemClock.uptimeMillis();
19470        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19471        mLastPowerCheckRealtime = curRealtime;
19472        mLastPowerCheckUptime = curUptime;
19473        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19474            doWakeKills = false;
19475        }
19476        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19477            doCpuKills = false;
19478        }
19479        int i = mLruProcesses.size();
19480        while (i > 0) {
19481            i--;
19482            ProcessRecord app = mLruProcesses.get(i);
19483            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19484                long wtime;
19485                synchronized (stats) {
19486                    wtime = stats.getProcessWakeTime(app.info.uid,
19487                            app.pid, curRealtime);
19488                }
19489                long wtimeUsed = wtime - app.lastWakeTime;
19490                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19491                if (DEBUG_POWER) {
19492                    StringBuilder sb = new StringBuilder(128);
19493                    sb.append("Wake for ");
19494                    app.toShortString(sb);
19495                    sb.append(": over ");
19496                    TimeUtils.formatDuration(realtimeSince, sb);
19497                    sb.append(" used ");
19498                    TimeUtils.formatDuration(wtimeUsed, sb);
19499                    sb.append(" (");
19500                    sb.append((wtimeUsed*100)/realtimeSince);
19501                    sb.append("%)");
19502                    Slog.i(TAG_POWER, sb.toString());
19503                    sb.setLength(0);
19504                    sb.append("CPU for ");
19505                    app.toShortString(sb);
19506                    sb.append(": over ");
19507                    TimeUtils.formatDuration(uptimeSince, sb);
19508                    sb.append(" used ");
19509                    TimeUtils.formatDuration(cputimeUsed, sb);
19510                    sb.append(" (");
19511                    sb.append((cputimeUsed*100)/uptimeSince);
19512                    sb.append("%)");
19513                    Slog.i(TAG_POWER, sb.toString());
19514                }
19515                // If a process has held a wake lock for more
19516                // than 50% of the time during this period,
19517                // that sounds bad.  Kill!
19518                if (doWakeKills && realtimeSince > 0
19519                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19520                    synchronized (stats) {
19521                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19522                                realtimeSince, wtimeUsed);
19523                    }
19524                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19525                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19526                } else if (doCpuKills && uptimeSince > 0
19527                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19528                    synchronized (stats) {
19529                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19530                                uptimeSince, cputimeUsed);
19531                    }
19532                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19533                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19534                } else {
19535                    app.lastWakeTime = wtime;
19536                    app.lastCpuTime = app.curCpuTime;
19537                }
19538            }
19539        }
19540    }
19541
19542    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19543            long nowElapsed) {
19544        boolean success = true;
19545
19546        if (app.curRawAdj != app.setRawAdj) {
19547            app.setRawAdj = app.curRawAdj;
19548        }
19549
19550        int changes = 0;
19551
19552        if (app.curAdj != app.setAdj) {
19553            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19554            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19555                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19556                    + app.adjType);
19557            app.setAdj = app.curAdj;
19558        }
19559
19560        if (app.setSchedGroup != app.curSchedGroup) {
19561            app.setSchedGroup = app.curSchedGroup;
19562            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19563                    "Setting sched group of " + app.processName
19564                    + " to " + app.curSchedGroup);
19565            if (app.waitingToKill != null && app.curReceiver == null
19566                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19567                app.kill(app.waitingToKill, true);
19568                success = false;
19569            } else {
19570                int processGroup;
19571                switch (app.curSchedGroup) {
19572                    case ProcessList.SCHED_GROUP_BACKGROUND:
19573                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19574                        break;
19575                    case ProcessList.SCHED_GROUP_TOP_APP:
19576                        processGroup = Process.THREAD_GROUP_TOP_APP;
19577                        break;
19578                    default:
19579                        processGroup = Process.THREAD_GROUP_DEFAULT;
19580                        break;
19581                }
19582                if (true) {
19583                    long oldId = Binder.clearCallingIdentity();
19584                    try {
19585                        Process.setProcessGroup(app.pid, processGroup);
19586                    } catch (Exception e) {
19587                        Slog.w(TAG, "Failed setting process group of " + app.pid
19588                                + " to " + app.curSchedGroup);
19589                        e.printStackTrace();
19590                    } finally {
19591                        Binder.restoreCallingIdentity(oldId);
19592                    }
19593                } else {
19594                    if (app.thread != null) {
19595                        try {
19596                            app.thread.setSchedulingGroup(processGroup);
19597                        } catch (RemoteException e) {
19598                        }
19599                    }
19600                }
19601            }
19602        }
19603        if (app.repForegroundActivities != app.foregroundActivities) {
19604            app.repForegroundActivities = app.foregroundActivities;
19605            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19606        }
19607        if (app.repProcState != app.curProcState) {
19608            app.repProcState = app.curProcState;
19609            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19610            if (app.thread != null) {
19611                try {
19612                    if (false) {
19613                        //RuntimeException h = new RuntimeException("here");
19614                        Slog.i(TAG, "Sending new process state " + app.repProcState
19615                                + " to " + app /*, h*/);
19616                    }
19617                    app.thread.setProcessState(app.repProcState);
19618                } catch (RemoteException e) {
19619                }
19620            }
19621        }
19622        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19623                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19624            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19625                // Experimental code to more aggressively collect pss while
19626                // running test...  the problem is that this tends to collect
19627                // the data right when a process is transitioning between process
19628                // states, which well tend to give noisy data.
19629                long start = SystemClock.uptimeMillis();
19630                long pss = Debug.getPss(app.pid, mTmpLong, null);
19631                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19632                mPendingPssProcesses.remove(app);
19633                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19634                        + " to " + app.curProcState + ": "
19635                        + (SystemClock.uptimeMillis()-start) + "ms");
19636            }
19637            app.lastStateTime = now;
19638            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19639                    mTestPssMode, isSleeping(), now);
19640            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19641                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19642                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19643                    + (app.nextPssTime-now) + ": " + app);
19644        } else {
19645            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19646                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19647                    mTestPssMode)))) {
19648                requestPssLocked(app, app.setProcState);
19649                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19650                        mTestPssMode, isSleeping(), now);
19651            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19652                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19653        }
19654        if (app.setProcState != app.curProcState) {
19655            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19656                    "Proc state change of " + app.processName
19657                            + " to " + app.curProcState);
19658            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19659            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19660            if (setImportant && !curImportant) {
19661                // This app is no longer something we consider important enough to allow to
19662                // use arbitrary amounts of battery power.  Note
19663                // its current wake lock time to later know to kill it if
19664                // it is not behaving well.
19665                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19666                synchronized (stats) {
19667                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19668                            app.pid, nowElapsed);
19669                }
19670                app.lastCpuTime = app.curCpuTime;
19671
19672            }
19673            // Inform UsageStats of important process state change
19674            // Must be called before updating setProcState
19675            maybeUpdateUsageStatsLocked(app, nowElapsed);
19676
19677            app.setProcState = app.curProcState;
19678            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19679                app.notCachedSinceIdle = false;
19680            }
19681            if (!doingAll) {
19682                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19683            } else {
19684                app.procStateChanged = true;
19685            }
19686        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19687                > USAGE_STATS_INTERACTION_INTERVAL) {
19688            // For apps that sit around for a long time in the interactive state, we need
19689            // to report this at least once a day so they don't go idle.
19690            maybeUpdateUsageStatsLocked(app, nowElapsed);
19691        }
19692
19693        if (changes != 0) {
19694            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19695                    "Changes in " + app + ": " + changes);
19696            int i = mPendingProcessChanges.size()-1;
19697            ProcessChangeItem item = null;
19698            while (i >= 0) {
19699                item = mPendingProcessChanges.get(i);
19700                if (item.pid == app.pid) {
19701                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19702                            "Re-using existing item: " + item);
19703                    break;
19704                }
19705                i--;
19706            }
19707            if (i < 0) {
19708                // No existing item in pending changes; need a new one.
19709                final int NA = mAvailProcessChanges.size();
19710                if (NA > 0) {
19711                    item = mAvailProcessChanges.remove(NA-1);
19712                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19713                            "Retrieving available item: " + item);
19714                } else {
19715                    item = new ProcessChangeItem();
19716                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19717                            "Allocating new item: " + item);
19718                }
19719                item.changes = 0;
19720                item.pid = app.pid;
19721                item.uid = app.info.uid;
19722                if (mPendingProcessChanges.size() == 0) {
19723                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19724                            "*** Enqueueing dispatch processes changed!");
19725                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19726                }
19727                mPendingProcessChanges.add(item);
19728            }
19729            item.changes |= changes;
19730            item.processState = app.repProcState;
19731            item.foregroundActivities = app.repForegroundActivities;
19732            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19733                    "Item " + Integer.toHexString(System.identityHashCode(item))
19734                    + " " + app.toShortString() + ": changes=" + item.changes
19735                    + " procState=" + item.processState
19736                    + " foreground=" + item.foregroundActivities
19737                    + " type=" + app.adjType + " source=" + app.adjSource
19738                    + " target=" + app.adjTarget);
19739        }
19740
19741        return success;
19742    }
19743
19744    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19745        final UidRecord.ChangeItem pendingChange;
19746        if (uidRec == null || uidRec.pendingChange == null) {
19747            if (mPendingUidChanges.size() == 0) {
19748                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19749                        "*** Enqueueing dispatch uid changed!");
19750                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19751            }
19752            final int NA = mAvailUidChanges.size();
19753            if (NA > 0) {
19754                pendingChange = mAvailUidChanges.remove(NA-1);
19755                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19756                        "Retrieving available item: " + pendingChange);
19757            } else {
19758                pendingChange = new UidRecord.ChangeItem();
19759                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19760                        "Allocating new item: " + pendingChange);
19761            }
19762            if (uidRec != null) {
19763                uidRec.pendingChange = pendingChange;
19764                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19765                    // If this uid is going away, and we haven't yet reported it is gone,
19766                    // then do so now.
19767                    change = UidRecord.CHANGE_GONE_IDLE;
19768                }
19769            } else if (uid < 0) {
19770                throw new IllegalArgumentException("No UidRecord or uid");
19771            }
19772            pendingChange.uidRecord = uidRec;
19773            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19774            mPendingUidChanges.add(pendingChange);
19775        } else {
19776            pendingChange = uidRec.pendingChange;
19777            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19778                change = UidRecord.CHANGE_GONE_IDLE;
19779            }
19780        }
19781        pendingChange.change = change;
19782        pendingChange.processState = uidRec != null
19783                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19784    }
19785
19786    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19787            String authority) {
19788        if (app == null) return;
19789        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19790            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19791            if (userState == null) return;
19792            final long now = SystemClock.elapsedRealtime();
19793            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19794            if (lastReported == null || lastReported < now - 60 * 1000L) {
19795                mUsageStatsService.reportContentProviderUsage(
19796                        authority, providerPkgName, app.userId);
19797                userState.mProviderLastReportedFg.put(authority, now);
19798            }
19799        }
19800    }
19801
19802    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19803        if (DEBUG_USAGE_STATS) {
19804            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19805                    + "] state changes: old = " + app.setProcState + ", new = "
19806                    + app.curProcState);
19807        }
19808        if (mUsageStatsService == null) {
19809            return;
19810        }
19811        boolean isInteraction;
19812        // To avoid some abuse patterns, we are going to be careful about what we consider
19813        // to be an app interaction.  Being the top activity doesn't count while the display
19814        // is sleeping, nor do short foreground services.
19815        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19816            isInteraction = true;
19817            app.fgInteractionTime = 0;
19818        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19819            if (app.fgInteractionTime == 0) {
19820                app.fgInteractionTime = nowElapsed;
19821                isInteraction = false;
19822            } else {
19823                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19824            }
19825        } else {
19826            isInteraction = app.curProcState
19827                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19828            app.fgInteractionTime = 0;
19829        }
19830        if (isInteraction && (!app.reportedInteraction
19831                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19832            app.interactionEventTime = nowElapsed;
19833            String[] packages = app.getPackageList();
19834            if (packages != null) {
19835                for (int i = 0; i < packages.length; i++) {
19836                    mUsageStatsService.reportEvent(packages[i], app.userId,
19837                            UsageEvents.Event.SYSTEM_INTERACTION);
19838                }
19839            }
19840        }
19841        app.reportedInteraction = isInteraction;
19842        if (!isInteraction) {
19843            app.interactionEventTime = 0;
19844        }
19845    }
19846
19847    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19848        if (proc.thread != null) {
19849            if (proc.baseProcessTracker != null) {
19850                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19851            }
19852        }
19853    }
19854
19855    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19856            ProcessRecord TOP_APP, boolean doingAll, long now) {
19857        if (app.thread == null) {
19858            return false;
19859        }
19860
19861        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19862
19863        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19864    }
19865
19866    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19867            boolean oomAdj) {
19868        if (isForeground != proc.foregroundServices) {
19869            proc.foregroundServices = isForeground;
19870            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19871                    proc.info.uid);
19872            if (isForeground) {
19873                if (curProcs == null) {
19874                    curProcs = new ArrayList<ProcessRecord>();
19875                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19876                }
19877                if (!curProcs.contains(proc)) {
19878                    curProcs.add(proc);
19879                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19880                            proc.info.packageName, proc.info.uid);
19881                }
19882            } else {
19883                if (curProcs != null) {
19884                    if (curProcs.remove(proc)) {
19885                        mBatteryStatsService.noteEvent(
19886                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19887                                proc.info.packageName, proc.info.uid);
19888                        if (curProcs.size() <= 0) {
19889                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19890                        }
19891                    }
19892                }
19893            }
19894            if (oomAdj) {
19895                updateOomAdjLocked();
19896            }
19897        }
19898    }
19899
19900    private final ActivityRecord resumedAppLocked() {
19901        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19902        String pkg;
19903        int uid;
19904        if (act != null) {
19905            pkg = act.packageName;
19906            uid = act.info.applicationInfo.uid;
19907        } else {
19908            pkg = null;
19909            uid = -1;
19910        }
19911        // Has the UID or resumed package name changed?
19912        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19913                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19914            if (mCurResumedPackage != null) {
19915                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19916                        mCurResumedPackage, mCurResumedUid);
19917            }
19918            mCurResumedPackage = pkg;
19919            mCurResumedUid = uid;
19920            if (mCurResumedPackage != null) {
19921                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19922                        mCurResumedPackage, mCurResumedUid);
19923            }
19924        }
19925        return act;
19926    }
19927
19928    final boolean updateOomAdjLocked(ProcessRecord app) {
19929        final ActivityRecord TOP_ACT = resumedAppLocked();
19930        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19931        final boolean wasCached = app.cached;
19932
19933        mAdjSeq++;
19934
19935        // This is the desired cached adjusment we want to tell it to use.
19936        // If our app is currently cached, we know it, and that is it.  Otherwise,
19937        // we don't know it yet, and it needs to now be cached we will then
19938        // need to do a complete oom adj.
19939        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19940                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19941        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19942                SystemClock.uptimeMillis());
19943        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19944            // Changed to/from cached state, so apps after it in the LRU
19945            // list may also be changed.
19946            updateOomAdjLocked();
19947        }
19948        return success;
19949    }
19950
19951    final void updateOomAdjLocked() {
19952        final ActivityRecord TOP_ACT = resumedAppLocked();
19953        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19954        final long now = SystemClock.uptimeMillis();
19955        final long nowElapsed = SystemClock.elapsedRealtime();
19956        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19957        final int N = mLruProcesses.size();
19958
19959        if (false) {
19960            RuntimeException e = new RuntimeException();
19961            e.fillInStackTrace();
19962            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19963        }
19964
19965        // Reset state in all uid records.
19966        for (int i=mActiveUids.size()-1; i>=0; i--) {
19967            final UidRecord uidRec = mActiveUids.valueAt(i);
19968            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19969                    "Starting update of " + uidRec);
19970            uidRec.reset();
19971        }
19972
19973        mStackSupervisor.rankTaskLayersIfNeeded();
19974
19975        mAdjSeq++;
19976        mNewNumServiceProcs = 0;
19977        mNewNumAServiceProcs = 0;
19978
19979        final int emptyProcessLimit;
19980        final int cachedProcessLimit;
19981        if (mProcessLimit <= 0) {
19982            emptyProcessLimit = cachedProcessLimit = 0;
19983        } else if (mProcessLimit == 1) {
19984            emptyProcessLimit = 1;
19985            cachedProcessLimit = 0;
19986        } else {
19987            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19988            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19989        }
19990
19991        // Let's determine how many processes we have running vs.
19992        // how many slots we have for background processes; we may want
19993        // to put multiple processes in a slot of there are enough of
19994        // them.
19995        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19996                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19997        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19998        if (numEmptyProcs > cachedProcessLimit) {
19999            // If there are more empty processes than our limit on cached
20000            // processes, then use the cached process limit for the factor.
20001            // This ensures that the really old empty processes get pushed
20002            // down to the bottom, so if we are running low on memory we will
20003            // have a better chance at keeping around more cached processes
20004            // instead of a gazillion empty processes.
20005            numEmptyProcs = cachedProcessLimit;
20006        }
20007        int emptyFactor = numEmptyProcs/numSlots;
20008        if (emptyFactor < 1) emptyFactor = 1;
20009        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20010        if (cachedFactor < 1) cachedFactor = 1;
20011        int stepCached = 0;
20012        int stepEmpty = 0;
20013        int numCached = 0;
20014        int numEmpty = 0;
20015        int numTrimming = 0;
20016
20017        mNumNonCachedProcs = 0;
20018        mNumCachedHiddenProcs = 0;
20019
20020        // First update the OOM adjustment for each of the
20021        // application processes based on their current state.
20022        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20023        int nextCachedAdj = curCachedAdj+1;
20024        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20025        int nextEmptyAdj = curEmptyAdj+2;
20026        for (int i=N-1; i>=0; i--) {
20027            ProcessRecord app = mLruProcesses.get(i);
20028            if (!app.killedByAm && app.thread != null) {
20029                app.procStateChanged = false;
20030                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20031
20032                // If we haven't yet assigned the final cached adj
20033                // to the process, do that now.
20034                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20035                    switch (app.curProcState) {
20036                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20037                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20038                            // This process is a cached process holding activities...
20039                            // assign it the next cached value for that type, and then
20040                            // step that cached level.
20041                            app.curRawAdj = curCachedAdj;
20042                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20043                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20044                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20045                                    + ")");
20046                            if (curCachedAdj != nextCachedAdj) {
20047                                stepCached++;
20048                                if (stepCached >= cachedFactor) {
20049                                    stepCached = 0;
20050                                    curCachedAdj = nextCachedAdj;
20051                                    nextCachedAdj += 2;
20052                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20053                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20054                                    }
20055                                }
20056                            }
20057                            break;
20058                        default:
20059                            // For everything else, assign next empty cached process
20060                            // level and bump that up.  Note that this means that
20061                            // long-running services that have dropped down to the
20062                            // cached level will be treated as empty (since their process
20063                            // state is still as a service), which is what we want.
20064                            app.curRawAdj = curEmptyAdj;
20065                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20066                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20067                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20068                                    + ")");
20069                            if (curEmptyAdj != nextEmptyAdj) {
20070                                stepEmpty++;
20071                                if (stepEmpty >= emptyFactor) {
20072                                    stepEmpty = 0;
20073                                    curEmptyAdj = nextEmptyAdj;
20074                                    nextEmptyAdj += 2;
20075                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20076                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20077                                    }
20078                                }
20079                            }
20080                            break;
20081                    }
20082                }
20083
20084                applyOomAdjLocked(app, true, now, nowElapsed);
20085
20086                // Count the number of process types.
20087                switch (app.curProcState) {
20088                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20089                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20090                        mNumCachedHiddenProcs++;
20091                        numCached++;
20092                        if (numCached > cachedProcessLimit) {
20093                            app.kill("cached #" + numCached, true);
20094                        }
20095                        break;
20096                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20097                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20098                                && app.lastActivityTime < oldTime) {
20099                            app.kill("empty for "
20100                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20101                                    / 1000) + "s", true);
20102                        } else {
20103                            numEmpty++;
20104                            if (numEmpty > emptyProcessLimit) {
20105                                app.kill("empty #" + numEmpty, DEBUG_PROCESSES);
20106                            }
20107                        }
20108                        break;
20109                    default:
20110                        mNumNonCachedProcs++;
20111                        break;
20112                }
20113
20114                if (app.isolated && app.services.size() <= 0) {
20115                    // If this is an isolated process, and there are no
20116                    // services running in it, then the process is no longer
20117                    // needed.  We agressively kill these because we can by
20118                    // definition not re-use the same process again, and it is
20119                    // good to avoid having whatever code was running in them
20120                    // left sitting around after no longer needed.
20121                    app.kill("isolated not needed", true);
20122                } else {
20123                    // Keeping this process, update its uid.
20124                    final UidRecord uidRec = app.uidRecord;
20125                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20126                        uidRec.curProcState = app.curProcState;
20127                    }
20128                }
20129
20130                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20131                        && !app.killedByAm) {
20132                    numTrimming++;
20133                }
20134            }
20135        }
20136
20137        mNumServiceProcs = mNewNumServiceProcs;
20138
20139        // Now determine the memory trimming level of background processes.
20140        // Unfortunately we need to start at the back of the list to do this
20141        // properly.  We only do this if the number of background apps we
20142        // are managing to keep around is less than half the maximum we desire;
20143        // if we are keeping a good number around, we'll let them use whatever
20144        // memory they want.
20145        final int numCachedAndEmpty = numCached + numEmpty;
20146        int memFactor;
20147        if (numCached <= ProcessList.TRIM_CACHED_APPS
20148                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20149            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20150                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20151            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20152                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20153            } else {
20154                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20155            }
20156        } else {
20157            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20158        }
20159        // We always allow the memory level to go up (better).  We only allow it to go
20160        // down if we are in a state where that is allowed, *and* the total number of processes
20161        // has gone down since last time.
20162        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20163                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20164                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20165        if (memFactor > mLastMemoryLevel) {
20166            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20167                memFactor = mLastMemoryLevel;
20168                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20169            }
20170        }
20171        mLastMemoryLevel = memFactor;
20172        mLastNumProcesses = mLruProcesses.size();
20173        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20174        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20175        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20176            if (mLowRamStartTime == 0) {
20177                mLowRamStartTime = now;
20178            }
20179            int step = 0;
20180            int fgTrimLevel;
20181            switch (memFactor) {
20182                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20183                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20184                    break;
20185                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20186                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20187                    break;
20188                default:
20189                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20190                    break;
20191            }
20192            int factor = numTrimming/3;
20193            int minFactor = 2;
20194            if (mHomeProcess != null) minFactor++;
20195            if (mPreviousProcess != null) minFactor++;
20196            if (factor < minFactor) factor = minFactor;
20197            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20198            for (int i=N-1; i>=0; i--) {
20199                ProcessRecord app = mLruProcesses.get(i);
20200                if (allChanged || app.procStateChanged) {
20201                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20202                    app.procStateChanged = false;
20203                }
20204                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20205                        && !app.killedByAm) {
20206                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20207                        try {
20208                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20209                                    "Trimming memory of " + app.processName + " to " + curLevel);
20210                            app.thread.scheduleTrimMemory(curLevel);
20211                        } catch (RemoteException e) {
20212                        }
20213                        if (false) {
20214                            // For now we won't do this; our memory trimming seems
20215                            // to be good enough at this point that destroying
20216                            // activities causes more harm than good.
20217                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20218                                    && app != mHomeProcess && app != mPreviousProcess) {
20219                                // Need to do this on its own message because the stack may not
20220                                // be in a consistent state at this point.
20221                                // For these apps we will also finish their activities
20222                                // to help them free memory.
20223                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20224                            }
20225                        }
20226                    }
20227                    app.trimMemoryLevel = curLevel;
20228                    step++;
20229                    if (step >= factor) {
20230                        step = 0;
20231                        switch (curLevel) {
20232                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20233                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20234                                break;
20235                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20236                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20237                                break;
20238                        }
20239                    }
20240                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20241                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20242                            && app.thread != null) {
20243                        try {
20244                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20245                                    "Trimming memory of heavy-weight " + app.processName
20246                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20247                            app.thread.scheduleTrimMemory(
20248                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20249                        } catch (RemoteException e) {
20250                        }
20251                    }
20252                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20253                } else {
20254                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20255                            || app.systemNoUi) && app.pendingUiClean) {
20256                        // If this application is now in the background and it
20257                        // had done UI, then give it the special trim level to
20258                        // have it free UI resources.
20259                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20260                        if (app.trimMemoryLevel < level && app.thread != null) {
20261                            try {
20262                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20263                                        "Trimming memory of bg-ui " + app.processName
20264                                        + " to " + level);
20265                                app.thread.scheduleTrimMemory(level);
20266                            } catch (RemoteException e) {
20267                            }
20268                        }
20269                        app.pendingUiClean = false;
20270                    }
20271                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20272                        try {
20273                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20274                                    "Trimming memory of fg " + app.processName
20275                                    + " to " + fgTrimLevel);
20276                            app.thread.scheduleTrimMemory(fgTrimLevel);
20277                        } catch (RemoteException e) {
20278                        }
20279                    }
20280                    app.trimMemoryLevel = fgTrimLevel;
20281                }
20282            }
20283        } else {
20284            if (mLowRamStartTime != 0) {
20285                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20286                mLowRamStartTime = 0;
20287            }
20288            for (int i=N-1; i>=0; i--) {
20289                ProcessRecord app = mLruProcesses.get(i);
20290                if (allChanged || app.procStateChanged) {
20291                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20292                    app.procStateChanged = false;
20293                }
20294                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20295                        || app.systemNoUi) && app.pendingUiClean) {
20296                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20297                            && app.thread != null) {
20298                        try {
20299                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20300                                    "Trimming memory of ui hidden " + app.processName
20301                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20302                            app.thread.scheduleTrimMemory(
20303                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20304                        } catch (RemoteException e) {
20305                        }
20306                    }
20307                    app.pendingUiClean = false;
20308                }
20309                app.trimMemoryLevel = 0;
20310            }
20311        }
20312
20313        if (mAlwaysFinishActivities) {
20314            // Need to do this on its own message because the stack may not
20315            // be in a consistent state at this point.
20316            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20317        }
20318
20319        if (allChanged) {
20320            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20321        }
20322
20323        // Update from any uid changes.
20324        for (int i=mActiveUids.size()-1; i>=0; i--) {
20325            final UidRecord uidRec = mActiveUids.valueAt(i);
20326            int uidChange = UidRecord.CHANGE_PROCSTATE;
20327            if (uidRec.setProcState != uidRec.curProcState) {
20328                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20329                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20330                        + " to " + uidRec.curProcState);
20331                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20332                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20333                        uidRec.lastBackgroundTime = nowElapsed;
20334                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20335                            // Note: the background settle time is in elapsed realtime, while
20336                            // the handler time base is uptime.  All this means is that we may
20337                            // stop background uids later than we had intended, but that only
20338                            // happens because the device was sleeping so we are okay anyway.
20339                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20340                        }
20341                    }
20342                } else {
20343                    if (uidRec.idle) {
20344                        uidChange = UidRecord.CHANGE_ACTIVE;
20345                        uidRec.idle = false;
20346                    }
20347                    uidRec.lastBackgroundTime = 0;
20348                }
20349                uidRec.setProcState = uidRec.curProcState;
20350                enqueueUidChangeLocked(uidRec, -1, uidChange);
20351                mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
20352            }
20353        }
20354
20355        if (mProcessStats.shouldWriteNowLocked(now)) {
20356            mHandler.post(new Runnable() {
20357                @Override public void run() {
20358                    synchronized (ActivityManagerService.this) {
20359                        mProcessStats.writeStateAsyncLocked();
20360                    }
20361                }
20362            });
20363        }
20364
20365        if (DEBUG_OOM_ADJ) {
20366            final long duration = SystemClock.uptimeMillis() - now;
20367            if (false) {
20368                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20369                        new RuntimeException("here").fillInStackTrace());
20370            } else {
20371                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20372            }
20373        }
20374    }
20375
20376    final void idleUids() {
20377        synchronized (this) {
20378            final long nowElapsed = SystemClock.elapsedRealtime();
20379            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20380            long nextTime = 0;
20381            for (int i=mActiveUids.size()-1; i>=0; i--) {
20382                final UidRecord uidRec = mActiveUids.valueAt(i);
20383                final long bgTime = uidRec.lastBackgroundTime;
20384                if (bgTime > 0 && !uidRec.idle) {
20385                    if (bgTime <= maxBgTime) {
20386                        uidRec.idle = true;
20387                        doStopUidLocked(uidRec.uid, uidRec);
20388                    } else {
20389                        if (nextTime == 0 || nextTime > bgTime) {
20390                            nextTime = bgTime;
20391                        }
20392                    }
20393                }
20394            }
20395            if (nextTime > 0) {
20396                mHandler.removeMessages(IDLE_UIDS_MSG);
20397                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20398                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20399            }
20400        }
20401    }
20402
20403    final void runInBackgroundDisabled(int uid) {
20404        synchronized (this) {
20405            UidRecord uidRec = mActiveUids.get(uid);
20406            if (uidRec != null) {
20407                // This uid is actually running...  should it be considered background now?
20408                if (uidRec.idle) {
20409                    doStopUidLocked(uidRec.uid, uidRec);
20410                }
20411            } else {
20412                // This uid isn't actually running...  still send a report about it being "stopped".
20413                doStopUidLocked(uid, null);
20414            }
20415        }
20416    }
20417
20418    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20419        mServices.stopInBackgroundLocked(uid);
20420        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20421    }
20422
20423    final void trimApplications() {
20424        synchronized (this) {
20425            int i;
20426
20427            // First remove any unused application processes whose package
20428            // has been removed.
20429            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20430                final ProcessRecord app = mRemovedProcesses.get(i);
20431                if (app.activities.size() == 0
20432                        && app.curReceiver == null && app.services.size() == 0) {
20433                    Slog.i(
20434                        TAG, "Exiting empty application process "
20435                        + app.processName + " ("
20436                        + (app.thread != null ? app.thread.asBinder() : null)
20437                        + ")\n");
20438                    if (app.pid > 0 && app.pid != MY_PID) {
20439                        app.kill("empty", false);
20440                    } else {
20441                        try {
20442                            app.thread.scheduleExit();
20443                        } catch (Exception e) {
20444                            // Ignore exceptions.
20445                        }
20446                    }
20447                    cleanUpApplicationRecordLocked(app, false, true, -1);
20448                    mRemovedProcesses.remove(i);
20449
20450                    if (app.persistent) {
20451                        addAppLocked(app.info, false, null /* ABI override */);
20452                    }
20453                }
20454            }
20455
20456            // Now update the oom adj for all processes.
20457            updateOomAdjLocked();
20458        }
20459    }
20460
20461    /** This method sends the specified signal to each of the persistent apps */
20462    public void signalPersistentProcesses(int sig) throws RemoteException {
20463        if (sig != Process.SIGNAL_USR1) {
20464            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20465        }
20466
20467        synchronized (this) {
20468            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20469                    != PackageManager.PERMISSION_GRANTED) {
20470                throw new SecurityException("Requires permission "
20471                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20472            }
20473
20474            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20475                ProcessRecord r = mLruProcesses.get(i);
20476                if (r.thread != null && r.persistent) {
20477                    Process.sendSignal(r.pid, sig);
20478                }
20479            }
20480        }
20481    }
20482
20483    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20484        if (proc == null || proc == mProfileProc) {
20485            proc = mProfileProc;
20486            profileType = mProfileType;
20487            clearProfilerLocked();
20488        }
20489        if (proc == null) {
20490            return;
20491        }
20492        try {
20493            proc.thread.profilerControl(false, null, profileType);
20494        } catch (RemoteException e) {
20495            throw new IllegalStateException("Process disappeared");
20496        }
20497    }
20498
20499    private void clearProfilerLocked() {
20500        if (mProfileFd != null) {
20501            try {
20502                mProfileFd.close();
20503            } catch (IOException e) {
20504            }
20505        }
20506        mProfileApp = null;
20507        mProfileProc = null;
20508        mProfileFile = null;
20509        mProfileType = 0;
20510        mAutoStopProfiler = false;
20511        mSamplingInterval = 0;
20512    }
20513
20514    public boolean profileControl(String process, int userId, boolean start,
20515            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20516
20517        try {
20518            synchronized (this) {
20519                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20520                // its own permission.
20521                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20522                        != PackageManager.PERMISSION_GRANTED) {
20523                    throw new SecurityException("Requires permission "
20524                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20525                }
20526
20527                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20528                    throw new IllegalArgumentException("null profile info or fd");
20529                }
20530
20531                ProcessRecord proc = null;
20532                if (process != null) {
20533                    proc = findProcessLocked(process, userId, "profileControl");
20534                }
20535
20536                if (start && (proc == null || proc.thread == null)) {
20537                    throw new IllegalArgumentException("Unknown process: " + process);
20538                }
20539
20540                if (start) {
20541                    stopProfilerLocked(null, 0);
20542                    setProfileApp(proc.info, proc.processName, profilerInfo);
20543                    mProfileProc = proc;
20544                    mProfileType = profileType;
20545                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20546                    try {
20547                        fd = fd.dup();
20548                    } catch (IOException e) {
20549                        fd = null;
20550                    }
20551                    profilerInfo.profileFd = fd;
20552                    proc.thread.profilerControl(start, profilerInfo, profileType);
20553                    fd = null;
20554                    mProfileFd = null;
20555                } else {
20556                    stopProfilerLocked(proc, profileType);
20557                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20558                        try {
20559                            profilerInfo.profileFd.close();
20560                        } catch (IOException e) {
20561                        }
20562                    }
20563                }
20564
20565                return true;
20566            }
20567        } catch (RemoteException e) {
20568            throw new IllegalStateException("Process disappeared");
20569        } finally {
20570            if (profilerInfo != null && profilerInfo.profileFd != null) {
20571                try {
20572                    profilerInfo.profileFd.close();
20573                } catch (IOException e) {
20574                }
20575            }
20576        }
20577    }
20578
20579    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20580        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20581                userId, true, ALLOW_FULL_ONLY, callName, null);
20582        ProcessRecord proc = null;
20583        try {
20584            int pid = Integer.parseInt(process);
20585            synchronized (mPidsSelfLocked) {
20586                proc = mPidsSelfLocked.get(pid);
20587            }
20588        } catch (NumberFormatException e) {
20589        }
20590
20591        if (proc == null) {
20592            ArrayMap<String, SparseArray<ProcessRecord>> all
20593                    = mProcessNames.getMap();
20594            SparseArray<ProcessRecord> procs = all.get(process);
20595            if (procs != null && procs.size() > 0) {
20596                proc = procs.valueAt(0);
20597                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20598                    for (int i=1; i<procs.size(); i++) {
20599                        ProcessRecord thisProc = procs.valueAt(i);
20600                        if (thisProc.userId == userId) {
20601                            proc = thisProc;
20602                            break;
20603                        }
20604                    }
20605                }
20606            }
20607        }
20608
20609        return proc;
20610    }
20611
20612    public boolean dumpHeap(String process, int userId, boolean managed,
20613            String path, ParcelFileDescriptor fd) throws RemoteException {
20614
20615        try {
20616            synchronized (this) {
20617                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20618                // its own permission (same as profileControl).
20619                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20620                        != PackageManager.PERMISSION_GRANTED) {
20621                    throw new SecurityException("Requires permission "
20622                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20623                }
20624
20625                if (fd == null) {
20626                    throw new IllegalArgumentException("null fd");
20627                }
20628
20629                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20630                if (proc == null || proc.thread == null) {
20631                    throw new IllegalArgumentException("Unknown process: " + process);
20632                }
20633
20634                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20635                if (!isDebuggable) {
20636                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20637                        throw new SecurityException("Process not debuggable: " + proc);
20638                    }
20639                }
20640
20641                proc.thread.dumpHeap(managed, path, fd);
20642                fd = null;
20643                return true;
20644            }
20645        } catch (RemoteException e) {
20646            throw new IllegalStateException("Process disappeared");
20647        } finally {
20648            if (fd != null) {
20649                try {
20650                    fd.close();
20651                } catch (IOException e) {
20652                }
20653            }
20654        }
20655    }
20656
20657    @Override
20658    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20659            String reportPackage) {
20660        if (processName != null) {
20661            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20662                    "setDumpHeapDebugLimit()");
20663        } else {
20664            synchronized (mPidsSelfLocked) {
20665                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20666                if (proc == null) {
20667                    throw new SecurityException("No process found for calling pid "
20668                            + Binder.getCallingPid());
20669                }
20670                if (!Build.IS_DEBUGGABLE
20671                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20672                    throw new SecurityException("Not running a debuggable build");
20673                }
20674                processName = proc.processName;
20675                uid = proc.uid;
20676                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20677                    throw new SecurityException("Package " + reportPackage + " is not running in "
20678                            + proc);
20679                }
20680            }
20681        }
20682        synchronized (this) {
20683            if (maxMemSize > 0) {
20684                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20685            } else {
20686                if (uid != 0) {
20687                    mMemWatchProcesses.remove(processName, uid);
20688                } else {
20689                    mMemWatchProcesses.getMap().remove(processName);
20690                }
20691            }
20692        }
20693    }
20694
20695    @Override
20696    public void dumpHeapFinished(String path) {
20697        synchronized (this) {
20698            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20699                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20700                        + " does not match last pid " + mMemWatchDumpPid);
20701                return;
20702            }
20703            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20704                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20705                        + " does not match last path " + mMemWatchDumpFile);
20706                return;
20707            }
20708            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20709            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20710        }
20711    }
20712
20713    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20714    public void monitor() {
20715        synchronized (this) { }
20716    }
20717
20718    void onCoreSettingsChange(Bundle settings) {
20719        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20720            ProcessRecord processRecord = mLruProcesses.get(i);
20721            try {
20722                if (processRecord.thread != null) {
20723                    processRecord.thread.setCoreSettings(settings);
20724                }
20725            } catch (RemoteException re) {
20726                /* ignore */
20727            }
20728        }
20729    }
20730
20731    // Multi-user methods
20732
20733    /**
20734     * Start user, if its not already running, but don't bring it to foreground.
20735     */
20736    @Override
20737    public boolean startUserInBackground(final int userId) {
20738        return mUserController.startUser(userId, /* foreground */ false);
20739    }
20740
20741    @Override
20742    public boolean unlockUser(int userId, byte[] token, byte[] secret) {
20743        return mUserController.unlockUser(userId, token, secret);
20744    }
20745
20746    @Override
20747    public boolean switchUser(final int targetUserId) {
20748        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20749        UserInfo currentUserInfo;
20750        UserInfo targetUserInfo;
20751        synchronized (this) {
20752            int currentUserId = mUserController.getCurrentUserIdLocked();
20753            currentUserInfo = mUserController.getUserInfo(currentUserId);
20754            targetUserInfo = mUserController.getUserInfo(targetUserId);
20755            if (targetUserInfo == null) {
20756                Slog.w(TAG, "No user info for user #" + targetUserId);
20757                return false;
20758            }
20759            if (!targetUserInfo.supportsSwitchTo()) {
20760                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20761                return false;
20762            }
20763            if (targetUserInfo.isManagedProfile()) {
20764                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20765                return false;
20766            }
20767            mUserController.setTargetUserIdLocked(targetUserId);
20768        }
20769        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20770        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20771        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20772        return true;
20773    }
20774
20775    void scheduleStartProfilesLocked() {
20776        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20777            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20778                    DateUtils.SECOND_IN_MILLIS);
20779        }
20780    }
20781
20782    @Override
20783    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20784        return mUserController.stopUser(userId, force, callback);
20785    }
20786
20787    @Override
20788    public UserInfo getCurrentUser() {
20789        return mUserController.getCurrentUser();
20790    }
20791
20792    @Override
20793    public boolean isUserRunning(int userId, int flags) {
20794        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20795                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20796            String msg = "Permission Denial: isUserRunning() from pid="
20797                    + Binder.getCallingPid()
20798                    + ", uid=" + Binder.getCallingUid()
20799                    + " requires " + INTERACT_ACROSS_USERS;
20800            Slog.w(TAG, msg);
20801            throw new SecurityException(msg);
20802        }
20803        synchronized (this) {
20804            return mUserController.isUserRunningLocked(userId, flags);
20805        }
20806    }
20807
20808    @Override
20809    public int[] getRunningUserIds() {
20810        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20811                != PackageManager.PERMISSION_GRANTED) {
20812            String msg = "Permission Denial: isUserRunning() from pid="
20813                    + Binder.getCallingPid()
20814                    + ", uid=" + Binder.getCallingUid()
20815                    + " requires " + INTERACT_ACROSS_USERS;
20816            Slog.w(TAG, msg);
20817            throw new SecurityException(msg);
20818        }
20819        synchronized (this) {
20820            return mUserController.getStartedUserArrayLocked();
20821        }
20822    }
20823
20824    @Override
20825    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20826        mUserController.registerUserSwitchObserver(observer);
20827    }
20828
20829    @Override
20830    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20831        mUserController.unregisterUserSwitchObserver(observer);
20832    }
20833
20834    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20835        if (info == null) return null;
20836        ApplicationInfo newInfo = new ApplicationInfo(info);
20837        newInfo.initForUser(userId);
20838        return newInfo;
20839    }
20840
20841    public boolean isUserStopped(int userId) {
20842        synchronized (this) {
20843            return mUserController.getStartedUserStateLocked(userId) == null;
20844        }
20845    }
20846
20847    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20848        if (aInfo == null
20849                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20850            return aInfo;
20851        }
20852
20853        ActivityInfo info = new ActivityInfo(aInfo);
20854        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20855        return info;
20856    }
20857
20858    private boolean processSanityChecksLocked(ProcessRecord process) {
20859        if (process == null || process.thread == null) {
20860            return false;
20861        }
20862
20863        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20864        if (!isDebuggable) {
20865            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20866                return false;
20867            }
20868        }
20869
20870        return true;
20871    }
20872
20873    public boolean startBinderTracking() throws RemoteException {
20874        synchronized (this) {
20875            mBinderTransactionTrackingEnabled = true;
20876            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20877            // permission (same as profileControl).
20878            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20879                    != PackageManager.PERMISSION_GRANTED) {
20880                throw new SecurityException("Requires permission "
20881                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20882            }
20883
20884            for (int i = 0; i < mLruProcesses.size(); i++) {
20885                ProcessRecord process = mLruProcesses.get(i);
20886                if (!processSanityChecksLocked(process)) {
20887                    continue;
20888                }
20889                try {
20890                    process.thread.startBinderTracking();
20891                } catch (RemoteException e) {
20892                    Log.v(TAG, "Process disappared");
20893                }
20894            }
20895            return true;
20896        }
20897    }
20898
20899    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20900        try {
20901            synchronized (this) {
20902                mBinderTransactionTrackingEnabled = false;
20903                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20904                // permission (same as profileControl).
20905                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20906                        != PackageManager.PERMISSION_GRANTED) {
20907                    throw new SecurityException("Requires permission "
20908                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20909                }
20910
20911                if (fd == null) {
20912                    throw new IllegalArgumentException("null fd");
20913                }
20914
20915                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20916                pw.println("Binder transaction traces for all processes.\n");
20917                for (ProcessRecord process : mLruProcesses) {
20918                    if (!processSanityChecksLocked(process)) {
20919                        continue;
20920                    }
20921
20922                    pw.println("Traces for process: " + process.processName);
20923                    pw.flush();
20924                    try {
20925                        TransferPipe tp = new TransferPipe();
20926                        try {
20927                            process.thread.stopBinderTrackingAndDump(
20928                                    tp.getWriteFd().getFileDescriptor());
20929                            tp.go(fd.getFileDescriptor());
20930                        } finally {
20931                            tp.kill();
20932                        }
20933                    } catch (IOException e) {
20934                        pw.println("Failure while dumping IPC traces from " + process +
20935                                ".  Exception: " + e);
20936                        pw.flush();
20937                    } catch (RemoteException e) {
20938                        pw.println("Got a RemoteException while dumping IPC traces from " +
20939                                process + ".  Exception: " + e);
20940                        pw.flush();
20941                    }
20942                }
20943                fd = null;
20944                return true;
20945            }
20946        } finally {
20947            if (fd != null) {
20948                try {
20949                    fd.close();
20950                } catch (IOException e) {
20951                }
20952            }
20953        }
20954    }
20955
20956    private final class LocalService extends ActivityManagerInternal {
20957        @Override
20958        public void onWakefulnessChanged(int wakefulness) {
20959            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20960        }
20961
20962        @Override
20963        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20964                String processName, String abiOverride, int uid, Runnable crashHandler) {
20965            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20966                    processName, abiOverride, uid, crashHandler);
20967        }
20968
20969        @Override
20970        public SleepToken acquireSleepToken(String tag) {
20971            Preconditions.checkNotNull(tag);
20972
20973            synchronized (ActivityManagerService.this) {
20974                SleepTokenImpl token = new SleepTokenImpl(tag);
20975                mSleepTokens.add(token);
20976                updateSleepIfNeededLocked();
20977                return token;
20978            }
20979        }
20980
20981        @Override
20982        public ComponentName getHomeActivityForUser(int userId) {
20983            synchronized (ActivityManagerService.this) {
20984                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20985                return homeActivity == null ? null : homeActivity.realActivity;
20986            }
20987        }
20988
20989        @Override
20990        public void onUserRemoved(int userId) {
20991            synchronized (ActivityManagerService.this) {
20992                ActivityManagerService.this.onUserStoppedLocked(userId);
20993            }
20994        }
20995
20996        @Override
20997        public void onLocalVoiceInteractionStarted(IBinder activity,
20998                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
20999            synchronized (ActivityManagerService.this) {
21000                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21001                        voiceSession, voiceInteractor);
21002            }
21003        }
21004
21005        @Override
21006        public void notifyStartingWindowDrawn() {
21007            synchronized (ActivityManagerService.this) {
21008                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21009            }
21010        }
21011
21012        @Override
21013        public void notifyAppTransitionStarting(int reason) {
21014            synchronized (ActivityManagerService.this) {
21015                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21016            }
21017        }
21018    }
21019
21020    private final class SleepTokenImpl extends SleepToken {
21021        private final String mTag;
21022        private final long mAcquireTime;
21023
21024        public SleepTokenImpl(String tag) {
21025            mTag = tag;
21026            mAcquireTime = SystemClock.uptimeMillis();
21027        }
21028
21029        @Override
21030        public void release() {
21031            synchronized (ActivityManagerService.this) {
21032                if (mSleepTokens.remove(this)) {
21033                    updateSleepIfNeededLocked();
21034                }
21035            }
21036        }
21037
21038        @Override
21039        public String toString() {
21040            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21041        }
21042    }
21043
21044    /**
21045     * An implementation of IAppTask, that allows an app to manage its own tasks via
21046     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21047     * only the process that calls getAppTasks() can call the AppTask methods.
21048     */
21049    class AppTaskImpl extends IAppTask.Stub {
21050        private int mTaskId;
21051        private int mCallingUid;
21052
21053        public AppTaskImpl(int taskId, int callingUid) {
21054            mTaskId = taskId;
21055            mCallingUid = callingUid;
21056        }
21057
21058        private void checkCaller() {
21059            if (mCallingUid != Binder.getCallingUid()) {
21060                throw new SecurityException("Caller " + mCallingUid
21061                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21062            }
21063        }
21064
21065        @Override
21066        public void finishAndRemoveTask() {
21067            checkCaller();
21068
21069            synchronized (ActivityManagerService.this) {
21070                long origId = Binder.clearCallingIdentity();
21071                try {
21072                    // We remove the task from recents to preserve backwards
21073                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21074                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21075                    }
21076                } finally {
21077                    Binder.restoreCallingIdentity(origId);
21078                }
21079            }
21080        }
21081
21082        @Override
21083        public ActivityManager.RecentTaskInfo getTaskInfo() {
21084            checkCaller();
21085
21086            synchronized (ActivityManagerService.this) {
21087                long origId = Binder.clearCallingIdentity();
21088                try {
21089                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21090                    if (tr == null) {
21091                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21092                    }
21093                    return createRecentTaskInfoFromTaskRecord(tr);
21094                } finally {
21095                    Binder.restoreCallingIdentity(origId);
21096                }
21097            }
21098        }
21099
21100        @Override
21101        public void moveToFront() {
21102            checkCaller();
21103            // Will bring task to front if it already has a root activity.
21104            final long origId = Binder.clearCallingIdentity();
21105            try {
21106                startActivityFromRecentsInner(mTaskId, null);
21107            } finally {
21108                Binder.restoreCallingIdentity(origId);
21109            }
21110        }
21111
21112        @Override
21113        public int startActivity(IBinder whoThread, String callingPackage,
21114                Intent intent, String resolvedType, Bundle bOptions) {
21115            checkCaller();
21116
21117            int callingUser = UserHandle.getCallingUserId();
21118            TaskRecord tr;
21119            IApplicationThread appThread;
21120            synchronized (ActivityManagerService.this) {
21121                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21122                if (tr == null) {
21123                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21124                }
21125                appThread = ApplicationThreadNative.asInterface(whoThread);
21126                if (appThread == null) {
21127                    throw new IllegalArgumentException("Bad app thread " + appThread);
21128                }
21129            }
21130            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21131                    resolvedType, null, null, null, null, 0, 0, null, null,
21132                    null, bOptions, false, callingUser, null, tr);
21133        }
21134
21135        @Override
21136        public void setExcludeFromRecents(boolean exclude) {
21137            checkCaller();
21138
21139            synchronized (ActivityManagerService.this) {
21140                long origId = Binder.clearCallingIdentity();
21141                try {
21142                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21143                    if (tr == null) {
21144                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21145                    }
21146                    Intent intent = tr.getBaseIntent();
21147                    if (exclude) {
21148                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21149                    } else {
21150                        intent.setFlags(intent.getFlags()
21151                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21152                    }
21153                } finally {
21154                    Binder.restoreCallingIdentity(origId);
21155                }
21156            }
21157        }
21158    }
21159
21160    /**
21161     * Kill processes for the user with id userId and that depend on the package named packageName
21162     */
21163    @Override
21164    public void killPackageDependents(String packageName, int userId) {
21165        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21166        if (packageName == null) {
21167            throw new NullPointerException(
21168                    "Cannot kill the dependents of a package without its name.");
21169        }
21170
21171        long callingId = Binder.clearCallingIdentity();
21172        IPackageManager pm = AppGlobals.getPackageManager();
21173        int pkgUid = -1;
21174        try {
21175            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21176        } catch (RemoteException e) {
21177        }
21178        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21179            throw new IllegalArgumentException(
21180                    "Cannot kill dependents of non-existing package " + packageName);
21181        }
21182        try {
21183            synchronized(this) {
21184                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21185                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21186                        "dep: " + packageName);
21187            }
21188        } finally {
21189            Binder.restoreCallingIdentity(callingId);
21190        }
21191    }
21192}
21193