ActivityManagerService.java revision 9c2f0d751d16360a2cd857b1db752f0009481b21
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;
21
22import com.android.internal.R;
23import com.android.internal.annotations.GuardedBy;
24import com.android.internal.app.AssistUtils;
25import com.android.internal.app.DumpHeapActivity;
26import com.android.internal.app.IAppOpsCallback;
27import com.android.internal.app.IAppOpsService;
28import com.android.internal.app.IVoiceInteractor;
29import com.android.internal.app.ProcessMap;
30import com.android.internal.app.ProcessStats;
31import com.android.internal.app.SystemUserHomeActivity;
32import com.android.internal.os.BackgroundThread;
33import com.android.internal.os.BatteryStatsImpl;
34import com.android.internal.os.IResultReceiver;
35import com.android.internal.os.ProcessCpuTracker;
36import com.android.internal.os.TransferPipe;
37import com.android.internal.os.Zygote;
38import com.android.internal.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.ServiceThread;
49import com.android.server.SystemService;
50import com.android.server.SystemServiceManager;
51import com.android.server.Watchdog;
52import com.android.server.am.ActivityStack.ActivityState;
53import com.android.server.firewall.IntentFirewall;
54import com.android.server.pm.Installer;
55import com.android.server.statusbar.StatusBarManagerInternal;
56import com.android.server.wm.AppTransition;
57import com.android.server.wm.WindowManagerService;
58
59import org.xmlpull.v1.XmlPullParser;
60import org.xmlpull.v1.XmlPullParserException;
61import org.xmlpull.v1.XmlSerializer;
62
63import android.Manifest;
64import android.app.Activity;
65import android.app.ActivityManager;
66import android.app.ActivityManager.RunningTaskInfo;
67import android.app.ActivityManager.StackId;
68import android.app.ActivityManager.StackInfo;
69import android.app.ActivityManager.TaskThumbnailInfo;
70import android.app.ActivityManagerInternal;
71import android.app.ActivityManagerInternal.SleepToken;
72import android.app.ActivityManagerNative;
73import android.app.ActivityOptions;
74import android.app.ActivityThread;
75import android.app.AlertDialog;
76import android.app.AppGlobals;
77import android.app.AppOpsManager;
78import android.app.ApplicationErrorReport;
79import android.app.ApplicationThreadNative;
80import android.app.BroadcastOptions;
81import android.app.Dialog;
82import android.app.IActivityContainer;
83import android.app.IActivityContainerCallback;
84import android.app.IActivityController;
85import android.app.IAppTask;
86import android.app.IApplicationThread;
87import android.app.IInstrumentationWatcher;
88import android.app.INotificationManager;
89import android.app.IProcessObserver;
90import android.app.IServiceConnection;
91import android.app.IStopUserCallback;
92import android.app.ITaskStackListener;
93import android.app.IUiAutomationConnection;
94import android.app.IUidObserver;
95import android.app.IUserSwitchObserver;
96import android.app.Instrumentation;
97import android.app.Notification;
98import android.app.NotificationManager;
99import android.app.PendingIntent;
100import android.app.ProfilerInfo;
101import android.app.admin.DevicePolicyManager;
102import android.app.assist.AssistContent;
103import android.app.assist.AssistStructure;
104import android.app.backup.IBackupManager;
105import android.app.usage.UsageEvents;
106import android.app.usage.UsageStatsManagerInternal;
107import android.appwidget.AppWidgetManager;
108import android.content.ActivityNotFoundException;
109import android.content.BroadcastReceiver;
110import android.content.ClipData;
111import android.content.ComponentCallbacks2;
112import android.content.ComponentName;
113import android.content.ContentProvider;
114import android.content.ContentResolver;
115import android.content.Context;
116import android.content.DialogInterface;
117import android.content.IContentProvider;
118import android.content.IIntentReceiver;
119import android.content.IIntentSender;
120import android.content.Intent;
121import android.content.IntentFilter;
122import android.content.IntentSender;
123import android.content.pm.ActivityInfo;
124import android.content.pm.ApplicationInfo;
125import android.content.pm.ConfigurationInfo;
126import android.content.pm.IPackageDataObserver;
127import android.content.pm.IPackageManager;
128import android.content.pm.InstrumentationInfo;
129import android.content.pm.PackageInfo;
130import android.content.pm.PackageManager;
131import android.content.pm.PackageManager.NameNotFoundException;
132import android.content.pm.PackageManagerInternal;
133import android.content.pm.ParceledListSlice;
134import android.content.pm.PathPermission;
135import android.content.pm.PermissionInfo;
136import android.content.pm.ProviderInfo;
137import android.content.pm.ResolveInfo;
138import android.content.pm.ServiceInfo;
139import android.content.pm.UserInfo;
140import android.content.res.CompatibilityInfo;
141import android.content.res.Configuration;
142import android.content.res.Resources;
143import android.graphics.Bitmap;
144import android.graphics.Point;
145import android.graphics.Rect;
146import android.net.Proxy;
147import android.net.ProxyInfo;
148import android.net.Uri;
149import android.os.BatteryStats;
150import android.os.Binder;
151import android.os.Build;
152import android.os.Bundle;
153import android.os.Debug;
154import android.os.DropBoxManager;
155import android.os.Environment;
156import android.os.FactoryTest;
157import android.os.FileObserver;
158import android.os.FileUtils;
159import android.os.Handler;
160import android.os.IBinder;
161import android.os.IPermissionController;
162import android.os.IProcessInfoService;
163import android.os.Looper;
164import android.os.Message;
165import android.os.Parcel;
166import android.os.ParcelFileDescriptor;
167import android.os.PersistableBundle;
168import android.os.PowerManager;
169import android.os.PowerManagerInternal;
170import android.os.Process;
171import android.os.RemoteCallbackList;
172import android.os.RemoteException;
173import android.os.ResultReceiver;
174import android.os.ServiceManager;
175import android.os.StrictMode;
176import android.os.SystemClock;
177import android.os.SystemProperties;
178import android.os.Trace;
179import android.os.TransactionTooLargeException;
180import android.os.UpdateLock;
181import android.os.UserHandle;
182import android.os.UserManager;
183import android.os.WorkSource;
184import android.os.storage.IMountService;
185import android.os.storage.MountServiceInternal;
186import android.os.storage.StorageManager;
187import android.provider.Settings;
188import android.service.voice.IVoiceInteractionSession;
189import android.service.voice.VoiceInteractionSession;
190import android.text.format.DateUtils;
191import android.text.format.Time;
192import android.util.ArrayMap;
193import android.util.ArraySet;
194import android.util.AtomicFile;
195import android.util.DebugUtils;
196import android.util.EventLog;
197import android.util.LocaleList;
198import android.util.Log;
199import android.util.Pair;
200import android.util.PrintWriterPrinter;
201import android.util.Slog;
202import android.util.SparseArray;
203import android.util.TimeUtils;
204import android.util.Xml;
205import android.view.Display;
206import android.view.Gravity;
207import android.view.LayoutInflater;
208import android.view.View;
209import android.view.WindowManager;
210
211import java.io.BufferedInputStream;
212import java.io.BufferedOutputStream;
213import java.io.DataInputStream;
214import java.io.DataOutputStream;
215import java.io.File;
216import java.io.FileDescriptor;
217import java.io.FileInputStream;
218import java.io.FileNotFoundException;
219import java.io.FileOutputStream;
220import java.io.IOException;
221import java.io.InputStreamReader;
222import java.io.PrintWriter;
223import java.io.StringWriter;
224import java.lang.ref.WeakReference;
225import java.nio.charset.StandardCharsets;
226import java.util.ArrayList;
227import java.util.Arrays;
228import java.util.Collections;
229import java.util.Comparator;
230import java.util.HashMap;
231import java.util.HashSet;
232import java.util.Iterator;
233import java.util.List;
234import java.util.Locale;
235import java.util.Map;
236import java.util.Set;
237import java.util.concurrent.atomic.AtomicBoolean;
238import java.util.concurrent.atomic.AtomicLong;
239
240import dalvik.system.VMRuntime;
241import libcore.io.IoUtils;
242import libcore.util.EmptyArray;
243
244import static android.Manifest.permission.INTERACT_ACROSS_USERS;
245import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
246import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
247import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
248import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
249import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
250import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
251import static android.app.ActivityManager.StackId.HOME_STACK_ID;
252import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
253import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
254import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
255import static android.content.pm.PackageManager.PERMISSION_GRANTED;
256import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
257import static android.provider.Settings.Global.DEBUG_APP;
258import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
259import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
260import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
261import static com.android.internal.util.XmlUtils.readBooleanAttribute;
262import static com.android.internal.util.XmlUtils.readIntAttribute;
263import static com.android.internal.util.XmlUtils.readLongAttribute;
264import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
265import static com.android.internal.util.XmlUtils.writeIntAttribute;
266import static com.android.internal.util.XmlUtils.writeLongAttribute;
267import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
268import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
269import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
270import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
271import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
272import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
273import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
274import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
275import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
276import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
277import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
278import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
279import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
280import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
281import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
282import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
283import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
284import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
285import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
286import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
287import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
299import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
300import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
301import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
302import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
303import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
304import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
305import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
306import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
307import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
308import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
309import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
310import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
311import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
312import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
313import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
314import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
315import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
316import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
317import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
318import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
319import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
323import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
324import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
325import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
326import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
327import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
328import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
329import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
330import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
331import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
332import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
333import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
334import static org.xmlpull.v1.XmlPullParser.START_TAG;
335
336public final class ActivityManagerService extends ActivityManagerNative
337        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
338
339    // File that stores last updated system version and called preboot receivers
340    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
341
342    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
343    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
344    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
345    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
346    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
347    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
348    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
349    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
350    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
351    private static final String TAG_LRU = TAG + POSTFIX_LRU;
352    private static final String TAG_MU = TAG + POSTFIX_MU;
353    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
354    private static final String TAG_POWER = TAG + POSTFIX_POWER;
355    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
356    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
357    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
358    private static final String TAG_PSS = TAG + POSTFIX_PSS;
359    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
360    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
361    private static final String TAG_STACK = TAG + POSTFIX_STACK;
362    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
363    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
364    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
365    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
366    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
367
368    /** Control over CPU and battery monitoring */
369    // write battery stats every 30 minutes.
370    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
371    static final boolean MONITOR_CPU_USAGE = true;
372    // don't sample cpu less than every 5 seconds.
373    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
374    // wait possibly forever for next cpu sample.
375    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
376    static final boolean MONITOR_THREAD_CPU_USAGE = false;
377
378    // The flags that are set for all calls we make to the package manager.
379    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
380
381    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
382
383    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
384
385    // Amount of time after a call to stopAppSwitches() during which we will
386    // prevent further untrusted switches from happening.
387    static final long APP_SWITCH_DELAY_TIME = 5*1000;
388
389    // How long we wait for a launched process to attach to the activity manager
390    // before we decide it's never going to come up for real.
391    static final int PROC_START_TIMEOUT = 10*1000;
392    // How long we wait for an attached process to publish its content providers
393    // before we decide it must be hung.
394    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
395
396    // How long we will retain processes hosting content providers in the "last activity"
397    // state before allowing them to drop down to the regular cached LRU list.  This is
398    // to avoid thrashing of provider processes under low memory situations.
399    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
400
401    // How long we wait for a launched process to attach to the activity manager
402    // before we decide it's never going to come up for real, when the process was
403    // started with a wrapper for instrumentation (such as Valgrind) because it
404    // could take much longer than usual.
405    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
406
407    // How long to wait after going idle before forcing apps to GC.
408    static final int GC_TIMEOUT = 5*1000;
409
410    // The minimum amount of time between successive GC requests for a process.
411    static final int GC_MIN_INTERVAL = 60*1000;
412
413    // The minimum amount of time between successive PSS requests for a process.
414    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
415
416    // The minimum amount of time between successive PSS requests for a process
417    // when the request is due to the memory state being lowered.
418    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
419
420    // The rate at which we check for apps using excessive power -- 15 mins.
421    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
422
423    // The minimum sample duration we will allow before deciding we have
424    // enough data on wake locks to start killing things.
425    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
426
427    // The minimum sample duration we will allow before deciding we have
428    // enough data on CPU usage to start killing things.
429    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
430
431    // How long we allow a receiver to run before giving up on it.
432    static final int BROADCAST_FG_TIMEOUT = 10*1000;
433    static final int BROADCAST_BG_TIMEOUT = 60*1000;
434
435    // How long we wait until we timeout on key dispatching.
436    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
437
438    // How long we wait until we timeout on key dispatching during instrumentation.
439    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
440
441    // This is the amount of time an app needs to be running a foreground service before
442    // we will consider it to be doing interaction for usage stats.
443    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
444
445    // Maximum amount of time we will allow to elapse before re-reporting usage stats
446    // interaction with foreground processes.
447    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
448
449    // This is the amount of time we allow an app to settle after it goes into the background,
450    // before we start restricting what it can do.
451    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
452
453    // How long to wait in getAssistContextExtras for the activity and foreground services
454    // to respond with the result.
455    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
456
457    // How long top wait when going through the modern assist (which doesn't need to block
458    // on getting this result before starting to launch its UI).
459    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
460
461    // Maximum number of persisted Uri grants a package is allowed
462    static final int MAX_PERSISTED_URI_GRANTS = 128;
463
464    static final int MY_PID = Process.myPid();
465
466    static final String[] EMPTY_STRING_ARRAY = new String[0];
467
468    // How many bytes to write into the dropbox log before truncating
469    static final int DROPBOX_MAX_SIZE = 256 * 1024;
470
471    // Access modes for handleIncomingUser.
472    static final int ALLOW_NON_FULL = 0;
473    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
474    static final int ALLOW_FULL_ONLY = 2;
475
476    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
477
478    // Delay in notifying task stack change listeners (in millis)
479    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
480
481    // Necessary ApplicationInfo flags to mark an app as persistent
482    private static final int PERSISTENT_MASK =
483            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
484
485
486    // Delay to disable app launch boost
487    static final int APP_BOOST_MESSAGE_DELAY = 3000;
488    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
489    static final int APP_BOOST_TIMEOUT = 2500;
490
491    // Used to indicate that a task is removed it should also be removed from recents.
492    private static final boolean REMOVE_FROM_RECENTS = true;
493
494    private static native int nativeMigrateToBoost();
495    private static native int nativeMigrateFromBoost();
496    private boolean mIsBoosted = false;
497    private long mBoostStartTime = 0;
498
499    /** All system services */
500    SystemServiceManager mSystemServiceManager;
501
502    private Installer mInstaller;
503
504    /** Run all ActivityStacks through this */
505    ActivityStackSupervisor mStackSupervisor;
506
507    /** Task stack change listeners. */
508    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
509            new RemoteCallbackList<ITaskStackListener>();
510
511    public IntentFirewall mIntentFirewall;
512
513    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
514    // default actuion automatically.  Important for devices without direct input
515    // devices.
516    private boolean mShowDialogs = true;
517
518    BroadcastQueue mFgBroadcastQueue;
519    BroadcastQueue mBgBroadcastQueue;
520    // Convenient for easy iteration over the queues. Foreground is first
521    // so that dispatch of foreground broadcasts gets precedence.
522    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
523
524    BroadcastQueue broadcastQueueForIntent(Intent intent) {
525        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
526        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
527                "Broadcast intent " + intent + " on "
528                + (isFg ? "foreground" : "background") + " queue");
529        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
530    }
531
532    /**
533     * Activity we have told the window manager to have key focus.
534     */
535    ActivityRecord mFocusedActivity = null;
536
537    /**
538     * User id of the last activity mFocusedActivity was set to.
539     */
540    private int mLastFocusedUserId;
541
542    /**
543     * If non-null, we are tracking the time the user spends in the currently focused app.
544     */
545    private AppTimeTracker mCurAppTimeTracker;
546
547    /**
548     * List of intents that were used to start the most recent tasks.
549     */
550    private final RecentTasks mRecentTasks;
551
552    /**
553     * For addAppTask: cached of the last activity component that was added.
554     */
555    ComponentName mLastAddedTaskComponent;
556
557    /**
558     * For addAppTask: cached of the last activity uid that was added.
559     */
560    int mLastAddedTaskUid;
561
562    /**
563     * For addAppTask: cached of the last ActivityInfo that was added.
564     */
565    ActivityInfo mLastAddedTaskActivity;
566
567    /**
568     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
569     */
570    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
571
572    /**
573     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
574     */
575    String mDeviceOwnerName;
576
577    final UserController mUserController;
578
579    public class PendingAssistExtras extends Binder implements Runnable {
580        public final ActivityRecord activity;
581        public final Bundle extras;
582        public final Intent intent;
583        public final String hint;
584        public final IResultReceiver receiver;
585        public final int userHandle;
586        public boolean haveResult = false;
587        public Bundle result = null;
588        public AssistStructure structure = null;
589        public AssistContent content = null;
590        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
591                String _hint, IResultReceiver _receiver, int _userHandle) {
592            activity = _activity;
593            extras = _extras;
594            intent = _intent;
595            hint = _hint;
596            receiver = _receiver;
597            userHandle = _userHandle;
598        }
599        @Override
600        public void run() {
601            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
602            synchronized (this) {
603                haveResult = true;
604                notifyAll();
605            }
606            pendingAssistExtrasTimedOut(this);
607        }
608    }
609
610    final ArrayList<PendingAssistExtras> mPendingAssistExtras
611            = new ArrayList<PendingAssistExtras>();
612
613    /**
614     * Process management.
615     */
616    final ProcessList mProcessList = new ProcessList();
617
618    /**
619     * All of the applications we currently have running organized by name.
620     * The keys are strings of the application package name (as
621     * returned by the package manager), and the keys are ApplicationRecord
622     * objects.
623     */
624    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
625
626    /**
627     * Tracking long-term execution of processes to look for abuse and other
628     * bad app behavior.
629     */
630    final ProcessStatsService mProcessStats;
631
632    /**
633     * The currently running isolated processes.
634     */
635    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
636
637    /**
638     * Counter for assigning isolated process uids, to avoid frequently reusing the
639     * same ones.
640     */
641    int mNextIsolatedProcessUid = 0;
642
643    /**
644     * The currently running heavy-weight process, if any.
645     */
646    ProcessRecord mHeavyWeightProcess = null;
647
648    /**
649     * The last time that various processes have crashed.
650     */
651    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
652
653    /**
654     * Information about a process that is currently marked as bad.
655     */
656    static final class BadProcessInfo {
657        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
658            this.time = time;
659            this.shortMsg = shortMsg;
660            this.longMsg = longMsg;
661            this.stack = stack;
662        }
663
664        final long time;
665        final String shortMsg;
666        final String longMsg;
667        final String stack;
668    }
669
670    /**
671     * Set of applications that we consider to be bad, and will reject
672     * incoming broadcasts from (which the user has no control over).
673     * Processes are added to this set when they have crashed twice within
674     * a minimum amount of time; they are removed from it when they are
675     * later restarted (hopefully due to some user action).  The value is the
676     * time it was added to the list.
677     */
678    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
679
680    /**
681     * All of the processes we currently have running organized by pid.
682     * The keys are the pid running the application.
683     *
684     * <p>NOTE: This object is protected by its own lock, NOT the global
685     * activity manager lock!
686     */
687    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
688
689    /**
690     * All of the processes that have been forced to be foreground.  The key
691     * is the pid of the caller who requested it (we hold a death
692     * link on it).
693     */
694    abstract class ForegroundToken implements IBinder.DeathRecipient {
695        int pid;
696        IBinder token;
697    }
698    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
699
700    /**
701     * List of records for processes that someone had tried to start before the
702     * system was ready.  We don't start them at that point, but ensure they
703     * are started by the time booting is complete.
704     */
705    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
706
707    /**
708     * List of persistent applications that are in the process
709     * of being started.
710     */
711    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
712
713    /**
714     * Processes that are being forcibly torn down.
715     */
716    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
717
718    /**
719     * List of running applications, sorted by recent usage.
720     * The first entry in the list is the least recently used.
721     */
722    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
723
724    /**
725     * Where in mLruProcesses that the processes hosting activities start.
726     */
727    int mLruProcessActivityStart = 0;
728
729    /**
730     * Where in mLruProcesses that the processes hosting services start.
731     * This is after (lower index) than mLruProcessesActivityStart.
732     */
733    int mLruProcessServiceStart = 0;
734
735    /**
736     * List of processes that should gc as soon as things are idle.
737     */
738    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
739
740    /**
741     * Processes we want to collect PSS data from.
742     */
743    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
744
745    private boolean mBinderTransactionTrackingEnabled = false;
746
747    /**
748     * Last time we requested PSS data of all processes.
749     */
750    long mLastFullPssTime = SystemClock.uptimeMillis();
751
752    /**
753     * If set, the next time we collect PSS data we should do a full collection
754     * with data from native processes and the kernel.
755     */
756    boolean mFullPssPending = false;
757
758    /**
759     * This is the process holding what we currently consider to be
760     * the "home" activity.
761     */
762    ProcessRecord mHomeProcess;
763
764    /**
765     * This is the process holding the activity the user last visited that
766     * is in a different process from the one they are currently in.
767     */
768    ProcessRecord mPreviousProcess;
769
770    /**
771     * The time at which the previous process was last visible.
772     */
773    long mPreviousProcessVisibleTime;
774
775    /**
776     * Track all uids that have actively running processes.
777     */
778    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
779
780    /**
781     * This is for verifying the UID report flow.
782     */
783    static final boolean VALIDATE_UID_STATES = true;
784    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
785
786    /**
787     * Packages that the user has asked to have run in screen size
788     * compatibility mode instead of filling the screen.
789     */
790    final CompatModePackages mCompatModePackages;
791
792    /**
793     * Set of IntentSenderRecord objects that are currently active.
794     */
795    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
796            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
797
798    /**
799     * Fingerprints (hashCode()) of stack traces that we've
800     * already logged DropBox entries for.  Guarded by itself.  If
801     * something (rogue user app) forces this over
802     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
803     */
804    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
805    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
806
807    /**
808     * Strict Mode background batched logging state.
809     *
810     * The string buffer is guarded by itself, and its lock is also
811     * used to determine if another batched write is already
812     * in-flight.
813     */
814    private final StringBuilder mStrictModeBuffer = new StringBuilder();
815
816    /**
817     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
818     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
819     */
820    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
821
822    /**
823     * Resolver for broadcast intents to registered receivers.
824     * Holds BroadcastFilter (subclass of IntentFilter).
825     */
826    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
827            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
828        @Override
829        protected boolean allowFilterResult(
830                BroadcastFilter filter, List<BroadcastFilter> dest) {
831            IBinder target = filter.receiverList.receiver.asBinder();
832            for (int i = dest.size() - 1; i >= 0; i--) {
833                if (dest.get(i).receiverList.receiver.asBinder() == target) {
834                    return false;
835                }
836            }
837            return true;
838        }
839
840        @Override
841        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
842            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
843                    || userId == filter.owningUserId) {
844                return super.newResult(filter, match, userId);
845            }
846            return null;
847        }
848
849        @Override
850        protected BroadcastFilter[] newArray(int size) {
851            return new BroadcastFilter[size];
852        }
853
854        @Override
855        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
856            return packageName.equals(filter.packageName);
857        }
858    };
859
860    /**
861     * State of all active sticky broadcasts per user.  Keys are the action of the
862     * sticky Intent, values are an ArrayList of all broadcasted intents with
863     * that action (which should usually be one).  The SparseArray is keyed
864     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
865     * for stickies that are sent to all users.
866     */
867    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
868            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
869
870    final ActiveServices mServices;
871
872    final static class Association {
873        final int mSourceUid;
874        final String mSourceProcess;
875        final int mTargetUid;
876        final ComponentName mTargetComponent;
877        final String mTargetProcess;
878
879        int mCount;
880        long mTime;
881
882        int mNesting;
883        long mStartTime;
884
885        Association(int sourceUid, String sourceProcess, int targetUid,
886                ComponentName targetComponent, String targetProcess) {
887            mSourceUid = sourceUid;
888            mSourceProcess = sourceProcess;
889            mTargetUid = targetUid;
890            mTargetComponent = targetComponent;
891            mTargetProcess = targetProcess;
892        }
893    }
894
895    /**
896     * When service association tracking is enabled, this is all of the associations we
897     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
898     * -> association data.
899     */
900    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
901            mAssociations = new SparseArray<>();
902    boolean mTrackingAssociations;
903
904    /**
905     * Backup/restore process management
906     */
907    String mBackupAppName = null;
908    BackupRecord mBackupTarget = null;
909
910    final ProviderMap mProviderMap;
911
912    /**
913     * List of content providers who have clients waiting for them.  The
914     * application is currently being launched and the provider will be
915     * removed from this list once it is published.
916     */
917    final ArrayList<ContentProviderRecord> mLaunchingProviders
918            = new ArrayList<ContentProviderRecord>();
919
920    /**
921     * File storing persisted {@link #mGrantedUriPermissions}.
922     */
923    private final AtomicFile mGrantFile;
924
925    /** XML constants used in {@link #mGrantFile} */
926    private static final String TAG_URI_GRANTS = "uri-grants";
927    private static final String TAG_URI_GRANT = "uri-grant";
928    private static final String ATTR_USER_HANDLE = "userHandle";
929    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
930    private static final String ATTR_TARGET_USER_ID = "targetUserId";
931    private static final String ATTR_SOURCE_PKG = "sourcePkg";
932    private static final String ATTR_TARGET_PKG = "targetPkg";
933    private static final String ATTR_URI = "uri";
934    private static final String ATTR_MODE_FLAGS = "modeFlags";
935    private static final String ATTR_CREATED_TIME = "createdTime";
936    private static final String ATTR_PREFIX = "prefix";
937
938    /**
939     * Global set of specific {@link Uri} permissions that have been granted.
940     * This optimized lookup structure maps from {@link UriPermission#targetUid}
941     * to {@link UriPermission#uri} to {@link UriPermission}.
942     */
943    @GuardedBy("this")
944    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
945            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
946
947    public static class GrantUri {
948        public final int sourceUserId;
949        public final Uri uri;
950        public boolean prefix;
951
952        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
953            this.sourceUserId = sourceUserId;
954            this.uri = uri;
955            this.prefix = prefix;
956        }
957
958        @Override
959        public int hashCode() {
960            int hashCode = 1;
961            hashCode = 31 * hashCode + sourceUserId;
962            hashCode = 31 * hashCode + uri.hashCode();
963            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
964            return hashCode;
965        }
966
967        @Override
968        public boolean equals(Object o) {
969            if (o instanceof GrantUri) {
970                GrantUri other = (GrantUri) o;
971                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
972                        && prefix == other.prefix;
973            }
974            return false;
975        }
976
977        @Override
978        public String toString() {
979            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
980            if (prefix) result += " [prefix]";
981            return result;
982        }
983
984        public String toSafeString() {
985            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
986            if (prefix) result += " [prefix]";
987            return result;
988        }
989
990        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
991            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
992                    ContentProvider.getUriWithoutUserId(uri), false);
993        }
994    }
995
996    CoreSettingsObserver mCoreSettingsObserver;
997
998    /**
999     * Thread-local storage used to carry caller permissions over through
1000     * indirect content-provider access.
1001     */
1002    private class Identity {
1003        public final IBinder token;
1004        public final int pid;
1005        public final int uid;
1006
1007        Identity(IBinder _token, int _pid, int _uid) {
1008            token = _token;
1009            pid = _pid;
1010            uid = _uid;
1011        }
1012    }
1013
1014    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1015
1016    /**
1017     * All information we have collected about the runtime performance of
1018     * any user id that can impact battery performance.
1019     */
1020    final BatteryStatsService mBatteryStatsService;
1021
1022    /**
1023     * Information about component usage
1024     */
1025    UsageStatsManagerInternal mUsageStatsService;
1026
1027    /**
1028     * Access to DeviceIdleController service.
1029     */
1030    DeviceIdleController.LocalService mLocalDeviceIdleController;
1031
1032    /**
1033     * Information about and control over application operations
1034     */
1035    final AppOpsService mAppOpsService;
1036
1037    /**
1038     * Save recent tasks information across reboots.
1039     */
1040    final TaskPersister mTaskPersister;
1041
1042    /**
1043     * Current configuration information.  HistoryRecord objects are given
1044     * a reference to this object to indicate which configuration they are
1045     * currently running in, so this object must be kept immutable.
1046     */
1047    Configuration mConfiguration = new Configuration();
1048
1049    /**
1050     * Current sequencing integer of the configuration, for skipping old
1051     * configurations.
1052     */
1053    int mConfigurationSeq = 0;
1054
1055    boolean mSuppressResizeConfigChanges = false;
1056
1057    /**
1058     * Hardware-reported OpenGLES version.
1059     */
1060    final int GL_ES_VERSION;
1061
1062    /**
1063     * List of initialization arguments to pass to all processes when binding applications to them.
1064     * For example, references to the commonly used services.
1065     */
1066    HashMap<String, IBinder> mAppBindArgs;
1067
1068    /**
1069     * Temporary to avoid allocations.  Protected by main lock.
1070     */
1071    final StringBuilder mStringBuilder = new StringBuilder(256);
1072
1073    /**
1074     * Used to control how we initialize the service.
1075     */
1076    ComponentName mTopComponent;
1077    String mTopAction = Intent.ACTION_MAIN;
1078    String mTopData;
1079    boolean mProcessesReady = false;
1080    boolean mSystemReady = false;
1081    boolean mBooting = false;
1082    boolean mCallFinishBooting = false;
1083    boolean mBootAnimationComplete = false;
1084    boolean mWaitingUpdate = false;
1085    boolean mDidUpdate = false;
1086    boolean mOnBattery = false;
1087    boolean mLaunchWarningShown = false;
1088
1089    Context mContext;
1090
1091    int mFactoryTest;
1092
1093    boolean mCheckedForSetup;
1094
1095    /**
1096     * The time at which we will allow normal application switches again,
1097     * after a call to {@link #stopAppSwitches()}.
1098     */
1099    long mAppSwitchesAllowedTime;
1100
1101    /**
1102     * This is set to true after the first switch after mAppSwitchesAllowedTime
1103     * is set; any switches after that will clear the time.
1104     */
1105    boolean mDidAppSwitch;
1106
1107    /**
1108     * Last time (in realtime) at which we checked for power usage.
1109     */
1110    long mLastPowerCheckRealtime;
1111
1112    /**
1113     * Last time (in uptime) at which we checked for power usage.
1114     */
1115    long mLastPowerCheckUptime;
1116
1117    /**
1118     * Set while we are wanting to sleep, to prevent any
1119     * activities from being started/resumed.
1120     */
1121    private boolean mSleeping = false;
1122
1123    /**
1124     * The process state used for processes that are running the top activities.
1125     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1126     */
1127    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1128
1129    /**
1130     * Set while we are running a voice interaction.  This overrides
1131     * sleeping while it is active.
1132     */
1133    private IVoiceInteractionSession mRunningVoice;
1134
1135    /**
1136     * For some direct access we need to power manager.
1137     */
1138    PowerManagerInternal mLocalPowerManager;
1139
1140    /**
1141     * We want to hold a wake lock while running a voice interaction session, since
1142     * this may happen with the screen off and we need to keep the CPU running to
1143     * be able to continue to interact with the user.
1144     */
1145    PowerManager.WakeLock mVoiceWakeLock;
1146
1147    /**
1148     * State of external calls telling us if the device is awake or asleep.
1149     */
1150    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1151
1152    /**
1153     * A list of tokens that cause the top activity to be put to sleep.
1154     * They are used by components that may hide and block interaction with underlying
1155     * activities.
1156     */
1157    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1158
1159    static final int LOCK_SCREEN_HIDDEN = 0;
1160    static final int LOCK_SCREEN_LEAVING = 1;
1161    static final int LOCK_SCREEN_SHOWN = 2;
1162    /**
1163     * State of external call telling us if the lock screen is shown.
1164     */
1165    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1166
1167    /**
1168     * Set if we are shutting down the system, similar to sleeping.
1169     */
1170    boolean mShuttingDown = false;
1171
1172    /**
1173     * Current sequence id for oom_adj computation traversal.
1174     */
1175    int mAdjSeq = 0;
1176
1177    /**
1178     * Current sequence id for process LRU updating.
1179     */
1180    int mLruSeq = 0;
1181
1182    /**
1183     * Keep track of the non-cached/empty process we last found, to help
1184     * determine how to distribute cached/empty processes next time.
1185     */
1186    int mNumNonCachedProcs = 0;
1187
1188    /**
1189     * Keep track of the number of cached hidden procs, to balance oom adj
1190     * distribution between those and empty procs.
1191     */
1192    int mNumCachedHiddenProcs = 0;
1193
1194    /**
1195     * Keep track of the number of service processes we last found, to
1196     * determine on the next iteration which should be B services.
1197     */
1198    int mNumServiceProcs = 0;
1199    int mNewNumAServiceProcs = 0;
1200    int mNewNumServiceProcs = 0;
1201
1202    /**
1203     * Allow the current computed overall memory level of the system to go down?
1204     * This is set to false when we are killing processes for reasons other than
1205     * memory management, so that the now smaller process list will not be taken as
1206     * an indication that memory is tighter.
1207     */
1208    boolean mAllowLowerMemLevel = false;
1209
1210    /**
1211     * The last computed memory level, for holding when we are in a state that
1212     * processes are going away for other reasons.
1213     */
1214    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1215
1216    /**
1217     * The last total number of process we have, to determine if changes actually look
1218     * like a shrinking number of process due to lower RAM.
1219     */
1220    int mLastNumProcesses;
1221
1222    /**
1223     * The uptime of the last time we performed idle maintenance.
1224     */
1225    long mLastIdleTime = SystemClock.uptimeMillis();
1226
1227    /**
1228     * Total time spent with RAM that has been added in the past since the last idle time.
1229     */
1230    long mLowRamTimeSinceLastIdle = 0;
1231
1232    /**
1233     * If RAM is currently low, when that horrible situation started.
1234     */
1235    long mLowRamStartTime = 0;
1236
1237    /**
1238     * For reporting to battery stats the current top application.
1239     */
1240    private String mCurResumedPackage = null;
1241    private int mCurResumedUid = -1;
1242
1243    /**
1244     * For reporting to battery stats the apps currently running foreground
1245     * service.  The ProcessMap is package/uid tuples; each of these contain
1246     * an array of the currently foreground processes.
1247     */
1248    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1249            = new ProcessMap<ArrayList<ProcessRecord>>();
1250
1251    /**
1252     * This is set if we had to do a delayed dexopt of an app before launching
1253     * it, to increase the ANR timeouts in that case.
1254     */
1255    boolean mDidDexOpt;
1256
1257    /**
1258     * Set if the systemServer made a call to enterSafeMode.
1259     */
1260    boolean mSafeMode;
1261
1262    /**
1263     * If true, we are running under a test environment so will sample PSS from processes
1264     * much more rapidly to try to collect better data when the tests are rapidly
1265     * running through apps.
1266     */
1267    boolean mTestPssMode = false;
1268
1269    String mDebugApp = null;
1270    boolean mWaitForDebugger = false;
1271    boolean mDebugTransient = false;
1272    String mOrigDebugApp = null;
1273    boolean mOrigWaitForDebugger = false;
1274    boolean mAlwaysFinishActivities = false;
1275    boolean mForceResizableActivities;
1276    boolean mSupportsFreeformWindowManagement;
1277    boolean mTakeFullscreenScreenshots;
1278    IActivityController mController = null;
1279    String mProfileApp = null;
1280    ProcessRecord mProfileProc = null;
1281    String mProfileFile;
1282    ParcelFileDescriptor mProfileFd;
1283    int mSamplingInterval = 0;
1284    boolean mAutoStopProfiler = false;
1285    int mProfileType = 0;
1286    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1287    String mMemWatchDumpProcName;
1288    String mMemWatchDumpFile;
1289    int mMemWatchDumpPid;
1290    int mMemWatchDumpUid;
1291    String mTrackAllocationApp = null;
1292
1293    final long[] mTmpLong = new long[1];
1294
1295    static final class ProcessChangeItem {
1296        static final int CHANGE_ACTIVITIES = 1<<0;
1297        static final int CHANGE_PROCESS_STATE = 1<<1;
1298        int changes;
1299        int uid;
1300        int pid;
1301        int processState;
1302        boolean foregroundActivities;
1303    }
1304
1305    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1306    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1307
1308    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1309    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1310
1311    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1312    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1313
1314    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1315    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1316
1317    ArraySet<String> mAppsNotReportingCrashes;
1318
1319    /**
1320     * Runtime CPU use collection thread.  This object's lock is used to
1321     * perform synchronization with the thread (notifying it to run).
1322     */
1323    final Thread mProcessCpuThread;
1324
1325    /**
1326     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1327     * Must acquire this object's lock when accessing it.
1328     * NOTE: this lock will be held while doing long operations (trawling
1329     * through all processes in /proc), so it should never be acquired by
1330     * any critical paths such as when holding the main activity manager lock.
1331     */
1332    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1333            MONITOR_THREAD_CPU_USAGE);
1334    final AtomicLong mLastCpuTime = new AtomicLong(0);
1335    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1336
1337    long mLastWriteTime = 0;
1338
1339    /**
1340     * Used to retain an update lock when the foreground activity is in
1341     * immersive mode.
1342     */
1343    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1344
1345    /**
1346     * Set to true after the system has finished booting.
1347     */
1348    boolean mBooted = false;
1349
1350    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1351    int mProcessLimitOverride = -1;
1352
1353    WindowManagerService mWindowManager;
1354
1355    final ActivityThread mSystemThread;
1356
1357    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1358        final ProcessRecord mApp;
1359        final int mPid;
1360        final IApplicationThread mAppThread;
1361
1362        AppDeathRecipient(ProcessRecord app, int pid,
1363                IApplicationThread thread) {
1364            if (DEBUG_ALL) Slog.v(
1365                TAG, "New death recipient " + this
1366                + " for thread " + thread.asBinder());
1367            mApp = app;
1368            mPid = pid;
1369            mAppThread = thread;
1370        }
1371
1372        @Override
1373        public void binderDied() {
1374            if (DEBUG_ALL) Slog.v(
1375                TAG, "Death received in " + this
1376                + " for thread " + mAppThread.asBinder());
1377            synchronized(ActivityManagerService.this) {
1378                appDiedLocked(mApp, mPid, mAppThread, true);
1379            }
1380        }
1381    }
1382
1383    static final int SHOW_ERROR_UI_MSG = 1;
1384    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1385    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1386    static final int UPDATE_CONFIGURATION_MSG = 4;
1387    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1388    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1389    static final int SERVICE_TIMEOUT_MSG = 12;
1390    static final int UPDATE_TIME_ZONE = 13;
1391    static final int SHOW_UID_ERROR_UI_MSG = 14;
1392    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1393    static final int PROC_START_TIMEOUT_MSG = 20;
1394    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1395    static final int KILL_APPLICATION_MSG = 22;
1396    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1397    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1398    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1399    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1400    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1401    static final int CLEAR_DNS_CACHE_MSG = 28;
1402    static final int UPDATE_HTTP_PROXY_MSG = 29;
1403    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1404    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1405    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1406    static final int REPORT_MEM_USAGE_MSG = 33;
1407    static final int REPORT_USER_SWITCH_MSG = 34;
1408    static final int CONTINUE_USER_SWITCH_MSG = 35;
1409    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1410    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1411    static final int PERSIST_URI_GRANTS_MSG = 38;
1412    static final int REQUEST_ALL_PSS_MSG = 39;
1413    static final int START_PROFILES_MSG = 40;
1414    static final int UPDATE_TIME = 41;
1415    static final int SYSTEM_USER_START_MSG = 42;
1416    static final int SYSTEM_USER_CURRENT_MSG = 43;
1417    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1418    static final int FINISH_BOOTING_MSG = 45;
1419    static final int START_USER_SWITCH_UI_MSG = 46;
1420    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1421    static final int DISMISS_DIALOG_UI_MSG = 48;
1422    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1423    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1424    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1425    static final int DELETE_DUMPHEAP_MSG = 52;
1426    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1427    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1428    static final int REPORT_TIME_TRACKER_MSG = 55;
1429    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1430    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1431    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1432    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1433    static final int IDLE_UIDS_MSG = 60;
1434    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1435
1436    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1437    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1438    static final int FIRST_COMPAT_MODE_MSG = 300;
1439    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1440
1441    CompatModeDialog mCompatModeDialog;
1442    long mLastMemUsageReportTime = 0;
1443
1444    /**
1445     * Flag whether the current user is a "monkey", i.e. whether
1446     * the UI is driven by a UI automation tool.
1447     */
1448    private boolean mUserIsMonkey;
1449
1450    /** Flag whether the device has a Recents UI */
1451    boolean mHasRecents;
1452
1453    /** The dimensions of the thumbnails in the Recents UI. */
1454    int mThumbnailWidth;
1455    int mThumbnailHeight;
1456
1457    final ServiceThread mHandlerThread;
1458    final MainHandler mHandler;
1459    final UiHandler mUiHandler;
1460
1461    PackageManagerInternal mPackageManagerInt;
1462
1463    final class UiHandler extends Handler {
1464        public UiHandler() {
1465            super(com.android.server.UiThread.get().getLooper(), null, true);
1466        }
1467
1468        @Override
1469        public void handleMessage(Message msg) {
1470            switch (msg.what) {
1471            case SHOW_ERROR_UI_MSG: {
1472                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1473                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1474                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1475                synchronized (ActivityManagerService.this) {
1476                    ProcessRecord proc = (ProcessRecord)data.get("app");
1477                    AppErrorResult res = (AppErrorResult) data.get("result");
1478                    if (proc != null && proc.crashDialog != null) {
1479                        Slog.e(TAG, "App already has crash dialog: " + proc);
1480                        if (res != null) {
1481                            res.set(0);
1482                        }
1483                        return;
1484                    }
1485                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1486                            >= Process.FIRST_APPLICATION_UID
1487                            && proc.pid != MY_PID);
1488                    for (int userId : mUserController.getCurrentProfileIdsLocked()) {
1489                        isBackground &= (proc.userId != userId);
1490                    }
1491                    if (isBackground && !showBackground) {
1492                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1493                        if (res != null) {
1494                            res.set(0);
1495                        }
1496                        return;
1497                    }
1498                    final boolean crashSilenced = mAppsNotReportingCrashes != null &&
1499                            mAppsNotReportingCrashes.contains(proc.info.packageName);
1500                    if (mShowDialogs && !mSleeping && !mShuttingDown && !crashSilenced) {
1501                        Dialog d = new AppErrorDialog(mContext,
1502                                ActivityManagerService.this, res, proc);
1503                        d.show();
1504                        proc.crashDialog = d;
1505                    } else {
1506                        // The device is asleep, so just pretend that the user
1507                        // saw a crash dialog and hit "force quit".
1508                        if (res != null) {
1509                            res.set(0);
1510                        }
1511                    }
1512                }
1513
1514                ensureBootCompleted();
1515            } break;
1516            case SHOW_NOT_RESPONDING_UI_MSG: {
1517                synchronized (ActivityManagerService.this) {
1518                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1519                    ProcessRecord proc = (ProcessRecord)data.get("app");
1520                    if (proc != null && proc.anrDialog != null) {
1521                        Slog.e(TAG, "App already has anr dialog: " + proc);
1522                        return;
1523                    }
1524
1525                    Intent intent = new Intent("android.intent.action.ANR");
1526                    if (!mProcessesReady) {
1527                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1528                                | Intent.FLAG_RECEIVER_FOREGROUND);
1529                    }
1530                    broadcastIntentLocked(null, null, intent,
1531                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1532                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1533
1534                    if (mShowDialogs) {
1535                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1536                                mContext, proc, (ActivityRecord)data.get("activity"),
1537                                msg.arg1 != 0);
1538                        d.show();
1539                        proc.anrDialog = d;
1540                    } else {
1541                        // Just kill the app if there is no dialog to be shown.
1542                        killAppAtUsersRequest(proc, null);
1543                    }
1544                }
1545
1546                ensureBootCompleted();
1547            } break;
1548            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1549                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1550                synchronized (ActivityManagerService.this) {
1551                    ProcessRecord proc = (ProcessRecord) data.get("app");
1552                    if (proc == null) {
1553                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1554                        break;
1555                    }
1556                    if (proc.crashDialog != null) {
1557                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1558                        return;
1559                    }
1560                    AppErrorResult res = (AppErrorResult) data.get("result");
1561                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1562                        Dialog d = new StrictModeViolationDialog(mContext,
1563                                ActivityManagerService.this, res, proc);
1564                        d.show();
1565                        proc.crashDialog = d;
1566                    } else {
1567                        // The device is asleep, so just pretend that the user
1568                        // saw a crash dialog and hit "force quit".
1569                        res.set(0);
1570                    }
1571                }
1572                ensureBootCompleted();
1573            } break;
1574            case SHOW_FACTORY_ERROR_UI_MSG: {
1575                Dialog d = new FactoryErrorDialog(
1576                    mContext, msg.getData().getCharSequence("msg"));
1577                d.show();
1578                ensureBootCompleted();
1579            } break;
1580            case WAIT_FOR_DEBUGGER_UI_MSG: {
1581                synchronized (ActivityManagerService.this) {
1582                    ProcessRecord app = (ProcessRecord)msg.obj;
1583                    if (msg.arg1 != 0) {
1584                        if (!app.waitedForDebugger) {
1585                            Dialog d = new AppWaitingForDebuggerDialog(
1586                                    ActivityManagerService.this,
1587                                    mContext, app);
1588                            app.waitDialog = d;
1589                            app.waitedForDebugger = true;
1590                            d.show();
1591                        }
1592                    } else {
1593                        if (app.waitDialog != null) {
1594                            app.waitDialog.dismiss();
1595                            app.waitDialog = null;
1596                        }
1597                    }
1598                }
1599            } break;
1600            case SHOW_UID_ERROR_UI_MSG: {
1601                if (mShowDialogs) {
1602                    AlertDialog d = new BaseErrorDialog(mContext);
1603                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1604                    d.setCancelable(false);
1605                    d.setTitle(mContext.getText(R.string.android_system_label));
1606                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1607                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1608                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1609                    d.show();
1610                }
1611            } break;
1612            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1613                if (mShowDialogs) {
1614                    AlertDialog d = new BaseErrorDialog(mContext);
1615                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1616                    d.setCancelable(false);
1617                    d.setTitle(mContext.getText(R.string.android_system_label));
1618                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1619                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1620                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1621                    d.show();
1622                }
1623            } break;
1624            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1625                synchronized (ActivityManagerService.this) {
1626                    ActivityRecord ar = (ActivityRecord) msg.obj;
1627                    if (mCompatModeDialog != null) {
1628                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1629                                ar.info.applicationInfo.packageName)) {
1630                            return;
1631                        }
1632                        mCompatModeDialog.dismiss();
1633                        mCompatModeDialog = null;
1634                    }
1635                    if (ar != null && false) {
1636                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1637                                ar.packageName)) {
1638                            int mode = mCompatModePackages.computeCompatModeLocked(
1639                                    ar.info.applicationInfo);
1640                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1641                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1642                                mCompatModeDialog = new CompatModeDialog(
1643                                        ActivityManagerService.this, mContext,
1644                                        ar.info.applicationInfo);
1645                                mCompatModeDialog.show();
1646                            }
1647                        }
1648                    }
1649                }
1650                break;
1651            }
1652            case START_USER_SWITCH_UI_MSG: {
1653                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1654                break;
1655            }
1656            case DISMISS_DIALOG_UI_MSG: {
1657                final Dialog d = (Dialog) msg.obj;
1658                d.dismiss();
1659                break;
1660            }
1661            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1662                dispatchProcessesChanged();
1663                break;
1664            }
1665            case DISPATCH_PROCESS_DIED_UI_MSG: {
1666                final int pid = msg.arg1;
1667                final int uid = msg.arg2;
1668                dispatchProcessDied(pid, uid);
1669                break;
1670            }
1671            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1672                dispatchUidsChanged();
1673            } break;
1674            }
1675        }
1676    }
1677
1678    final class MainHandler extends Handler {
1679        public MainHandler(Looper looper) {
1680            super(looper, null, true);
1681        }
1682
1683        @Override
1684        public void handleMessage(Message msg) {
1685            switch (msg.what) {
1686            case UPDATE_CONFIGURATION_MSG: {
1687                final ContentResolver resolver = mContext.getContentResolver();
1688                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1689                        msg.arg1);
1690            } break;
1691            case GC_BACKGROUND_PROCESSES_MSG: {
1692                synchronized (ActivityManagerService.this) {
1693                    performAppGcsIfAppropriateLocked();
1694                }
1695            } break;
1696            case SERVICE_TIMEOUT_MSG: {
1697                if (mDidDexOpt) {
1698                    mDidDexOpt = false;
1699                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1700                    nmsg.obj = msg.obj;
1701                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1702                    return;
1703                }
1704                mServices.serviceTimeout((ProcessRecord)msg.obj);
1705            } break;
1706            case UPDATE_TIME_ZONE: {
1707                synchronized (ActivityManagerService.this) {
1708                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1709                        ProcessRecord r = mLruProcesses.get(i);
1710                        if (r.thread != null) {
1711                            try {
1712                                r.thread.updateTimeZone();
1713                            } catch (RemoteException ex) {
1714                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1715                            }
1716                        }
1717                    }
1718                }
1719            } break;
1720            case CLEAR_DNS_CACHE_MSG: {
1721                synchronized (ActivityManagerService.this) {
1722                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1723                        ProcessRecord r = mLruProcesses.get(i);
1724                        if (r.thread != null) {
1725                            try {
1726                                r.thread.clearDnsCache();
1727                            } catch (RemoteException ex) {
1728                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1729                            }
1730                        }
1731                    }
1732                }
1733            } break;
1734            case UPDATE_HTTP_PROXY_MSG: {
1735                ProxyInfo proxy = (ProxyInfo)msg.obj;
1736                String host = "";
1737                String port = "";
1738                String exclList = "";
1739                Uri pacFileUrl = Uri.EMPTY;
1740                if (proxy != null) {
1741                    host = proxy.getHost();
1742                    port = Integer.toString(proxy.getPort());
1743                    exclList = proxy.getExclusionListAsString();
1744                    pacFileUrl = proxy.getPacFileUrl();
1745                }
1746                synchronized (ActivityManagerService.this) {
1747                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1748                        ProcessRecord r = mLruProcesses.get(i);
1749                        if (r.thread != null) {
1750                            try {
1751                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1752                            } catch (RemoteException ex) {
1753                                Slog.w(TAG, "Failed to update http proxy for: " +
1754                                        r.info.processName);
1755                            }
1756                        }
1757                    }
1758                }
1759            } break;
1760            case PROC_START_TIMEOUT_MSG: {
1761                if (mDidDexOpt) {
1762                    mDidDexOpt = false;
1763                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1764                    nmsg.obj = msg.obj;
1765                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1766                    return;
1767                }
1768                ProcessRecord app = (ProcessRecord)msg.obj;
1769                synchronized (ActivityManagerService.this) {
1770                    processStartTimedOutLocked(app);
1771                }
1772            } break;
1773            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1774                ProcessRecord app = (ProcessRecord)msg.obj;
1775                synchronized (ActivityManagerService.this) {
1776                    processContentProviderPublishTimedOutLocked(app);
1777                }
1778            } break;
1779            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1780                synchronized (ActivityManagerService.this) {
1781                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1782                }
1783            } break;
1784            case KILL_APPLICATION_MSG: {
1785                synchronized (ActivityManagerService.this) {
1786                    int appid = msg.arg1;
1787                    boolean restart = (msg.arg2 == 1);
1788                    Bundle bundle = (Bundle)msg.obj;
1789                    String pkg = bundle.getString("pkg");
1790                    String reason = bundle.getString("reason");
1791                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1792                            false, UserHandle.USER_ALL, reason);
1793                }
1794            } break;
1795            case FINALIZE_PENDING_INTENT_MSG: {
1796                ((PendingIntentRecord)msg.obj).completeFinalize();
1797            } break;
1798            case POST_HEAVY_NOTIFICATION_MSG: {
1799                INotificationManager inm = NotificationManager.getService();
1800                if (inm == null) {
1801                    return;
1802                }
1803
1804                ActivityRecord root = (ActivityRecord)msg.obj;
1805                ProcessRecord process = root.app;
1806                if (process == null) {
1807                    return;
1808                }
1809
1810                try {
1811                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1812                    String text = mContext.getString(R.string.heavy_weight_notification,
1813                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1814                    Notification notification = new Notification.Builder(context)
1815                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1816                            .setWhen(0)
1817                            .setOngoing(true)
1818                            .setTicker(text)
1819                            .setColor(mContext.getColor(
1820                                    com.android.internal.R.color.system_notification_accent_color))
1821                            .setContentTitle(text)
1822                            .setContentText(
1823                                    mContext.getText(R.string.heavy_weight_notification_detail))
1824                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1825                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1826                                    new UserHandle(root.userId)))
1827                            .build();
1828                    try {
1829                        int[] outId = new int[1];
1830                        inm.enqueueNotificationWithTag("android", "android", null,
1831                                R.string.heavy_weight_notification,
1832                                notification, outId, root.userId);
1833                    } catch (RuntimeException e) {
1834                        Slog.w(ActivityManagerService.TAG,
1835                                "Error showing notification for heavy-weight app", e);
1836                    } catch (RemoteException e) {
1837                    }
1838                } catch (NameNotFoundException e) {
1839                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1840                }
1841            } break;
1842            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1843                INotificationManager inm = NotificationManager.getService();
1844                if (inm == null) {
1845                    return;
1846                }
1847                try {
1848                    inm.cancelNotificationWithTag("android", null,
1849                            R.string.heavy_weight_notification,  msg.arg1);
1850                } catch (RuntimeException e) {
1851                    Slog.w(ActivityManagerService.TAG,
1852                            "Error canceling notification for service", e);
1853                } catch (RemoteException e) {
1854                }
1855            } break;
1856            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1857                synchronized (ActivityManagerService.this) {
1858                    checkExcessivePowerUsageLocked(true);
1859                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1860                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1861                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1862                }
1863            } break;
1864            case REPORT_MEM_USAGE_MSG: {
1865                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1866                Thread thread = new Thread() {
1867                    @Override public void run() {
1868                        reportMemUsage(memInfos);
1869                    }
1870                };
1871                thread.start();
1872                break;
1873            }
1874            case REPORT_USER_SWITCH_MSG: {
1875                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1876                break;
1877            }
1878            case CONTINUE_USER_SWITCH_MSG: {
1879                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1880                break;
1881            }
1882            case USER_SWITCH_TIMEOUT_MSG: {
1883                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1884                break;
1885            }
1886            case IMMERSIVE_MODE_LOCK_MSG: {
1887                final boolean nextState = (msg.arg1 != 0);
1888                if (mUpdateLock.isHeld() != nextState) {
1889                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1890                            "Applying new update lock state '" + nextState
1891                            + "' for " + (ActivityRecord)msg.obj);
1892                    if (nextState) {
1893                        mUpdateLock.acquire();
1894                    } else {
1895                        mUpdateLock.release();
1896                    }
1897                }
1898                break;
1899            }
1900            case PERSIST_URI_GRANTS_MSG: {
1901                writeGrantedUriPermissions();
1902                break;
1903            }
1904            case REQUEST_ALL_PSS_MSG: {
1905                synchronized (ActivityManagerService.this) {
1906                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1907                }
1908                break;
1909            }
1910            case START_PROFILES_MSG: {
1911                synchronized (ActivityManagerService.this) {
1912                    mUserController.startProfilesLocked();
1913                }
1914                break;
1915            }
1916            case UPDATE_TIME: {
1917                synchronized (ActivityManagerService.this) {
1918                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1919                        ProcessRecord r = mLruProcesses.get(i);
1920                        if (r.thread != null) {
1921                            try {
1922                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1923                            } catch (RemoteException ex) {
1924                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1925                            }
1926                        }
1927                    }
1928                }
1929                break;
1930            }
1931            case SYSTEM_USER_START_MSG: {
1932                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1933                        Integer.toString(msg.arg1), msg.arg1);
1934                mSystemServiceManager.startUser(msg.arg1);
1935                break;
1936            }
1937            case SYSTEM_USER_UNLOCK_MSG: {
1938                mSystemServiceManager.unlockUser(msg.arg1);
1939                break;
1940            }
1941            case SYSTEM_USER_CURRENT_MSG: {
1942                mBatteryStatsService.noteEvent(
1943                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1944                        Integer.toString(msg.arg2), msg.arg2);
1945                mBatteryStatsService.noteEvent(
1946                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1947                        Integer.toString(msg.arg1), msg.arg1);
1948                mSystemServiceManager.switchUser(msg.arg1);
1949                break;
1950            }
1951            case ENTER_ANIMATION_COMPLETE_MSG: {
1952                synchronized (ActivityManagerService.this) {
1953                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1954                    if (r != null && r.app != null && r.app.thread != null) {
1955                        try {
1956                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1957                        } catch (RemoteException e) {
1958                        }
1959                    }
1960                }
1961                break;
1962            }
1963            case FINISH_BOOTING_MSG: {
1964                if (msg.arg1 != 0) {
1965                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1966                    finishBooting();
1967                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1968                }
1969                if (msg.arg2 != 0) {
1970                    enableScreenAfterBoot();
1971                }
1972                break;
1973            }
1974            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1975                try {
1976                    Locale l = (Locale) msg.obj;
1977                    IBinder service = ServiceManager.getService("mount");
1978                    IMountService mountService = IMountService.Stub.asInterface(service);
1979                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1980                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1981                } catch (RemoteException e) {
1982                    Log.e(TAG, "Error storing locale for decryption UI", e);
1983                }
1984                break;
1985            }
1986            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1987                synchronized (ActivityManagerService.this) {
1988                    int i = mTaskStackListeners.beginBroadcast();
1989                    while (i > 0) {
1990                        i--;
1991                        try {
1992                            // Make a one-way callback to the listener
1993                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1994                        } catch (RemoteException e){
1995                            // Handled by the RemoteCallbackList
1996                        }
1997                    }
1998                    mTaskStackListeners.finishBroadcast();
1999                }
2000                break;
2001            }
2002            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2003                final int uid = msg.arg1;
2004                final byte[] firstPacket = (byte[]) msg.obj;
2005
2006                synchronized (mPidsSelfLocked) {
2007                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2008                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2009                        if (p.uid == uid) {
2010                            try {
2011                                p.thread.notifyCleartextNetwork(firstPacket);
2012                            } catch (RemoteException ignored) {
2013                            }
2014                        }
2015                    }
2016                }
2017                break;
2018            }
2019            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2020                final String procName;
2021                final int uid;
2022                final long memLimit;
2023                final String reportPackage;
2024                synchronized (ActivityManagerService.this) {
2025                    procName = mMemWatchDumpProcName;
2026                    uid = mMemWatchDumpUid;
2027                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2028                    if (val == null) {
2029                        val = mMemWatchProcesses.get(procName, 0);
2030                    }
2031                    if (val != null) {
2032                        memLimit = val.first;
2033                        reportPackage = val.second;
2034                    } else {
2035                        memLimit = 0;
2036                        reportPackage = null;
2037                    }
2038                }
2039                if (procName == null) {
2040                    return;
2041                }
2042
2043                if (DEBUG_PSS) Slog.d(TAG_PSS,
2044                        "Showing dump heap notification from " + procName + "/" + uid);
2045
2046                INotificationManager inm = NotificationManager.getService();
2047                if (inm == null) {
2048                    return;
2049                }
2050
2051                String text = mContext.getString(R.string.dump_heap_notification, procName);
2052
2053
2054                Intent deleteIntent = new Intent();
2055                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2056                Intent intent = new Intent();
2057                intent.setClassName("android", DumpHeapActivity.class.getName());
2058                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2059                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2060                if (reportPackage != null) {
2061                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2062                }
2063                int userId = UserHandle.getUserId(uid);
2064                Notification notification = new Notification.Builder(mContext)
2065                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2066                        .setWhen(0)
2067                        .setOngoing(true)
2068                        .setAutoCancel(true)
2069                        .setTicker(text)
2070                        .setColor(mContext.getColor(
2071                                com.android.internal.R.color.system_notification_accent_color))
2072                        .setContentTitle(text)
2073                        .setContentText(
2074                                mContext.getText(R.string.dump_heap_notification_detail))
2075                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2076                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2077                                new UserHandle(userId)))
2078                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2079                                deleteIntent, 0, UserHandle.SYSTEM))
2080                        .build();
2081
2082                try {
2083                    int[] outId = new int[1];
2084                    inm.enqueueNotificationWithTag("android", "android", null,
2085                            R.string.dump_heap_notification,
2086                            notification, outId, userId);
2087                } catch (RuntimeException e) {
2088                    Slog.w(ActivityManagerService.TAG,
2089                            "Error showing notification for dump heap", e);
2090                } catch (RemoteException e) {
2091                }
2092            } break;
2093            case DELETE_DUMPHEAP_MSG: {
2094                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2095                        DumpHeapActivity.JAVA_URI,
2096                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2097                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2098                        UserHandle.myUserId());
2099                synchronized (ActivityManagerService.this) {
2100                    mMemWatchDumpFile = null;
2101                    mMemWatchDumpProcName = null;
2102                    mMemWatchDumpPid = -1;
2103                    mMemWatchDumpUid = -1;
2104                }
2105            } break;
2106            case FOREGROUND_PROFILE_CHANGED_MSG: {
2107                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2108            } break;
2109            case REPORT_TIME_TRACKER_MSG: {
2110                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2111                tracker.deliverResult(mContext);
2112            } break;
2113            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2114                mUserController.dispatchUserSwitchComplete(msg.arg1);
2115            } break;
2116            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2117                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2118                try {
2119                    connection.shutdown();
2120                } catch (RemoteException e) {
2121                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2122                }
2123                // Only a UiAutomation can set this flag and now that
2124                // it is finished we make sure it is reset to its default.
2125                mUserIsMonkey = false;
2126            } break;
2127            case APP_BOOST_DEACTIVATE_MSG: {
2128                synchronized(ActivityManagerService.this) {
2129                    if (mIsBoosted) {
2130                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2131                            nativeMigrateFromBoost();
2132                            mIsBoosted = false;
2133                            mBoostStartTime = 0;
2134                        } else {
2135                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2136                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2137                        }
2138                    }
2139                }
2140            } break;
2141            case IDLE_UIDS_MSG: {
2142                idleUids();
2143            } break;
2144            }
2145        }
2146    };
2147
2148    static final int COLLECT_PSS_BG_MSG = 1;
2149
2150    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2151        @Override
2152        public void handleMessage(Message msg) {
2153            switch (msg.what) {
2154            case COLLECT_PSS_BG_MSG: {
2155                long start = SystemClock.uptimeMillis();
2156                MemInfoReader memInfo = null;
2157                synchronized (ActivityManagerService.this) {
2158                    if (mFullPssPending) {
2159                        mFullPssPending = false;
2160                        memInfo = new MemInfoReader();
2161                    }
2162                }
2163                if (memInfo != null) {
2164                    updateCpuStatsNow();
2165                    long nativeTotalPss = 0;
2166                    synchronized (mProcessCpuTracker) {
2167                        final int N = mProcessCpuTracker.countStats();
2168                        for (int j=0; j<N; j++) {
2169                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2170                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2171                                // This is definitely an application process; skip it.
2172                                continue;
2173                            }
2174                            synchronized (mPidsSelfLocked) {
2175                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2176                                    // This is one of our own processes; skip it.
2177                                    continue;
2178                                }
2179                            }
2180                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2181                        }
2182                    }
2183                    memInfo.readMemInfo();
2184                    synchronized (ActivityManagerService.this) {
2185                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2186                                + (SystemClock.uptimeMillis()-start) + "ms");
2187                        final long cachedKb = memInfo.getCachedSizeKb();
2188                        final long freeKb = memInfo.getFreeSizeKb();
2189                        final long zramKb = memInfo.getZramTotalSizeKb();
2190                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2191                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2192                                kernelKb*1024, nativeTotalPss*1024);
2193                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2194                                nativeTotalPss);
2195                    }
2196                }
2197
2198                int num = 0;
2199                long[] tmp = new long[1];
2200                do {
2201                    ProcessRecord proc;
2202                    int procState;
2203                    int pid;
2204                    long lastPssTime;
2205                    synchronized (ActivityManagerService.this) {
2206                        if (mPendingPssProcesses.size() <= 0) {
2207                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2208                                    "Collected PSS of " + num + " processes in "
2209                                    + (SystemClock.uptimeMillis() - start) + "ms");
2210                            mPendingPssProcesses.clear();
2211                            return;
2212                        }
2213                        proc = mPendingPssProcesses.remove(0);
2214                        procState = proc.pssProcState;
2215                        lastPssTime = proc.lastPssTime;
2216                        if (proc.thread != null && procState == proc.setProcState
2217                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2218                                        < SystemClock.uptimeMillis()) {
2219                            pid = proc.pid;
2220                        } else {
2221                            proc = null;
2222                            pid = 0;
2223                        }
2224                    }
2225                    if (proc != null) {
2226                        long pss = Debug.getPss(pid, tmp, null);
2227                        synchronized (ActivityManagerService.this) {
2228                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2229                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2230                                num++;
2231                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2232                                        SystemClock.uptimeMillis());
2233                            }
2234                        }
2235                    }
2236                } while (true);
2237            }
2238            }
2239        }
2240    };
2241
2242    public void setSystemProcess() {
2243        try {
2244            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2245            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2246            ServiceManager.addService("meminfo", new MemBinder(this));
2247            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2248            ServiceManager.addService("dbinfo", new DbBinder(this));
2249            if (MONITOR_CPU_USAGE) {
2250                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2251            }
2252            ServiceManager.addService("permission", new PermissionController(this));
2253            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2254
2255            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2256                    "android", STOCK_PM_FLAGS);
2257            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2258
2259            synchronized (this) {
2260                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2261                app.persistent = true;
2262                app.pid = MY_PID;
2263                app.maxAdj = ProcessList.SYSTEM_ADJ;
2264                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2265                synchronized (mPidsSelfLocked) {
2266                    mPidsSelfLocked.put(app.pid, app);
2267                }
2268                updateLruProcessLocked(app, false, null);
2269                updateOomAdjLocked();
2270            }
2271        } catch (PackageManager.NameNotFoundException e) {
2272            throw new RuntimeException(
2273                    "Unable to find android system package", e);
2274        }
2275    }
2276
2277    public void setWindowManager(WindowManagerService wm) {
2278        mWindowManager = wm;
2279        mStackSupervisor.setWindowManager(wm);
2280    }
2281
2282    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2283        mUsageStatsService = usageStatsManager;
2284    }
2285
2286    public void startObservingNativeCrashes() {
2287        final NativeCrashListener ncl = new NativeCrashListener(this);
2288        ncl.start();
2289    }
2290
2291    public IAppOpsService getAppOpsService() {
2292        return mAppOpsService;
2293    }
2294
2295    static class MemBinder extends Binder {
2296        ActivityManagerService mActivityManagerService;
2297        MemBinder(ActivityManagerService activityManagerService) {
2298            mActivityManagerService = activityManagerService;
2299        }
2300
2301        @Override
2302        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2303            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2304                    != PackageManager.PERMISSION_GRANTED) {
2305                pw.println("Permission Denial: can't dump meminfo from from pid="
2306                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2307                        + " without permission " + android.Manifest.permission.DUMP);
2308                return;
2309            }
2310
2311            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2312        }
2313    }
2314
2315    static class GraphicsBinder extends Binder {
2316        ActivityManagerService mActivityManagerService;
2317        GraphicsBinder(ActivityManagerService activityManagerService) {
2318            mActivityManagerService = activityManagerService;
2319        }
2320
2321        @Override
2322        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2323            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2324                    != PackageManager.PERMISSION_GRANTED) {
2325                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2326                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2327                        + " without permission " + android.Manifest.permission.DUMP);
2328                return;
2329            }
2330
2331            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2332        }
2333    }
2334
2335    static class DbBinder extends Binder {
2336        ActivityManagerService mActivityManagerService;
2337        DbBinder(ActivityManagerService activityManagerService) {
2338            mActivityManagerService = activityManagerService;
2339        }
2340
2341        @Override
2342        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2343            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2344                    != PackageManager.PERMISSION_GRANTED) {
2345                pw.println("Permission Denial: can't dump dbinfo from from pid="
2346                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2347                        + " without permission " + android.Manifest.permission.DUMP);
2348                return;
2349            }
2350
2351            mActivityManagerService.dumpDbInfo(fd, pw, args);
2352        }
2353    }
2354
2355    static class CpuBinder extends Binder {
2356        ActivityManagerService mActivityManagerService;
2357        CpuBinder(ActivityManagerService activityManagerService) {
2358            mActivityManagerService = activityManagerService;
2359        }
2360
2361        @Override
2362        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2363            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2364                    != PackageManager.PERMISSION_GRANTED) {
2365                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2366                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2367                        + " without permission " + android.Manifest.permission.DUMP);
2368                return;
2369            }
2370
2371            synchronized (mActivityManagerService.mProcessCpuTracker) {
2372                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2373                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2374                        SystemClock.uptimeMillis()));
2375            }
2376        }
2377    }
2378
2379    public static final class Lifecycle extends SystemService {
2380        private final ActivityManagerService mService;
2381
2382        public Lifecycle(Context context) {
2383            super(context);
2384            mService = new ActivityManagerService(context);
2385        }
2386
2387        @Override
2388        public void onStart() {
2389            mService.start();
2390        }
2391
2392        public ActivityManagerService getService() {
2393            return mService;
2394        }
2395    }
2396
2397    // Note: This method is invoked on the main thread but may need to attach various
2398    // handlers to other threads.  So take care to be explicit about the looper.
2399    public ActivityManagerService(Context systemContext) {
2400        mContext = systemContext;
2401        mFactoryTest = FactoryTest.getMode();
2402        mSystemThread = ActivityThread.currentActivityThread();
2403
2404        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2405
2406        mHandlerThread = new ServiceThread(TAG,
2407                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2408        mHandlerThread.start();
2409        mHandler = new MainHandler(mHandlerThread.getLooper());
2410        mUiHandler = new UiHandler();
2411
2412        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2413                "foreground", BROADCAST_FG_TIMEOUT, false);
2414        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2415                "background", BROADCAST_BG_TIMEOUT, true);
2416        mBroadcastQueues[0] = mFgBroadcastQueue;
2417        mBroadcastQueues[1] = mBgBroadcastQueue;
2418
2419        mServices = new ActiveServices(this);
2420        mProviderMap = new ProviderMap(this);
2421
2422        // TODO: Move creation of battery stats service outside of activity manager service.
2423        File dataDir = Environment.getDataDirectory();
2424        File systemDir = new File(dataDir, "system");
2425        systemDir.mkdirs();
2426        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2427        mBatteryStatsService.getActiveStatistics().readLocked();
2428        mBatteryStatsService.scheduleWriteToDisk();
2429        mOnBattery = DEBUG_POWER ? true
2430                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2431        mBatteryStatsService.getActiveStatistics().setCallback(this);
2432
2433        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2434
2435        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2436        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2437                new IAppOpsCallback.Stub() {
2438                    @Override public void opChanged(int op, int uid, String packageName) {
2439                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2440                            if (mAppOpsService.checkOperation(op, uid, packageName)
2441                                    != AppOpsManager.MODE_ALLOWED) {
2442                                runInBackgroundDisabled(uid);
2443                            }
2444                        }
2445                    }
2446                });
2447
2448        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2449
2450        mUserController = new UserController(this);
2451
2452        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2453            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2454
2455        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2456
2457        mConfiguration.setToDefaults();
2458        mConfiguration.setLocales(LocaleList.getDefault());
2459
2460        mConfigurationSeq = mConfiguration.seq = 1;
2461        mProcessCpuTracker.init();
2462
2463        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2464        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2465        mRecentTasks = new RecentTasks(this);
2466        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2467        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2468
2469        mProcessCpuThread = new Thread("CpuTracker") {
2470            @Override
2471            public void run() {
2472                while (true) {
2473                    try {
2474                        try {
2475                            synchronized(this) {
2476                                final long now = SystemClock.uptimeMillis();
2477                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2478                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2479                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2480                                //        + ", write delay=" + nextWriteDelay);
2481                                if (nextWriteDelay < nextCpuDelay) {
2482                                    nextCpuDelay = nextWriteDelay;
2483                                }
2484                                if (nextCpuDelay > 0) {
2485                                    mProcessCpuMutexFree.set(true);
2486                                    this.wait(nextCpuDelay);
2487                                }
2488                            }
2489                        } catch (InterruptedException e) {
2490                        }
2491                        updateCpuStatsNow();
2492                    } catch (Exception e) {
2493                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2494                    }
2495                }
2496            }
2497        };
2498
2499        Watchdog.getInstance().addMonitor(this);
2500        Watchdog.getInstance().addThread(mHandler);
2501    }
2502
2503    public void setSystemServiceManager(SystemServiceManager mgr) {
2504        mSystemServiceManager = mgr;
2505    }
2506
2507    public void setInstaller(Installer installer) {
2508        mInstaller = installer;
2509    }
2510
2511    private void start() {
2512        Process.removeAllProcessGroups();
2513        mProcessCpuThread.start();
2514
2515        mBatteryStatsService.publish(mContext);
2516        mAppOpsService.publish(mContext);
2517        Slog.d("AppOps", "AppOpsService published");
2518        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2519    }
2520
2521    public void initPowerManagement() {
2522        mStackSupervisor.initPowerManagement();
2523        mBatteryStatsService.initPowerManagement();
2524        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2525        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2526        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2527        mVoiceWakeLock.setReferenceCounted(false);
2528    }
2529
2530    @Override
2531    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2532            throws RemoteException {
2533        if (code == SYSPROPS_TRANSACTION) {
2534            // We need to tell all apps about the system property change.
2535            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2536            synchronized(this) {
2537                final int NP = mProcessNames.getMap().size();
2538                for (int ip=0; ip<NP; ip++) {
2539                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2540                    final int NA = apps.size();
2541                    for (int ia=0; ia<NA; ia++) {
2542                        ProcessRecord app = apps.valueAt(ia);
2543                        if (app.thread != null) {
2544                            procs.add(app.thread.asBinder());
2545                        }
2546                    }
2547                }
2548            }
2549
2550            int N = procs.size();
2551            for (int i=0; i<N; i++) {
2552                Parcel data2 = Parcel.obtain();
2553                try {
2554                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2555                } catch (RemoteException e) {
2556                }
2557                data2.recycle();
2558            }
2559        }
2560        try {
2561            return super.onTransact(code, data, reply, flags);
2562        } catch (RuntimeException e) {
2563            // The activity manager only throws security exceptions, so let's
2564            // log all others.
2565            if (!(e instanceof SecurityException)) {
2566                Slog.wtf(TAG, "Activity Manager Crash", e);
2567            }
2568            throw e;
2569        }
2570    }
2571
2572    void updateCpuStats() {
2573        final long now = SystemClock.uptimeMillis();
2574        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2575            return;
2576        }
2577        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2578            synchronized (mProcessCpuThread) {
2579                mProcessCpuThread.notify();
2580            }
2581        }
2582    }
2583
2584    void updateCpuStatsNow() {
2585        synchronized (mProcessCpuTracker) {
2586            mProcessCpuMutexFree.set(false);
2587            final long now = SystemClock.uptimeMillis();
2588            boolean haveNewCpuStats = false;
2589
2590            if (MONITOR_CPU_USAGE &&
2591                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2592                mLastCpuTime.set(now);
2593                mProcessCpuTracker.update();
2594                if (mProcessCpuTracker.hasGoodLastStats()) {
2595                    haveNewCpuStats = true;
2596                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2597                    //Slog.i(TAG, "Total CPU usage: "
2598                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2599
2600                    // Slog the cpu usage if the property is set.
2601                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2602                        int user = mProcessCpuTracker.getLastUserTime();
2603                        int system = mProcessCpuTracker.getLastSystemTime();
2604                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2605                        int irq = mProcessCpuTracker.getLastIrqTime();
2606                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2607                        int idle = mProcessCpuTracker.getLastIdleTime();
2608
2609                        int total = user + system + iowait + irq + softIrq + idle;
2610                        if (total == 0) total = 1;
2611
2612                        EventLog.writeEvent(EventLogTags.CPU,
2613                                ((user+system+iowait+irq+softIrq) * 100) / total,
2614                                (user * 100) / total,
2615                                (system * 100) / total,
2616                                (iowait * 100) / total,
2617                                (irq * 100) / total,
2618                                (softIrq * 100) / total);
2619                    }
2620                }
2621            }
2622
2623            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2624            synchronized(bstats) {
2625                synchronized(mPidsSelfLocked) {
2626                    if (haveNewCpuStats) {
2627                        if (bstats.startAddingCpuLocked()) {
2628                            int totalUTime = 0;
2629                            int totalSTime = 0;
2630                            final int N = mProcessCpuTracker.countStats();
2631                            for (int i=0; i<N; i++) {
2632                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2633                                if (!st.working) {
2634                                    continue;
2635                                }
2636                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2637                                totalUTime += st.rel_utime;
2638                                totalSTime += st.rel_stime;
2639                                if (pr != null) {
2640                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2641                                    if (ps == null || !ps.isActive()) {
2642                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2643                                                pr.info.uid, pr.processName);
2644                                    }
2645                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2646                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2647                                } else {
2648                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2649                                    if (ps == null || !ps.isActive()) {
2650                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2651                                                bstats.mapUid(st.uid), st.name);
2652                                    }
2653                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2654                                }
2655                            }
2656                            final int userTime = mProcessCpuTracker.getLastUserTime();
2657                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2658                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2659                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2660                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2661                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2662                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2663                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2664                        }
2665                    }
2666                }
2667
2668                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2669                    mLastWriteTime = now;
2670                    mBatteryStatsService.scheduleWriteToDisk();
2671                }
2672            }
2673        }
2674    }
2675
2676    @Override
2677    public void batteryNeedsCpuUpdate() {
2678        updateCpuStatsNow();
2679    }
2680
2681    @Override
2682    public void batteryPowerChanged(boolean onBattery) {
2683        // When plugging in, update the CPU stats first before changing
2684        // the plug state.
2685        updateCpuStatsNow();
2686        synchronized (this) {
2687            synchronized(mPidsSelfLocked) {
2688                mOnBattery = DEBUG_POWER ? true : onBattery;
2689            }
2690        }
2691    }
2692
2693    @Override
2694    public void batterySendBroadcast(Intent intent) {
2695        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2696                AppOpsManager.OP_NONE, null, false, false,
2697                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2698    }
2699
2700    /**
2701     * Initialize the application bind args. These are passed to each
2702     * process when the bindApplication() IPC is sent to the process. They're
2703     * lazily setup to make sure the services are running when they're asked for.
2704     */
2705    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2706        if (mAppBindArgs == null) {
2707            mAppBindArgs = new HashMap<>();
2708
2709            // Isolated processes won't get this optimization, so that we don't
2710            // violate the rules about which services they have access to.
2711            if (!isolated) {
2712                // Setup the application init args
2713                mAppBindArgs.put("package", ServiceManager.getService("package"));
2714                mAppBindArgs.put("window", ServiceManager.getService("window"));
2715                mAppBindArgs.put(Context.ALARM_SERVICE,
2716                        ServiceManager.getService(Context.ALARM_SERVICE));
2717            }
2718        }
2719        return mAppBindArgs;
2720    }
2721
2722    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2723        if (r == null || mFocusedActivity == r) {
2724            return;
2725        }
2726
2727        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2728        final ActivityRecord last = mFocusedActivity;
2729        mFocusedActivity = r;
2730        if (r.task.isApplicationTask()) {
2731            if (mCurAppTimeTracker != r.appTimeTracker) {
2732                // We are switching app tracking.  Complete the current one.
2733                if (mCurAppTimeTracker != null) {
2734                    mCurAppTimeTracker.stop();
2735                    mHandler.obtainMessage(
2736                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2737                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2738                    mCurAppTimeTracker = null;
2739                }
2740                if (r.appTimeTracker != null) {
2741                    mCurAppTimeTracker = r.appTimeTracker;
2742                    startTimeTrackingFocusedActivityLocked();
2743                }
2744            } else {
2745                startTimeTrackingFocusedActivityLocked();
2746            }
2747        } else {
2748            r.appTimeTracker = null;
2749        }
2750        if (r.task.voiceInteractor != null) {
2751            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2752        } else {
2753            finishRunningVoiceLocked();
2754            if (last != null && last.task.voiceSession != null) {
2755                // We had been in a voice interaction session, but now focused has
2756                // move to something different.  Just finish the session, we can't
2757                // return to it and retain the proper state and synchronization with
2758                // the voice interaction service.
2759                finishVoiceTask(last.task.voiceSession);
2760            }
2761        }
2762        if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2763            mWindowManager.setFocusedApp(r.appToken, true);
2764        }
2765        applyUpdateLockStateLocked(r);
2766        if (mFocusedActivity.userId != mLastFocusedUserId) {
2767            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2768            mHandler.obtainMessage(
2769                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2770            mLastFocusedUserId = mFocusedActivity.userId;
2771        }
2772
2773        EventLogTags.writeAmFocusedActivity(
2774                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2775                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2776                reason);
2777    }
2778
2779    final void clearFocusedActivity(ActivityRecord r) {
2780        if (mFocusedActivity == r) {
2781            ActivityStack stack = mStackSupervisor.getFocusedStack();
2782            if (stack != null) {
2783                ActivityRecord top = stack.topActivity();
2784                if (top != null && top.userId != mLastFocusedUserId) {
2785                    mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2786                    mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2787                                    top.userId, 0));
2788                    mLastFocusedUserId = top.userId;
2789                }
2790            }
2791            mFocusedActivity = null;
2792            EventLogTags.writeAmFocusedActivity(-1, "NULL", "clearFocusedActivity");
2793        }
2794    }
2795
2796    @Override
2797    public void setFocusedStack(int stackId) {
2798        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2799        synchronized (ActivityManagerService.this) {
2800            ActivityStack stack = mStackSupervisor.getStack(stackId);
2801            if (stack != null) {
2802                ActivityRecord r = stack.topRunningActivityLocked();
2803                if (r != null) {
2804                    setFocusedActivityLocked(r, "setFocusedStack");
2805                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2806                }
2807            }
2808        }
2809    }
2810
2811    @Override
2812    public void setFocusedTask(int taskId) {
2813        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2814        long callingId = Binder.clearCallingIdentity();
2815        try {
2816            synchronized (ActivityManagerService.this) {
2817                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2818                if (task != null) {
2819                    ActivityRecord r = task.topRunningActivityLocked();
2820                    if (r != null) {
2821                        setFocusedActivityLocked(r, "setFocusedTask");
2822                        mStackSupervisor.resumeTopActivitiesLocked(task.stack, null, null);
2823                    }
2824                }
2825            }
2826        } finally {
2827            Binder.restoreCallingIdentity(callingId);
2828        }
2829    }
2830
2831    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2832    @Override
2833    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2834        synchronized (ActivityManagerService.this) {
2835            if (listener != null) {
2836                mTaskStackListeners.register(listener);
2837            }
2838        }
2839    }
2840
2841    @Override
2842    public void notifyActivityDrawn(IBinder token) {
2843        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2844        synchronized (this) {
2845            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2846            if (r != null) {
2847                r.task.stack.notifyActivityDrawnLocked(r);
2848            }
2849        }
2850    }
2851
2852    final void applyUpdateLockStateLocked(ActivityRecord r) {
2853        // Modifications to the UpdateLock state are done on our handler, outside
2854        // the activity manager's locks.  The new state is determined based on the
2855        // state *now* of the relevant activity record.  The object is passed to
2856        // the handler solely for logging detail, not to be consulted/modified.
2857        final boolean nextState = r != null && r.immersive;
2858        mHandler.sendMessage(
2859                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2860    }
2861
2862    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2863        Message msg = Message.obtain();
2864        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
2865        msg.obj = r.task.askedCompatMode ? null : r;
2866        mUiHandler.sendMessage(msg);
2867    }
2868
2869    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2870            String what, Object obj, ProcessRecord srcApp) {
2871        app.lastActivityTime = now;
2872
2873        if (app.activities.size() > 0) {
2874            // Don't want to touch dependent processes that are hosting activities.
2875            return index;
2876        }
2877
2878        int lrui = mLruProcesses.lastIndexOf(app);
2879        if (lrui < 0) {
2880            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2881                    + what + " " + obj + " from " + srcApp);
2882            return index;
2883        }
2884
2885        if (lrui >= index) {
2886            // Don't want to cause this to move dependent processes *back* in the
2887            // list as if they were less frequently used.
2888            return index;
2889        }
2890
2891        if (lrui >= mLruProcessActivityStart) {
2892            // Don't want to touch dependent processes that are hosting activities.
2893            return index;
2894        }
2895
2896        mLruProcesses.remove(lrui);
2897        if (index > 0) {
2898            index--;
2899        }
2900        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2901                + " in LRU list: " + app);
2902        mLruProcesses.add(index, app);
2903        return index;
2904    }
2905
2906    private static void killProcessGroup(int uid, int pid) {
2907        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2908        Process.killProcessGroup(uid, pid);
2909        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2910    }
2911
2912    final void removeLruProcessLocked(ProcessRecord app) {
2913        int lrui = mLruProcesses.lastIndexOf(app);
2914        if (lrui >= 0) {
2915            if (!app.killed) {
2916                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2917                Process.killProcessQuiet(app.pid);
2918                killProcessGroup(app.info.uid, app.pid);
2919            }
2920            if (lrui <= mLruProcessActivityStart) {
2921                mLruProcessActivityStart--;
2922            }
2923            if (lrui <= mLruProcessServiceStart) {
2924                mLruProcessServiceStart--;
2925            }
2926            mLruProcesses.remove(lrui);
2927        }
2928    }
2929
2930    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2931            ProcessRecord client) {
2932        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2933                || app.treatLikeActivity;
2934        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2935        if (!activityChange && hasActivity) {
2936            // The process has activities, so we are only allowing activity-based adjustments
2937            // to move it.  It should be kept in the front of the list with other
2938            // processes that have activities, and we don't want those to change their
2939            // order except due to activity operations.
2940            return;
2941        }
2942
2943        mLruSeq++;
2944        final long now = SystemClock.uptimeMillis();
2945        app.lastActivityTime = now;
2946
2947        // First a quick reject: if the app is already at the position we will
2948        // put it, then there is nothing to do.
2949        if (hasActivity) {
2950            final int N = mLruProcesses.size();
2951            if (N > 0 && mLruProcesses.get(N-1) == app) {
2952                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2953                return;
2954            }
2955        } else {
2956            if (mLruProcessServiceStart > 0
2957                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2958                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2959                return;
2960            }
2961        }
2962
2963        int lrui = mLruProcesses.lastIndexOf(app);
2964
2965        if (app.persistent && lrui >= 0) {
2966            // We don't care about the position of persistent processes, as long as
2967            // they are in the list.
2968            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2969            return;
2970        }
2971
2972        /* In progress: compute new position first, so we can avoid doing work
2973           if the process is not actually going to move.  Not yet working.
2974        int addIndex;
2975        int nextIndex;
2976        boolean inActivity = false, inService = false;
2977        if (hasActivity) {
2978            // Process has activities, put it at the very tipsy-top.
2979            addIndex = mLruProcesses.size();
2980            nextIndex = mLruProcessServiceStart;
2981            inActivity = true;
2982        } else if (hasService) {
2983            // Process has services, put it at the top of the service list.
2984            addIndex = mLruProcessActivityStart;
2985            nextIndex = mLruProcessServiceStart;
2986            inActivity = true;
2987            inService = true;
2988        } else  {
2989            // Process not otherwise of interest, it goes to the top of the non-service area.
2990            addIndex = mLruProcessServiceStart;
2991            if (client != null) {
2992                int clientIndex = mLruProcesses.lastIndexOf(client);
2993                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2994                        + app);
2995                if (clientIndex >= 0 && addIndex > clientIndex) {
2996                    addIndex = clientIndex;
2997                }
2998            }
2999            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3000        }
3001
3002        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3003                + mLruProcessActivityStart + "): " + app);
3004        */
3005
3006        if (lrui >= 0) {
3007            if (lrui < mLruProcessActivityStart) {
3008                mLruProcessActivityStart--;
3009            }
3010            if (lrui < mLruProcessServiceStart) {
3011                mLruProcessServiceStart--;
3012            }
3013            /*
3014            if (addIndex > lrui) {
3015                addIndex--;
3016            }
3017            if (nextIndex > lrui) {
3018                nextIndex--;
3019            }
3020            */
3021            mLruProcesses.remove(lrui);
3022        }
3023
3024        /*
3025        mLruProcesses.add(addIndex, app);
3026        if (inActivity) {
3027            mLruProcessActivityStart++;
3028        }
3029        if (inService) {
3030            mLruProcessActivityStart++;
3031        }
3032        */
3033
3034        int nextIndex;
3035        if (hasActivity) {
3036            final int N = mLruProcesses.size();
3037            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3038                // Process doesn't have activities, but has clients with
3039                // activities...  move it up, but one below the top (the top
3040                // should always have a real activity).
3041                if (DEBUG_LRU) Slog.d(TAG_LRU,
3042                        "Adding to second-top of LRU activity list: " + app);
3043                mLruProcesses.add(N - 1, app);
3044                // To keep it from spamming the LRU list (by making a bunch of clients),
3045                // we will push down any other entries owned by the app.
3046                final int uid = app.info.uid;
3047                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3048                    ProcessRecord subProc = mLruProcesses.get(i);
3049                    if (subProc.info.uid == uid) {
3050                        // We want to push this one down the list.  If the process after
3051                        // it is for the same uid, however, don't do so, because we don't
3052                        // want them internally to be re-ordered.
3053                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3054                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3055                                    "Pushing uid " + uid + " swapping at " + i + ": "
3056                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3057                            ProcessRecord tmp = mLruProcesses.get(i);
3058                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3059                            mLruProcesses.set(i - 1, tmp);
3060                            i--;
3061                        }
3062                    } else {
3063                        // A gap, we can stop here.
3064                        break;
3065                    }
3066                }
3067            } else {
3068                // Process has activities, put it at the very tipsy-top.
3069                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3070                mLruProcesses.add(app);
3071            }
3072            nextIndex = mLruProcessServiceStart;
3073        } else if (hasService) {
3074            // Process has services, put it at the top of the service list.
3075            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3076            mLruProcesses.add(mLruProcessActivityStart, app);
3077            nextIndex = mLruProcessServiceStart;
3078            mLruProcessActivityStart++;
3079        } else  {
3080            // Process not otherwise of interest, it goes to the top of the non-service area.
3081            int index = mLruProcessServiceStart;
3082            if (client != null) {
3083                // If there is a client, don't allow the process to be moved up higher
3084                // in the list than that client.
3085                int clientIndex = mLruProcesses.lastIndexOf(client);
3086                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3087                        + " when updating " + app);
3088                if (clientIndex <= lrui) {
3089                    // Don't allow the client index restriction to push it down farther in the
3090                    // list than it already is.
3091                    clientIndex = lrui;
3092                }
3093                if (clientIndex >= 0 && index > clientIndex) {
3094                    index = clientIndex;
3095                }
3096            }
3097            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3098            mLruProcesses.add(index, app);
3099            nextIndex = index-1;
3100            mLruProcessActivityStart++;
3101            mLruProcessServiceStart++;
3102        }
3103
3104        // If the app is currently using a content provider or service,
3105        // bump those processes as well.
3106        for (int j=app.connections.size()-1; j>=0; j--) {
3107            ConnectionRecord cr = app.connections.valueAt(j);
3108            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3109                    && cr.binding.service.app != null
3110                    && cr.binding.service.app.lruSeq != mLruSeq
3111                    && !cr.binding.service.app.persistent) {
3112                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3113                        "service connection", cr, app);
3114            }
3115        }
3116        for (int j=app.conProviders.size()-1; j>=0; j--) {
3117            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3118            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3119                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3120                        "provider reference", cpr, app);
3121            }
3122        }
3123    }
3124
3125    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3126        if (uid == Process.SYSTEM_UID) {
3127            // The system gets to run in any process.  If there are multiple
3128            // processes with the same uid, just pick the first (this
3129            // should never happen).
3130            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3131            if (procs == null) return null;
3132            final int procCount = procs.size();
3133            for (int i = 0; i < procCount; i++) {
3134                final int procUid = procs.keyAt(i);
3135                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3136                    // Don't use an app process or different user process for system component.
3137                    continue;
3138                }
3139                return procs.valueAt(i);
3140            }
3141        }
3142        ProcessRecord proc = mProcessNames.get(processName, uid);
3143        if (false && proc != null && !keepIfLarge
3144                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3145                && proc.lastCachedPss >= 4000) {
3146            // Turn this condition on to cause killing to happen regularly, for testing.
3147            if (proc.baseProcessTracker != null) {
3148                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3149            }
3150            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3151        } else if (proc != null && !keepIfLarge
3152                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3153                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3154            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3155            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3156                if (proc.baseProcessTracker != null) {
3157                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3158                }
3159                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3160            }
3161        }
3162        return proc;
3163    }
3164
3165    void notifyPackageUse(String packageName) {
3166        IPackageManager pm = AppGlobals.getPackageManager();
3167        try {
3168            pm.notifyPackageUse(packageName);
3169        } catch (RemoteException e) {
3170        }
3171    }
3172
3173    boolean isNextTransitionForward() {
3174        int transit = mWindowManager.getPendingAppTransition();
3175        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3176                || transit == AppTransition.TRANSIT_TASK_OPEN
3177                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3178    }
3179
3180    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3181            String processName, String abiOverride, int uid, Runnable crashHandler) {
3182        synchronized(this) {
3183            ApplicationInfo info = new ApplicationInfo();
3184            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3185            // For isolated processes, the former contains the parent's uid and the latter the
3186            // actual uid of the isolated process.
3187            // In the special case introduced by this method (which is, starting an isolated
3188            // process directly from the SystemServer without an actual parent app process) the
3189            // closest thing to a parent's uid is SYSTEM_UID.
3190            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3191            // the |isolated| logic in the ProcessRecord constructor.
3192            info.uid = Process.SYSTEM_UID;
3193            info.processName = processName;
3194            info.className = entryPoint;
3195            info.packageName = "android";
3196            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3197                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3198                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3199                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3200                    crashHandler);
3201            return proc != null ? proc.pid : 0;
3202        }
3203    }
3204
3205    final ProcessRecord startProcessLocked(String processName,
3206            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3207            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3208            boolean isolated, boolean keepIfLarge) {
3209        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3210                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3211                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3212                null /* crashHandler */);
3213    }
3214
3215    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3216            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3217            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3218            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3219        long startTime = SystemClock.elapsedRealtime();
3220        ProcessRecord app;
3221        if (!isolated) {
3222            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3223            checkTime(startTime, "startProcess: after getProcessRecord");
3224
3225            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3226                // If we are in the background, then check to see if this process
3227                // is bad.  If so, we will just silently fail.
3228                if (mBadProcesses.get(info.processName, info.uid) != null) {
3229                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3230                            + "/" + info.processName);
3231                    return null;
3232                }
3233            } else {
3234                // When the user is explicitly starting a process, then clear its
3235                // crash count so that we won't make it bad until they see at
3236                // least one crash dialog again, and make the process good again
3237                // if it had been bad.
3238                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3239                        + "/" + info.processName);
3240                mProcessCrashTimes.remove(info.processName, info.uid);
3241                if (mBadProcesses.get(info.processName, info.uid) != null) {
3242                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3243                            UserHandle.getUserId(info.uid), info.uid,
3244                            info.processName);
3245                    mBadProcesses.remove(info.processName, info.uid);
3246                    if (app != null) {
3247                        app.bad = false;
3248                    }
3249                }
3250            }
3251        } else {
3252            // If this is an isolated process, it can't re-use an existing process.
3253            app = null;
3254        }
3255
3256        // app launch boost for big.little configurations
3257        // use cpusets to migrate freshly launched tasks to big cores
3258        synchronized(ActivityManagerService.this) {
3259            nativeMigrateToBoost();
3260            mIsBoosted = true;
3261            mBoostStartTime = SystemClock.uptimeMillis();
3262            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3263            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3264        }
3265
3266        // We don't have to do anything more if:
3267        // (1) There is an existing application record; and
3268        // (2) The caller doesn't think it is dead, OR there is no thread
3269        //     object attached to it so we know it couldn't have crashed; and
3270        // (3) There is a pid assigned to it, so it is either starting or
3271        //     already running.
3272        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3273                + " app=" + app + " knownToBeDead=" + knownToBeDead
3274                + " thread=" + (app != null ? app.thread : null)
3275                + " pid=" + (app != null ? app.pid : -1));
3276        if (app != null && app.pid > 0) {
3277            if (!knownToBeDead || app.thread == null) {
3278                // We already have the app running, or are waiting for it to
3279                // come up (we have a pid but not yet its thread), so keep it.
3280                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3281                // If this is a new package in the process, add the package to the list
3282                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3283                checkTime(startTime, "startProcess: done, added package to proc");
3284                return app;
3285            }
3286
3287            // An application record is attached to a previous process,
3288            // clean it up now.
3289            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3290            checkTime(startTime, "startProcess: bad proc running, killing");
3291            killProcessGroup(app.info.uid, app.pid);
3292            handleAppDiedLocked(app, true, true);
3293            checkTime(startTime, "startProcess: done killing old proc");
3294        }
3295
3296        String hostingNameStr = hostingName != null
3297                ? hostingName.flattenToShortString() : null;
3298
3299        if (app == null) {
3300            checkTime(startTime, "startProcess: creating new process record");
3301            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3302            if (app == null) {
3303                Slog.w(TAG, "Failed making new process record for "
3304                        + processName + "/" + info.uid + " isolated=" + isolated);
3305                return null;
3306            }
3307            app.crashHandler = crashHandler;
3308            checkTime(startTime, "startProcess: done creating new process record");
3309        } else {
3310            // If this is a new package in the process, add the package to the list
3311            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3312            checkTime(startTime, "startProcess: added package to existing proc");
3313        }
3314
3315        // If the system is not ready yet, then hold off on starting this
3316        // process until it is.
3317        if (!mProcessesReady
3318                && !isAllowedWhileBooting(info)
3319                && !allowWhileBooting) {
3320            if (!mProcessesOnHold.contains(app)) {
3321                mProcessesOnHold.add(app);
3322            }
3323            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3324                    "System not ready, putting on hold: " + app);
3325            checkTime(startTime, "startProcess: returning with proc on hold");
3326            return app;
3327        }
3328
3329        checkTime(startTime, "startProcess: stepping in to startProcess");
3330        startProcessLocked(
3331                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3332        checkTime(startTime, "startProcess: done starting proc!");
3333        return (app.pid != 0) ? app : null;
3334    }
3335
3336    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3337        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3338    }
3339
3340    private final void startProcessLocked(ProcessRecord app,
3341            String hostingType, String hostingNameStr) {
3342        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3343                null /* entryPoint */, null /* entryPointArgs */);
3344    }
3345
3346    private final void startProcessLocked(ProcessRecord app, String hostingType,
3347            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3348        long startTime = SystemClock.elapsedRealtime();
3349        if (app.pid > 0 && app.pid != MY_PID) {
3350            checkTime(startTime, "startProcess: removing from pids map");
3351            synchronized (mPidsSelfLocked) {
3352                mPidsSelfLocked.remove(app.pid);
3353                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3354            }
3355            checkTime(startTime, "startProcess: done removing from pids map");
3356            app.setPid(0);
3357        }
3358
3359        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3360                "startProcessLocked removing on hold: " + app);
3361        mProcessesOnHold.remove(app);
3362
3363        checkTime(startTime, "startProcess: starting to update cpu stats");
3364        updateCpuStats();
3365        checkTime(startTime, "startProcess: done updating cpu stats");
3366
3367        try {
3368            try {
3369                final int userId = UserHandle.getUserId(app.uid);
3370                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3371            } catch (RemoteException e) {
3372                throw e.rethrowAsRuntimeException();
3373            }
3374
3375            int uid = app.uid;
3376            int[] gids = null;
3377            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3378            if (!app.isolated) {
3379                int[] permGids = null;
3380                try {
3381                    checkTime(startTime, "startProcess: getting gids from package manager");
3382                    final IPackageManager pm = AppGlobals.getPackageManager();
3383                    permGids = pm.getPackageGids(app.info.packageName, app.userId);
3384                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3385                            MountServiceInternal.class);
3386                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3387                            app.info.packageName);
3388                } catch (RemoteException e) {
3389                    throw e.rethrowAsRuntimeException();
3390                }
3391
3392                /*
3393                 * Add shared application and profile GIDs so applications can share some
3394                 * resources like shared libraries and access user-wide resources
3395                 */
3396                if (ArrayUtils.isEmpty(permGids)) {
3397                    gids = new int[2];
3398                } else {
3399                    gids = new int[permGids.length + 2];
3400                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3401                }
3402                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3403                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3404            }
3405            checkTime(startTime, "startProcess: building args");
3406            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3407                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3408                        && mTopComponent != null
3409                        && app.processName.equals(mTopComponent.getPackageName())) {
3410                    uid = 0;
3411                }
3412                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3413                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3414                    uid = 0;
3415                }
3416            }
3417            int debugFlags = 0;
3418            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3419                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3420                // Also turn on CheckJNI for debuggable apps. It's quite
3421                // awkward to turn on otherwise.
3422                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3423            }
3424            // Run the app in safe mode if its manifest requests so or the
3425            // system is booted in safe mode.
3426            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3427                mSafeMode == true) {
3428                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3429            }
3430            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3431                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3432            }
3433            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3434            if ("true".equals(genDebugInfoProperty)) {
3435                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3436            }
3437            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3438                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3439            }
3440            if ("1".equals(SystemProperties.get("debug.assert"))) {
3441                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3442            }
3443
3444            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3445            if (requiredAbi == null) {
3446                requiredAbi = Build.SUPPORTED_ABIS[0];
3447            }
3448
3449            String instructionSet = null;
3450            if (app.info.primaryCpuAbi != null) {
3451                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3452            }
3453
3454            app.gids = gids;
3455            app.requiredAbi = requiredAbi;
3456            app.instructionSet = instructionSet;
3457
3458            // Start the process.  It will either succeed and return a result containing
3459            // the PID of the new process, or else throw a RuntimeException.
3460            boolean isActivityProcess = (entryPoint == null);
3461            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3462            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3463                    app.processName);
3464            checkTime(startTime, "startProcess: asking zygote to start proc");
3465            Process.ProcessStartResult startResult = Process.start(entryPoint,
3466                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3467                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3468                    app.info.dataDir, entryPointArgs);
3469            checkTime(startTime, "startProcess: returned from zygote!");
3470            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3471
3472            if (app.isolated) {
3473                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3474            }
3475            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3476            checkTime(startTime, "startProcess: done updating battery stats");
3477
3478            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3479                    UserHandle.getUserId(uid), startResult.pid, uid,
3480                    app.processName, hostingType,
3481                    hostingNameStr != null ? hostingNameStr : "");
3482
3483            if (app.persistent) {
3484                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3485            }
3486
3487            checkTime(startTime, "startProcess: building log message");
3488            StringBuilder buf = mStringBuilder;
3489            buf.setLength(0);
3490            buf.append("Start proc ");
3491            buf.append(startResult.pid);
3492            buf.append(':');
3493            buf.append(app.processName);
3494            buf.append('/');
3495            UserHandle.formatUid(buf, uid);
3496            if (!isActivityProcess) {
3497                buf.append(" [");
3498                buf.append(entryPoint);
3499                buf.append("]");
3500            }
3501            buf.append(" for ");
3502            buf.append(hostingType);
3503            if (hostingNameStr != null) {
3504                buf.append(" ");
3505                buf.append(hostingNameStr);
3506            }
3507            Slog.i(TAG, buf.toString());
3508            app.setPid(startResult.pid);
3509            app.usingWrapper = startResult.usingWrapper;
3510            app.removed = false;
3511            app.killed = false;
3512            app.killedByAm = false;
3513            checkTime(startTime, "startProcess: starting to update pids map");
3514            synchronized (mPidsSelfLocked) {
3515                this.mPidsSelfLocked.put(startResult.pid, app);
3516                if (isActivityProcess) {
3517                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3518                    msg.obj = app;
3519                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3520                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3521                }
3522            }
3523            checkTime(startTime, "startProcess: done updating pids map");
3524        } catch (RuntimeException e) {
3525            // XXX do better error recovery.
3526            app.setPid(0);
3527            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3528            if (app.isolated) {
3529                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3530            }
3531            Slog.e(TAG, "Failure starting process " + app.processName, e);
3532        }
3533    }
3534
3535    void updateUsageStats(ActivityRecord component, boolean resumed) {
3536        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3537                "updateUsageStats: comp=" + component + "res=" + resumed);
3538        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3539        if (resumed) {
3540            if (mUsageStatsService != null) {
3541                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3542                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3543            }
3544            synchronized (stats) {
3545                stats.noteActivityResumedLocked(component.app.uid);
3546            }
3547        } else {
3548            if (mUsageStatsService != null) {
3549                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3550                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3551            }
3552            synchronized (stats) {
3553                stats.noteActivityPausedLocked(component.app.uid);
3554            }
3555        }
3556    }
3557
3558    Intent getHomeIntent() {
3559        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3560        intent.setComponent(mTopComponent);
3561        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3562            intent.addCategory(Intent.CATEGORY_HOME);
3563        }
3564        return intent;
3565    }
3566
3567    boolean startHomeActivityLocked(int userId, String reason) {
3568        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3569                && mTopAction == null) {
3570            // We are running in factory test mode, but unable to find
3571            // the factory test app, so just sit around displaying the
3572            // error message and don't try to start anything.
3573            return false;
3574        }
3575        Intent intent = getHomeIntent();
3576        ActivityInfo aInfo =
3577            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3578        if (aInfo != null) {
3579            intent.setComponent(new ComponentName(
3580                    aInfo.applicationInfo.packageName, aInfo.name));
3581            // Don't do this if the home app is currently being
3582            // instrumented.
3583            aInfo = new ActivityInfo(aInfo);
3584            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3585            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3586                    aInfo.applicationInfo.uid, true);
3587            if (app == null || app.instrumentationClass == null) {
3588                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3589                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3590            }
3591        }
3592
3593        return true;
3594    }
3595
3596    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3597        ActivityInfo ai = null;
3598        ComponentName comp = intent.getComponent();
3599        try {
3600            if (comp != null) {
3601                // Factory test.
3602                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3603            } else {
3604                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3605                        intent,
3606                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3607                        flags, userId);
3608
3609                if (info != null) {
3610                    ai = info.activityInfo;
3611                }
3612            }
3613        } catch (RemoteException e) {
3614            // ignore
3615        }
3616
3617        return ai;
3618    }
3619
3620    /**
3621     * Starts the "new version setup screen" if appropriate.
3622     */
3623    void startSetupActivityLocked() {
3624        // Only do this once per boot.
3625        if (mCheckedForSetup) {
3626            return;
3627        }
3628
3629        // We will show this screen if the current one is a different
3630        // version than the last one shown, and we are not running in
3631        // low-level factory test mode.
3632        final ContentResolver resolver = mContext.getContentResolver();
3633        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3634                Settings.Global.getInt(resolver,
3635                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3636            mCheckedForSetup = true;
3637
3638            // See if we should be showing the platform update setup UI.
3639            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3640            List<ResolveInfo> ris = mContext.getPackageManager()
3641                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3642
3643            // We don't allow third party apps to replace this.
3644            ResolveInfo ri = null;
3645            for (int i=0; ris != null && i<ris.size(); i++) {
3646                if ((ris.get(i).activityInfo.applicationInfo.flags
3647                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3648                    ri = ris.get(i);
3649                    break;
3650                }
3651            }
3652
3653            if (ri != null) {
3654                String vers = ri.activityInfo.metaData != null
3655                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3656                        : null;
3657                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3658                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3659                            Intent.METADATA_SETUP_VERSION);
3660                }
3661                String lastVers = Settings.Secure.getString(
3662                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3663                if (vers != null && !vers.equals(lastVers)) {
3664                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3665                    intent.setComponent(new ComponentName(
3666                            ri.activityInfo.packageName, ri.activityInfo.name));
3667                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3668                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
3669                            null, null, null);
3670                }
3671            }
3672        }
3673    }
3674
3675    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3676        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3677    }
3678
3679    void enforceNotIsolatedCaller(String caller) {
3680        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3681            throw new SecurityException("Isolated process not allowed to call " + caller);
3682        }
3683    }
3684
3685    void enforceShellRestriction(String restriction, int userHandle) {
3686        if (Binder.getCallingUid() == Process.SHELL_UID) {
3687            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3688                throw new SecurityException("Shell does not have permission to access user "
3689                        + userHandle);
3690            }
3691        }
3692    }
3693
3694    @Override
3695    public int getFrontActivityScreenCompatMode() {
3696        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3697        synchronized (this) {
3698            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3699        }
3700    }
3701
3702    @Override
3703    public void setFrontActivityScreenCompatMode(int mode) {
3704        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3705                "setFrontActivityScreenCompatMode");
3706        synchronized (this) {
3707            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3708        }
3709    }
3710
3711    @Override
3712    public int getPackageScreenCompatMode(String packageName) {
3713        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3714        synchronized (this) {
3715            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3716        }
3717    }
3718
3719    @Override
3720    public void setPackageScreenCompatMode(String packageName, int mode) {
3721        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3722                "setPackageScreenCompatMode");
3723        synchronized (this) {
3724            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3725        }
3726    }
3727
3728    @Override
3729    public boolean getPackageAskScreenCompat(String packageName) {
3730        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3731        synchronized (this) {
3732            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3733        }
3734    }
3735
3736    @Override
3737    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3738        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3739                "setPackageAskScreenCompat");
3740        synchronized (this) {
3741            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3742        }
3743    }
3744
3745    private boolean hasUsageStatsPermission(String callingPackage) {
3746        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3747                Binder.getCallingUid(), callingPackage);
3748        if (mode == AppOpsManager.MODE_DEFAULT) {
3749            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3750                    == PackageManager.PERMISSION_GRANTED;
3751        }
3752        return mode == AppOpsManager.MODE_ALLOWED;
3753    }
3754
3755    @Override
3756    public int getPackageProcessState(String packageName, String callingPackage) {
3757        if (!hasUsageStatsPermission(callingPackage)) {
3758            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3759                    "getPackageProcessState");
3760        }
3761
3762        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3763        synchronized (this) {
3764            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3765                final ProcessRecord proc = mLruProcesses.get(i);
3766                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3767                        || procState > proc.setProcState) {
3768                    boolean found = false;
3769                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3770                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3771                            procState = proc.setProcState;
3772                            found = true;
3773                        }
3774                    }
3775                    if (proc.pkgDeps != null && !found) {
3776                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3777                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3778                                procState = proc.setProcState;
3779                                break;
3780                            }
3781                        }
3782                    }
3783                }
3784            }
3785        }
3786        return procState;
3787    }
3788
3789    @Override
3790    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3791        synchronized (this) {
3792            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3793            if (app == null) {
3794                return false;
3795            }
3796            if (app.trimMemoryLevel < level && app.thread != null &&
3797                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3798                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3799                try {
3800                    app.thread.scheduleTrimMemory(level);
3801                    app.trimMemoryLevel = level;
3802                    return true;
3803                } catch (RemoteException e) {
3804                    // Fallthrough to failure case.
3805                }
3806            }
3807        }
3808        return false;
3809    }
3810
3811    private void dispatchProcessesChanged() {
3812        int N;
3813        synchronized (this) {
3814            N = mPendingProcessChanges.size();
3815            if (mActiveProcessChanges.length < N) {
3816                mActiveProcessChanges = new ProcessChangeItem[N];
3817            }
3818            mPendingProcessChanges.toArray(mActiveProcessChanges);
3819            mPendingProcessChanges.clear();
3820            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3821                    "*** Delivering " + N + " process changes");
3822        }
3823
3824        int i = mProcessObservers.beginBroadcast();
3825        while (i > 0) {
3826            i--;
3827            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3828            if (observer != null) {
3829                try {
3830                    for (int j=0; j<N; j++) {
3831                        ProcessChangeItem item = mActiveProcessChanges[j];
3832                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3833                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3834                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3835                                    + item.uid + ": " + item.foregroundActivities);
3836                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3837                                    item.foregroundActivities);
3838                        }
3839                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3840                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3841                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3842                                    + ": " + item.processState);
3843                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3844                        }
3845                    }
3846                } catch (RemoteException e) {
3847                }
3848            }
3849        }
3850        mProcessObservers.finishBroadcast();
3851
3852        synchronized (this) {
3853            for (int j=0; j<N; j++) {
3854                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3855            }
3856        }
3857    }
3858
3859    private void dispatchProcessDied(int pid, int uid) {
3860        int i = mProcessObservers.beginBroadcast();
3861        while (i > 0) {
3862            i--;
3863            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3864            if (observer != null) {
3865                try {
3866                    observer.onProcessDied(pid, uid);
3867                } catch (RemoteException e) {
3868                }
3869            }
3870        }
3871        mProcessObservers.finishBroadcast();
3872    }
3873
3874    private void dispatchUidsChanged() {
3875        int N;
3876        synchronized (this) {
3877            N = mPendingUidChanges.size();
3878            if (mActiveUidChanges.length < N) {
3879                mActiveUidChanges = new UidRecord.ChangeItem[N];
3880            }
3881            for (int i=0; i<N; i++) {
3882                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3883                mActiveUidChanges[i] = change;
3884                if (change.uidRecord != null) {
3885                    change.uidRecord.pendingChange = null;
3886                    change.uidRecord = null;
3887                }
3888            }
3889            mPendingUidChanges.clear();
3890            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3891                    "*** Delivering " + N + " uid changes");
3892        }
3893
3894        if (mLocalPowerManager != null) {
3895            for (int j=0; j<N; j++) {
3896                UidRecord.ChangeItem item = mActiveUidChanges[j];
3897                if (item.change == UidRecord.CHANGE_GONE
3898                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
3899                    mLocalPowerManager.uidGone(item.uid);
3900                } else {
3901                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3902                }
3903            }
3904        }
3905
3906        int i = mUidObservers.beginBroadcast();
3907        while (i > 0) {
3908            i--;
3909            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3910            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
3911            if (observer != null) {
3912                try {
3913                    for (int j=0; j<N; j++) {
3914                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3915                        final int change = item.change;
3916                        UidRecord validateUid = null;
3917                        if (VALIDATE_UID_STATES && i == 0) {
3918                            validateUid = mValidateUids.get(item.uid);
3919                            if (validateUid == null && change != UidRecord.CHANGE_GONE
3920                                    && change != UidRecord.CHANGE_GONE_IDLE) {
3921                                validateUid = new UidRecord(item.uid);
3922                                mValidateUids.put(item.uid, validateUid);
3923                            }
3924                        }
3925                        if (change == UidRecord.CHANGE_IDLE
3926                                || change == UidRecord.CHANGE_GONE_IDLE) {
3927                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
3928                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3929                                        "UID idle uid=" + item.uid);
3930                                observer.onUidIdle(item.uid);
3931                            }
3932                            if (VALIDATE_UID_STATES && i == 0) {
3933                                if (validateUid != null) {
3934                                    validateUid.idle = true;
3935                                }
3936                            }
3937                        } else if (change == UidRecord.CHANGE_ACTIVE) {
3938                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
3939                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3940                                        "UID active uid=" + item.uid);
3941                                observer.onUidActive(item.uid);
3942                            }
3943                            if (VALIDATE_UID_STATES && i == 0) {
3944                                validateUid.idle = false;
3945                            }
3946                        }
3947                        if (change == UidRecord.CHANGE_GONE
3948                                || change == UidRecord.CHANGE_GONE_IDLE) {
3949                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
3950                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3951                                        "UID gone uid=" + item.uid);
3952                                observer.onUidGone(item.uid);
3953                            }
3954                            if (VALIDATE_UID_STATES && i == 0) {
3955                                if (validateUid != null) {
3956                                    mValidateUids.remove(item.uid);
3957                                }
3958                            }
3959                        } else {
3960                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
3961                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3962                                        "UID CHANGED uid=" + item.uid
3963                                                + ": " + item.processState);
3964                                observer.onUidStateChanged(item.uid, item.processState);
3965                            }
3966                            if (VALIDATE_UID_STATES && i == 0) {
3967                                validateUid.curProcState = validateUid.setProcState
3968                                        = item.processState;
3969                            }
3970                        }
3971                    }
3972                } catch (RemoteException e) {
3973                }
3974            }
3975        }
3976        mUidObservers.finishBroadcast();
3977
3978        synchronized (this) {
3979            for (int j=0; j<N; j++) {
3980                mAvailUidChanges.add(mActiveUidChanges[j]);
3981            }
3982        }
3983    }
3984
3985    @Override
3986    public final int startActivity(IApplicationThread caller, String callingPackage,
3987            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3988            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
3989        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3990                resultWho, requestCode, startFlags, profilerInfo, bOptions,
3991                UserHandle.getCallingUserId());
3992    }
3993
3994    @Override
3995    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3996            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3997            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
3998        enforceNotIsolatedCaller("startActivity");
3999        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4000                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4001        // TODO: Switch to user app stacks here.
4002        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
4003                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4004                profilerInfo, null, null, bOptions, false, userId, null, null);
4005    }
4006
4007    @Override
4008    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4009            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4010            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4011            int userId) {
4012
4013        // This is very dangerous -- it allows you to perform a start activity (including
4014        // permission grants) as any app that may launch one of your own activities.  So
4015        // we will only allow this to be done from activities that are part of the core framework,
4016        // and then only when they are running as the system.
4017        final ActivityRecord sourceRecord;
4018        final int targetUid;
4019        final String targetPackage;
4020        synchronized (this) {
4021            if (resultTo == null) {
4022                throw new SecurityException("Must be called from an activity");
4023            }
4024            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4025            if (sourceRecord == null) {
4026                throw new SecurityException("Called with bad activity token: " + resultTo);
4027            }
4028            if (!sourceRecord.info.packageName.equals("android")) {
4029                throw new SecurityException(
4030                        "Must be called from an activity that is declared in the android package");
4031            }
4032            if (sourceRecord.app == null) {
4033                throw new SecurityException("Called without a process attached to activity");
4034            }
4035            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4036                // This is still okay, as long as this activity is running under the
4037                // uid of the original calling activity.
4038                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4039                    throw new SecurityException(
4040                            "Calling activity in uid " + sourceRecord.app.uid
4041                                    + " must be system uid or original calling uid "
4042                                    + sourceRecord.launchedFromUid);
4043                }
4044            }
4045            if (ignoreTargetSecurity) {
4046                if (intent.getComponent() == null) {
4047                    throw new SecurityException(
4048                            "Component must be specified with ignoreTargetSecurity");
4049                }
4050                if (intent.getSelector() != null) {
4051                    throw new SecurityException(
4052                            "Selector not allowed with ignoreTargetSecurity");
4053                }
4054            }
4055            targetUid = sourceRecord.launchedFromUid;
4056            targetPackage = sourceRecord.launchedFromPackage;
4057        }
4058
4059        if (userId == UserHandle.USER_NULL) {
4060            userId = UserHandle.getUserId(sourceRecord.app.uid);
4061        }
4062
4063        // TODO: Switch to user app stacks here.
4064        try {
4065            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
4066                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4067                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4068            return ret;
4069        } catch (SecurityException e) {
4070            // XXX need to figure out how to propagate to original app.
4071            // A SecurityException here is generally actually a fault of the original
4072            // calling activity (such as a fairly granting permissions), so propagate it
4073            // back to them.
4074            /*
4075            StringBuilder msg = new StringBuilder();
4076            msg.append("While launching");
4077            msg.append(intent.toString());
4078            msg.append(": ");
4079            msg.append(e.getMessage());
4080            */
4081            throw e;
4082        }
4083    }
4084
4085    @Override
4086    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4087            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4088            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4089        enforceNotIsolatedCaller("startActivityAndWait");
4090        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4091                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4092        WaitResult res = new WaitResult();
4093        // TODO: Switch to user app stacks here.
4094        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4095                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4096                bOptions, false, userId, null, null);
4097        return res;
4098    }
4099
4100    @Override
4101    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4102            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4103            int startFlags, Configuration config, Bundle bOptions, int userId) {
4104        enforceNotIsolatedCaller("startActivityWithConfig");
4105        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4106                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4107        // TODO: Switch to user app stacks here.
4108        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
4109                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4110                null, null, config, bOptions, false, userId, null, null);
4111        return ret;
4112    }
4113
4114    @Override
4115    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4116            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4117            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4118            throws TransactionTooLargeException {
4119        enforceNotIsolatedCaller("startActivityIntentSender");
4120        // Refuse possible leaked file descriptors
4121        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4122            throw new IllegalArgumentException("File descriptors passed in Intent");
4123        }
4124
4125        IIntentSender sender = intent.getTarget();
4126        if (!(sender instanceof PendingIntentRecord)) {
4127            throw new IllegalArgumentException("Bad PendingIntent object");
4128        }
4129
4130        PendingIntentRecord pir = (PendingIntentRecord)sender;
4131
4132        synchronized (this) {
4133            // If this is coming from the currently resumed activity, it is
4134            // effectively saying that app switches are allowed at this point.
4135            final ActivityStack stack = getFocusedStack();
4136            if (stack.mResumedActivity != null &&
4137                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4138                mAppSwitchesAllowedTime = 0;
4139            }
4140        }
4141        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4142                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4143        return ret;
4144    }
4145
4146    @Override
4147    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4148            Intent intent, String resolvedType, IVoiceInteractionSession session,
4149            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4150            Bundle bOptions, int userId) {
4151        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4152                != PackageManager.PERMISSION_GRANTED) {
4153            String msg = "Permission Denial: startVoiceActivity() from pid="
4154                    + Binder.getCallingPid()
4155                    + ", uid=" + Binder.getCallingUid()
4156                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4157            Slog.w(TAG, msg);
4158            throw new SecurityException(msg);
4159        }
4160        if (session == null || interactor == null) {
4161            throw new NullPointerException("null session or interactor");
4162        }
4163        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4164                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4165        // TODO: Switch to user app stacks here.
4166        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
4167                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4168                null, bOptions, false, userId, null, null);
4169    }
4170
4171    @Override
4172    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4173        synchronized (this) {
4174            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4175                if (keepAwake) {
4176                    mVoiceWakeLock.acquire();
4177                } else {
4178                    mVoiceWakeLock.release();
4179                }
4180            }
4181        }
4182    }
4183
4184    @Override
4185    public boolean startNextMatchingActivity(IBinder callingActivity,
4186            Intent intent, Bundle bOptions) {
4187        // Refuse possible leaked file descriptors
4188        if (intent != null && intent.hasFileDescriptors() == true) {
4189            throw new IllegalArgumentException("File descriptors passed in Intent");
4190        }
4191        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4192
4193        synchronized (this) {
4194            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4195            if (r == null) {
4196                ActivityOptions.abort(options);
4197                return false;
4198            }
4199            if (r.app == null || r.app.thread == null) {
4200                // The caller is not running...  d'oh!
4201                ActivityOptions.abort(options);
4202                return false;
4203            }
4204            intent = new Intent(intent);
4205            // The caller is not allowed to change the data.
4206            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4207            // And we are resetting to find the next component...
4208            intent.setComponent(null);
4209
4210            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4211
4212            ActivityInfo aInfo = null;
4213            try {
4214                List<ResolveInfo> resolves =
4215                    AppGlobals.getPackageManager().queryIntentActivities(
4216                            intent, r.resolvedType,
4217                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4218                            UserHandle.getCallingUserId());
4219
4220                // Look for the original activity in the list...
4221                final int N = resolves != null ? resolves.size() : 0;
4222                for (int i=0; i<N; i++) {
4223                    ResolveInfo rInfo = resolves.get(i);
4224                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4225                            && rInfo.activityInfo.name.equals(r.info.name)) {
4226                        // We found the current one...  the next matching is
4227                        // after it.
4228                        i++;
4229                        if (i<N) {
4230                            aInfo = resolves.get(i).activityInfo;
4231                        }
4232                        if (debug) {
4233                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4234                                    + "/" + r.info.name);
4235                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4236                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4237                        }
4238                        break;
4239                    }
4240                }
4241            } catch (RemoteException e) {
4242            }
4243
4244            if (aInfo == null) {
4245                // Nobody who is next!
4246                ActivityOptions.abort(options);
4247                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4248                return false;
4249            }
4250
4251            intent.setComponent(new ComponentName(
4252                    aInfo.applicationInfo.packageName, aInfo.name));
4253            intent.setFlags(intent.getFlags()&~(
4254                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4255                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4256                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4257                    Intent.FLAG_ACTIVITY_NEW_TASK));
4258
4259            // Okay now we need to start the new activity, replacing the
4260            // currently running activity.  This is a little tricky because
4261            // we want to start the new one as if the current one is finished,
4262            // but not finish the current one first so that there is no flicker.
4263            // And thus...
4264            final boolean wasFinishing = r.finishing;
4265            r.finishing = true;
4266
4267            // Propagate reply information over to the new activity.
4268            final ActivityRecord resultTo = r.resultTo;
4269            final String resultWho = r.resultWho;
4270            final int requestCode = r.requestCode;
4271            r.resultTo = null;
4272            if (resultTo != null) {
4273                resultTo.removeResultsLocked(r, resultWho, requestCode);
4274            }
4275
4276            final long origId = Binder.clearCallingIdentity();
4277            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4278                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4279                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4280                    -1, r.launchedFromUid, 0, options, false, false, null, null, null);
4281            Binder.restoreCallingIdentity(origId);
4282
4283            r.finishing = wasFinishing;
4284            if (res != ActivityManager.START_SUCCESS) {
4285                return false;
4286            }
4287            return true;
4288        }
4289    }
4290
4291    @Override
4292    public final int startActivityFromRecents(int taskId, int launchStackId, Bundle bOptions) {
4293        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4294            String msg = "Permission Denial: startActivityFromRecents called without " +
4295                    START_TASKS_FROM_RECENTS;
4296            Slog.w(TAG, msg);
4297            throw new SecurityException(msg);
4298        }
4299        final long origId = Binder.clearCallingIdentity();
4300        try {
4301            return startActivityFromRecentsInner(taskId, launchStackId, bOptions);
4302        } finally {
4303            Binder.restoreCallingIdentity(origId);
4304        }
4305    }
4306
4307    final int startActivityFromRecentsInner(int taskId, int launchStackId, Bundle bOptions) {
4308        final TaskRecord task;
4309        final int callingUid;
4310        final String callingPackage;
4311        final Intent intent;
4312        final int userId;
4313        synchronized (this) {
4314            if (launchStackId == HOME_STACK_ID) {
4315                throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4316                        + taskId + " can't be launch in the home stack.");
4317            }
4318
4319            task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4320            if (task == null) {
4321                throw new IllegalArgumentException(
4322                        "startActivityFromRecentsInner: Task " + taskId + " not found.");
4323            }
4324
4325            if (launchStackId != INVALID_STACK_ID) {
4326                if (launchStackId == DOCKED_STACK_ID && bOptions != null) {
4327                    ActivityOptions activityOptions = new ActivityOptions(bOptions);
4328                    mWindowManager.setDockedStackCreateState(activityOptions.getDockCreateMode(),
4329                            null /* initialBounds */);
4330                }
4331                if (task.stack.mStackId != launchStackId) {
4332                    mStackSupervisor.moveTaskToStackLocked(
4333                            taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
4334                            true /* animate */);
4335                }
4336            }
4337
4338            if (task.getRootActivity() != null) {
4339                moveTaskToFrontLocked(task.taskId, 0, bOptions);
4340                return ActivityManager.START_TASK_TO_FRONT;
4341            }
4342            callingUid = task.mCallingUid;
4343            callingPackage = task.mCallingPackage;
4344            intent = task.intent;
4345            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4346            userId = task.userId;
4347        }
4348        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4349                bOptions, userId, null, task);
4350    }
4351
4352    final int startActivityInPackage(int uid, String callingPackage,
4353            Intent intent, String resolvedType, IBinder resultTo,
4354            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4355            IActivityContainer container, TaskRecord inTask) {
4356
4357        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4358                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4359
4360        // TODO: Switch to user app stacks here.
4361        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4362                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4363                null, null, null, bOptions, false, userId, container, inTask);
4364        return ret;
4365    }
4366
4367    @Override
4368    public final int startActivities(IApplicationThread caller, String callingPackage,
4369            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4370            int userId) {
4371        enforceNotIsolatedCaller("startActivities");
4372        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4373                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4374        // TODO: Switch to user app stacks here.
4375        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4376                resolvedTypes, resultTo, bOptions, userId);
4377        return ret;
4378    }
4379
4380    final int startActivitiesInPackage(int uid, String callingPackage,
4381            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4382            Bundle bOptions, int userId) {
4383
4384        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4385                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4386        // TODO: Switch to user app stacks here.
4387        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4388                resultTo, bOptions, userId);
4389        return ret;
4390    }
4391
4392    @Override
4393    public void reportActivityFullyDrawn(IBinder token) {
4394        synchronized (this) {
4395            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4396            if (r == null) {
4397                return;
4398            }
4399            r.reportFullyDrawnLocked();
4400        }
4401    }
4402
4403    @Override
4404    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4405        synchronized (this) {
4406            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4407            if (r == null) {
4408                return;
4409            }
4410            TaskRecord task = r.task;
4411            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4412                // Fixed screen orientation isn't supported when activities aren't in full screen
4413                // mode.
4414                return;
4415            }
4416            final long origId = Binder.clearCallingIdentity();
4417            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4418            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4419                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4420            if (config != null) {
4421                r.frozenBeforeDestroy = true;
4422                if (!updateConfigurationLocked(config, r, false)) {
4423                    mStackSupervisor.resumeTopActivitiesLocked();
4424                }
4425            }
4426            Binder.restoreCallingIdentity(origId);
4427        }
4428    }
4429
4430    @Override
4431    public int getRequestedOrientation(IBinder token) {
4432        synchronized (this) {
4433            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4434            if (r == null) {
4435                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4436            }
4437            return mWindowManager.getAppOrientation(r.appToken);
4438        }
4439    }
4440
4441    /**
4442     * This is the internal entry point for handling Activity.finish().
4443     *
4444     * @param token The Binder token referencing the Activity we want to finish.
4445     * @param resultCode Result code, if any, from this Activity.
4446     * @param resultData Result data (Intent), if any, from this Activity.
4447     * @param finishTask Whether to finish the task associated with this Activity.
4448     *
4449     * @return Returns true if the activity successfully finished, or false if it is still running.
4450     */
4451    @Override
4452    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4453            int finishTask) {
4454        // Refuse possible leaked file descriptors
4455        if (resultData != null && resultData.hasFileDescriptors() == true) {
4456            throw new IllegalArgumentException("File descriptors passed in Intent");
4457        }
4458
4459        synchronized(this) {
4460            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4461            if (r == null) {
4462                return true;
4463            }
4464            // Keep track of the root activity of the task before we finish it
4465            TaskRecord tr = r.task;
4466            ActivityRecord rootR = tr.getRootActivity();
4467            if (rootR == null) {
4468                Slog.w(TAG, "Finishing task with all activities already finished");
4469            }
4470            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4471            // finish.
4472            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4473                    mStackSupervisor.isLastLockedTask(tr)) {
4474                Slog.i(TAG, "Not finishing task in lock task mode");
4475                mStackSupervisor.showLockTaskToast();
4476                return false;
4477            }
4478            if (mController != null) {
4479                // Find the first activity that is not finishing.
4480                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4481                if (next != null) {
4482                    // ask watcher if this is allowed
4483                    boolean resumeOK = true;
4484                    try {
4485                        resumeOK = mController.activityResuming(next.packageName);
4486                    } catch (RemoteException e) {
4487                        mController = null;
4488                        Watchdog.getInstance().setActivityController(null);
4489                    }
4490
4491                    if (!resumeOK) {
4492                        Slog.i(TAG, "Not finishing activity because controller resumed");
4493                        return false;
4494                    }
4495                }
4496            }
4497            final long origId = Binder.clearCallingIdentity();
4498            try {
4499                boolean res;
4500                final boolean finishWithRootActivity =
4501                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4502                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4503                        || (finishWithRootActivity && r == rootR)) {
4504                    // If requested, remove the task that is associated to this activity only if it
4505                    // was the root activity in the task. The result code and data is ignored
4506                    // because we don't support returning them across task boundaries. Also, to
4507                    // keep backwards compatibility we remove the task from recents when finishing
4508                    // task with root activity.
4509                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4510                    if (!res) {
4511                        Slog.i(TAG, "Removing task failed to finish activity");
4512                    }
4513                } else {
4514                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4515                            resultData, "app-request", true);
4516                    if (!res) {
4517                        Slog.i(TAG, "Failed to finish by app-request");
4518                    }
4519                }
4520                return res;
4521            } finally {
4522                Binder.restoreCallingIdentity(origId);
4523            }
4524        }
4525    }
4526
4527    @Override
4528    public final void finishHeavyWeightApp() {
4529        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4530                != PackageManager.PERMISSION_GRANTED) {
4531            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4532                    + Binder.getCallingPid()
4533                    + ", uid=" + Binder.getCallingUid()
4534                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4535            Slog.w(TAG, msg);
4536            throw new SecurityException(msg);
4537        }
4538
4539        synchronized(this) {
4540            if (mHeavyWeightProcess == null) {
4541                return;
4542            }
4543
4544            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4545            for (int i = 0; i < activities.size(); i++) {
4546                ActivityRecord r = activities.get(i);
4547                if (!r.finishing && r.isInStackLocked()) {
4548                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4549                            null, "finish-heavy", true);
4550                }
4551            }
4552
4553            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4554                    mHeavyWeightProcess.userId, 0));
4555            mHeavyWeightProcess = null;
4556        }
4557    }
4558
4559    @Override
4560    public void crashApplication(int uid, int initialPid, String packageName,
4561            String message) {
4562        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4563                != PackageManager.PERMISSION_GRANTED) {
4564            String msg = "Permission Denial: crashApplication() from pid="
4565                    + Binder.getCallingPid()
4566                    + ", uid=" + Binder.getCallingUid()
4567                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4568            Slog.w(TAG, msg);
4569            throw new SecurityException(msg);
4570        }
4571
4572        synchronized(this) {
4573            ProcessRecord proc = null;
4574
4575            // Figure out which process to kill.  We don't trust that initialPid
4576            // still has any relation to current pids, so must scan through the
4577            // list.
4578            synchronized (mPidsSelfLocked) {
4579                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4580                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4581                    if (p.uid != uid) {
4582                        continue;
4583                    }
4584                    if (p.pid == initialPid) {
4585                        proc = p;
4586                        break;
4587                    }
4588                    if (p.pkgList.containsKey(packageName)) {
4589                        proc = p;
4590                    }
4591                }
4592            }
4593
4594            if (proc == null) {
4595                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4596                        + " initialPid=" + initialPid
4597                        + " packageName=" + packageName);
4598                return;
4599            }
4600
4601            if (proc.thread != null) {
4602                if (proc.pid == Process.myPid()) {
4603                    Log.w(TAG, "crashApplication: trying to crash self!");
4604                    return;
4605                }
4606                long ident = Binder.clearCallingIdentity();
4607                try {
4608                    proc.thread.scheduleCrash(message);
4609                } catch (RemoteException e) {
4610                }
4611                Binder.restoreCallingIdentity(ident);
4612            }
4613        }
4614    }
4615
4616    @Override
4617    public final void finishSubActivity(IBinder token, String resultWho,
4618            int requestCode) {
4619        synchronized(this) {
4620            final long origId = Binder.clearCallingIdentity();
4621            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4622            if (r != null) {
4623                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4624            }
4625            Binder.restoreCallingIdentity(origId);
4626        }
4627    }
4628
4629    @Override
4630    public boolean finishActivityAffinity(IBinder token) {
4631        synchronized(this) {
4632            final long origId = Binder.clearCallingIdentity();
4633            try {
4634                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4635                if (r == null) {
4636                    return false;
4637                }
4638
4639                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4640                // can finish.
4641                final TaskRecord task = r.task;
4642                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4643                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4644                    mStackSupervisor.showLockTaskToast();
4645                    return false;
4646                }
4647                return task.stack.finishActivityAffinityLocked(r);
4648            } finally {
4649                Binder.restoreCallingIdentity(origId);
4650            }
4651        }
4652    }
4653
4654    @Override
4655    public void finishVoiceTask(IVoiceInteractionSession session) {
4656        synchronized(this) {
4657            final long origId = Binder.clearCallingIdentity();
4658            try {
4659                mStackSupervisor.finishVoiceTask(session);
4660            } finally {
4661                Binder.restoreCallingIdentity(origId);
4662            }
4663        }
4664
4665    }
4666
4667    @Override
4668    public boolean releaseActivityInstance(IBinder token) {
4669        synchronized(this) {
4670            final long origId = Binder.clearCallingIdentity();
4671            try {
4672                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4673                if (r == null) {
4674                    return false;
4675                }
4676                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4677            } finally {
4678                Binder.restoreCallingIdentity(origId);
4679            }
4680        }
4681    }
4682
4683    @Override
4684    public void releaseSomeActivities(IApplicationThread appInt) {
4685        synchronized(this) {
4686            final long origId = Binder.clearCallingIdentity();
4687            try {
4688                ProcessRecord app = getRecordForAppLocked(appInt);
4689                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4690            } finally {
4691                Binder.restoreCallingIdentity(origId);
4692            }
4693        }
4694    }
4695
4696    @Override
4697    public boolean willActivityBeVisible(IBinder token) {
4698        synchronized(this) {
4699            ActivityStack stack = ActivityRecord.getStackLocked(token);
4700            if (stack != null) {
4701                return stack.willActivityBeVisibleLocked(token);
4702            }
4703            return false;
4704        }
4705    }
4706
4707    @Override
4708    public void overridePendingTransition(IBinder token, String packageName,
4709            int enterAnim, int exitAnim) {
4710        synchronized(this) {
4711            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4712            if (self == null) {
4713                return;
4714            }
4715
4716            final long origId = Binder.clearCallingIdentity();
4717
4718            if (self.state == ActivityState.RESUMED
4719                    || self.state == ActivityState.PAUSING) {
4720                mWindowManager.overridePendingAppTransition(packageName,
4721                        enterAnim, exitAnim, null);
4722            }
4723
4724            Binder.restoreCallingIdentity(origId);
4725        }
4726    }
4727
4728    /**
4729     * Main function for removing an existing process from the activity manager
4730     * as a result of that process going away.  Clears out all connections
4731     * to the process.
4732     */
4733    private final void handleAppDiedLocked(ProcessRecord app,
4734            boolean restarting, boolean allowRestart) {
4735        int pid = app.pid;
4736        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4737        if (!kept && !restarting) {
4738            removeLruProcessLocked(app);
4739            if (pid > 0) {
4740                ProcessList.remove(pid);
4741            }
4742        }
4743
4744        if (mProfileProc == app) {
4745            clearProfilerLocked();
4746        }
4747
4748        // Remove this application's activities from active lists.
4749        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4750
4751        app.activities.clear();
4752
4753        if (app.instrumentationClass != null) {
4754            Slog.w(TAG, "Crash of app " + app.processName
4755                  + " running instrumentation " + app.instrumentationClass);
4756            Bundle info = new Bundle();
4757            info.putString("shortMsg", "Process crashed.");
4758            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4759        }
4760
4761        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4762            // If there was nothing to resume, and we are not already
4763            // restarting this process, but there is a visible activity that
4764            // is hosted by the process...  then make sure all visible
4765            // activities are running, taking care of restarting this
4766            // process.
4767            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4768        }
4769    }
4770
4771    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4772        IBinder threadBinder = thread.asBinder();
4773        // Find the application record.
4774        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4775            ProcessRecord rec = mLruProcesses.get(i);
4776            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4777                return i;
4778            }
4779        }
4780        return -1;
4781    }
4782
4783    final ProcessRecord getRecordForAppLocked(
4784            IApplicationThread thread) {
4785        if (thread == null) {
4786            return null;
4787        }
4788
4789        int appIndex = getLRURecordIndexForAppLocked(thread);
4790        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4791    }
4792
4793    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4794        // If there are no longer any background processes running,
4795        // and the app that died was not running instrumentation,
4796        // then tell everyone we are now low on memory.
4797        boolean haveBg = false;
4798        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4799            ProcessRecord rec = mLruProcesses.get(i);
4800            if (rec.thread != null
4801                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4802                haveBg = true;
4803                break;
4804            }
4805        }
4806
4807        if (!haveBg) {
4808            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4809            if (doReport) {
4810                long now = SystemClock.uptimeMillis();
4811                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4812                    doReport = false;
4813                } else {
4814                    mLastMemUsageReportTime = now;
4815                }
4816            }
4817            final ArrayList<ProcessMemInfo> memInfos
4818                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4819            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4820            long now = SystemClock.uptimeMillis();
4821            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4822                ProcessRecord rec = mLruProcesses.get(i);
4823                if (rec == dyingProc || rec.thread == null) {
4824                    continue;
4825                }
4826                if (doReport) {
4827                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4828                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4829                }
4830                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4831                    // The low memory report is overriding any current
4832                    // state for a GC request.  Make sure to do
4833                    // heavy/important/visible/foreground processes first.
4834                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4835                        rec.lastRequestedGc = 0;
4836                    } else {
4837                        rec.lastRequestedGc = rec.lastLowMemory;
4838                    }
4839                    rec.reportLowMemory = true;
4840                    rec.lastLowMemory = now;
4841                    mProcessesToGc.remove(rec);
4842                    addProcessToGcListLocked(rec);
4843                }
4844            }
4845            if (doReport) {
4846                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4847                mHandler.sendMessage(msg);
4848            }
4849            scheduleAppGcsLocked();
4850        }
4851    }
4852
4853    final void appDiedLocked(ProcessRecord app) {
4854       appDiedLocked(app, app.pid, app.thread, false);
4855    }
4856
4857    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4858            boolean fromBinderDied) {
4859        // First check if this ProcessRecord is actually active for the pid.
4860        synchronized (mPidsSelfLocked) {
4861            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4862            if (curProc != app) {
4863                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4864                return;
4865            }
4866        }
4867
4868        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4869        synchronized (stats) {
4870            stats.noteProcessDiedLocked(app.info.uid, pid);
4871        }
4872
4873        if (!app.killed) {
4874            if (!fromBinderDied) {
4875                Process.killProcessQuiet(pid);
4876            }
4877            killProcessGroup(app.info.uid, pid);
4878            app.killed = true;
4879        }
4880
4881        // Clean up already done if the process has been re-started.
4882        if (app.pid == pid && app.thread != null &&
4883                app.thread.asBinder() == thread.asBinder()) {
4884            boolean doLowMem = app.instrumentationClass == null;
4885            boolean doOomAdj = doLowMem;
4886            if (!app.killedByAm) {
4887                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4888                        + ") has died");
4889                mAllowLowerMemLevel = true;
4890            } else {
4891                // Note that we always want to do oom adj to update our state with the
4892                // new number of procs.
4893                mAllowLowerMemLevel = false;
4894                doLowMem = false;
4895            }
4896            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4897            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4898                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4899            handleAppDiedLocked(app, false, true);
4900
4901            if (doOomAdj) {
4902                updateOomAdjLocked();
4903            }
4904            if (doLowMem) {
4905                doLowMemReportIfNeededLocked(app);
4906            }
4907        } else if (app.pid != pid) {
4908            // A new process has already been started.
4909            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4910                    + ") has died and restarted (pid " + app.pid + ").");
4911            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4912        } else if (DEBUG_PROCESSES) {
4913            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4914                    + thread.asBinder());
4915        }
4916    }
4917
4918    /**
4919     * If a stack trace dump file is configured, dump process stack traces.
4920     * @param clearTraces causes the dump file to be erased prior to the new
4921     *    traces being written, if true; when false, the new traces will be
4922     *    appended to any existing file content.
4923     * @param firstPids of dalvik VM processes to dump stack traces for first
4924     * @param lastPids of dalvik VM processes to dump stack traces for last
4925     * @param nativeProcs optional list of native process names to dump stack crawls
4926     * @return file containing stack traces, or null if no dump file is configured
4927     */
4928    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4929            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4930        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4931        if (tracesPath == null || tracesPath.length() == 0) {
4932            return null;
4933        }
4934
4935        File tracesFile = new File(tracesPath);
4936        try {
4937            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4938            tracesFile.createNewFile();
4939            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4940        } catch (IOException e) {
4941            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4942            return null;
4943        }
4944
4945        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4946        return tracesFile;
4947    }
4948
4949    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4950            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4951        // Use a FileObserver to detect when traces finish writing.
4952        // The order of traces is considered important to maintain for legibility.
4953        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4954            @Override
4955            public synchronized void onEvent(int event, String path) { notify(); }
4956        };
4957
4958        try {
4959            observer.startWatching();
4960
4961            // First collect all of the stacks of the most important pids.
4962            if (firstPids != null) {
4963                try {
4964                    int num = firstPids.size();
4965                    for (int i = 0; i < num; i++) {
4966                        synchronized (observer) {
4967                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4968                            observer.wait(200);  // Wait for write-close, give up after 200msec
4969                        }
4970                    }
4971                } catch (InterruptedException e) {
4972                    Slog.wtf(TAG, e);
4973                }
4974            }
4975
4976            // Next collect the stacks of the native pids
4977            if (nativeProcs != null) {
4978                int[] pids = Process.getPidsForCommands(nativeProcs);
4979                if (pids != null) {
4980                    for (int pid : pids) {
4981                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4982                    }
4983                }
4984            }
4985
4986            // Lastly, measure CPU usage.
4987            if (processCpuTracker != null) {
4988                processCpuTracker.init();
4989                System.gc();
4990                processCpuTracker.update();
4991                try {
4992                    synchronized (processCpuTracker) {
4993                        processCpuTracker.wait(500); // measure over 1/2 second.
4994                    }
4995                } catch (InterruptedException e) {
4996                }
4997                processCpuTracker.update();
4998
4999                // We'll take the stack crawls of just the top apps using CPU.
5000                final int N = processCpuTracker.countWorkingStats();
5001                int numProcs = 0;
5002                for (int i=0; i<N && numProcs<5; i++) {
5003                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5004                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5005                        numProcs++;
5006                        try {
5007                            synchronized (observer) {
5008                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5009                                observer.wait(200);  // Wait for write-close, give up after 200msec
5010                            }
5011                        } catch (InterruptedException e) {
5012                            Slog.wtf(TAG, e);
5013                        }
5014
5015                    }
5016                }
5017            }
5018        } finally {
5019            observer.stopWatching();
5020        }
5021    }
5022
5023    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5024        if (true || IS_USER_BUILD) {
5025            return;
5026        }
5027        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5028        if (tracesPath == null || tracesPath.length() == 0) {
5029            return;
5030        }
5031
5032        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5033        StrictMode.allowThreadDiskWrites();
5034        try {
5035            final File tracesFile = new File(tracesPath);
5036            final File tracesDir = tracesFile.getParentFile();
5037            final File tracesTmp = new File(tracesDir, "__tmp__");
5038            try {
5039                if (tracesFile.exists()) {
5040                    tracesTmp.delete();
5041                    tracesFile.renameTo(tracesTmp);
5042                }
5043                StringBuilder sb = new StringBuilder();
5044                Time tobj = new Time();
5045                tobj.set(System.currentTimeMillis());
5046                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5047                sb.append(": ");
5048                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5049                sb.append(" since ");
5050                sb.append(msg);
5051                FileOutputStream fos = new FileOutputStream(tracesFile);
5052                fos.write(sb.toString().getBytes());
5053                if (app == null) {
5054                    fos.write("\n*** No application process!".getBytes());
5055                }
5056                fos.close();
5057                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5058            } catch (IOException e) {
5059                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5060                return;
5061            }
5062
5063            if (app != null) {
5064                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5065                firstPids.add(app.pid);
5066                dumpStackTraces(tracesPath, firstPids, null, null, null);
5067            }
5068
5069            File lastTracesFile = null;
5070            File curTracesFile = null;
5071            for (int i=9; i>=0; i--) {
5072                String name = String.format(Locale.US, "slow%02d.txt", i);
5073                curTracesFile = new File(tracesDir, name);
5074                if (curTracesFile.exists()) {
5075                    if (lastTracesFile != null) {
5076                        curTracesFile.renameTo(lastTracesFile);
5077                    } else {
5078                        curTracesFile.delete();
5079                    }
5080                }
5081                lastTracesFile = curTracesFile;
5082            }
5083            tracesFile.renameTo(curTracesFile);
5084            if (tracesTmp.exists()) {
5085                tracesTmp.renameTo(tracesFile);
5086            }
5087        } finally {
5088            StrictMode.setThreadPolicy(oldPolicy);
5089        }
5090    }
5091
5092    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5093            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5094        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5095        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5096
5097        if (mController != null) {
5098            try {
5099                // 0 == continue, -1 = kill process immediately
5100                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5101                if (res < 0 && app.pid != MY_PID) {
5102                    app.kill("anr", true);
5103                }
5104            } catch (RemoteException e) {
5105                mController = null;
5106                Watchdog.getInstance().setActivityController(null);
5107            }
5108        }
5109
5110        long anrTime = SystemClock.uptimeMillis();
5111        if (MONITOR_CPU_USAGE) {
5112            updateCpuStatsNow();
5113        }
5114
5115        synchronized (this) {
5116            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5117            if (mShuttingDown) {
5118                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5119                return;
5120            } else if (app.notResponding) {
5121                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5122                return;
5123            } else if (app.crashing) {
5124                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5125                return;
5126            }
5127
5128            // In case we come through here for the same app before completing
5129            // this one, mark as anring now so we will bail out.
5130            app.notResponding = true;
5131
5132            // Log the ANR to the event log.
5133            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5134                    app.processName, app.info.flags, annotation);
5135
5136            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5137            firstPids.add(app.pid);
5138
5139            int parentPid = app.pid;
5140            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5141            if (parentPid != app.pid) firstPids.add(parentPid);
5142
5143            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5144
5145            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5146                ProcessRecord r = mLruProcesses.get(i);
5147                if (r != null && r.thread != null) {
5148                    int pid = r.pid;
5149                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5150                        if (r.persistent) {
5151                            firstPids.add(pid);
5152                        } else {
5153                            lastPids.put(pid, Boolean.TRUE);
5154                        }
5155                    }
5156                }
5157            }
5158        }
5159
5160        // Log the ANR to the main log.
5161        StringBuilder info = new StringBuilder();
5162        info.setLength(0);
5163        info.append("ANR in ").append(app.processName);
5164        if (activity != null && activity.shortComponentName != null) {
5165            info.append(" (").append(activity.shortComponentName).append(")");
5166        }
5167        info.append("\n");
5168        info.append("PID: ").append(app.pid).append("\n");
5169        if (annotation != null) {
5170            info.append("Reason: ").append(annotation).append("\n");
5171        }
5172        if (parent != null && parent != activity) {
5173            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5174        }
5175
5176        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5177
5178        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5179                NATIVE_STACKS_OF_INTEREST);
5180
5181        String cpuInfo = null;
5182        if (MONITOR_CPU_USAGE) {
5183            updateCpuStatsNow();
5184            synchronized (mProcessCpuTracker) {
5185                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5186            }
5187            info.append(processCpuTracker.printCurrentLoad());
5188            info.append(cpuInfo);
5189        }
5190
5191        info.append(processCpuTracker.printCurrentState(anrTime));
5192
5193        Slog.e(TAG, info.toString());
5194        if (tracesFile == null) {
5195            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5196            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5197        }
5198
5199        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5200                cpuInfo, tracesFile, null);
5201
5202        if (mController != null) {
5203            try {
5204                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5205                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5206                if (res != 0) {
5207                    if (res < 0 && app.pid != MY_PID) {
5208                        app.kill("anr", true);
5209                    } else {
5210                        synchronized (this) {
5211                            mServices.scheduleServiceTimeoutLocked(app);
5212                        }
5213                    }
5214                    return;
5215                }
5216            } catch (RemoteException e) {
5217                mController = null;
5218                Watchdog.getInstance().setActivityController(null);
5219            }
5220        }
5221
5222        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5223        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5224                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5225
5226        synchronized (this) {
5227            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5228
5229            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5230                app.kill("bg anr", true);
5231                return;
5232            }
5233
5234            // Set the app's notResponding state, and look up the errorReportReceiver
5235            makeAppNotRespondingLocked(app,
5236                    activity != null ? activity.shortComponentName : null,
5237                    annotation != null ? "ANR " + annotation : "ANR",
5238                    info.toString());
5239
5240            // Bring up the infamous App Not Responding dialog
5241            Message msg = Message.obtain();
5242            HashMap<String, Object> map = new HashMap<String, Object>();
5243            msg.what = SHOW_NOT_RESPONDING_UI_MSG;
5244            msg.obj = map;
5245            msg.arg1 = aboveSystem ? 1 : 0;
5246            map.put("app", app);
5247            if (activity != null) {
5248                map.put("activity", activity);
5249            }
5250
5251            mUiHandler.sendMessage(msg);
5252        }
5253    }
5254
5255    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5256        if (!mLaunchWarningShown) {
5257            mLaunchWarningShown = true;
5258            mUiHandler.post(new Runnable() {
5259                @Override
5260                public void run() {
5261                    synchronized (ActivityManagerService.this) {
5262                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5263                        d.show();
5264                        mUiHandler.postDelayed(new Runnable() {
5265                            @Override
5266                            public void run() {
5267                                synchronized (ActivityManagerService.this) {
5268                                    d.dismiss();
5269                                    mLaunchWarningShown = false;
5270                                }
5271                            }
5272                        }, 4000);
5273                    }
5274                }
5275            });
5276        }
5277    }
5278
5279    @Override
5280    public boolean clearApplicationUserData(final String packageName,
5281            final IPackageDataObserver observer, int userId) {
5282        enforceNotIsolatedCaller("clearApplicationUserData");
5283        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5284            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5285        }
5286        int uid = Binder.getCallingUid();
5287        int pid = Binder.getCallingPid();
5288        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5289                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5290        long callingId = Binder.clearCallingIdentity();
5291        try {
5292            IPackageManager pm = AppGlobals.getPackageManager();
5293            int pkgUid = -1;
5294            synchronized(this) {
5295                try {
5296                    pkgUid = pm.getPackageUid(packageName, userId);
5297                } catch (RemoteException e) {
5298                }
5299                if (pkgUid == -1) {
5300                    Slog.w(TAG, "Invalid packageName: " + packageName);
5301                    if (observer != null) {
5302                        try {
5303                            observer.onRemoveCompleted(packageName, false);
5304                        } catch (RemoteException e) {
5305                            Slog.i(TAG, "Observer no longer exists.");
5306                        }
5307                    }
5308                    return false;
5309                }
5310                if (uid == pkgUid || checkComponentPermission(
5311                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5312                        pid, uid, -1, true)
5313                        == PackageManager.PERMISSION_GRANTED) {
5314                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5315                } else {
5316                    throw new SecurityException("PID " + pid + " does not have permission "
5317                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5318                                    + " of package " + packageName);
5319                }
5320
5321                // Remove all tasks match the cleared application package and user
5322                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5323                    final TaskRecord tr = mRecentTasks.get(i);
5324                    final String taskPackageName =
5325                            tr.getBaseIntent().getComponent().getPackageName();
5326                    if (tr.userId != userId) continue;
5327                    if (!taskPackageName.equals(packageName)) continue;
5328                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5329                }
5330            }
5331
5332            try {
5333                // Clear application user data
5334                pm.clearApplicationUserData(packageName, observer, userId);
5335
5336                synchronized(this) {
5337                    // Remove all permissions granted from/to this package
5338                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5339                }
5340
5341                // Remove all zen rules created by this package; revoke it's zen access.
5342                INotificationManager inm = NotificationManager.getService();
5343                inm.removeAutomaticZenRules(packageName);
5344                inm.setNotificationPolicyAccessGranted(packageName, false);
5345
5346                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5347                        Uri.fromParts("package", packageName, null));
5348                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5349                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5350                        null, null, 0, null, null, null, null, false, false, userId);
5351            } catch (RemoteException e) {
5352            }
5353        } finally {
5354            Binder.restoreCallingIdentity(callingId);
5355        }
5356        return true;
5357    }
5358
5359    @Override
5360    public void killBackgroundProcesses(final String packageName, int userId) {
5361        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5362                != PackageManager.PERMISSION_GRANTED &&
5363                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5364                        != PackageManager.PERMISSION_GRANTED) {
5365            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5366                    + Binder.getCallingPid()
5367                    + ", uid=" + Binder.getCallingUid()
5368                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5369            Slog.w(TAG, msg);
5370            throw new SecurityException(msg);
5371        }
5372
5373        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5374                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5375        long callingId = Binder.clearCallingIdentity();
5376        try {
5377            IPackageManager pm = AppGlobals.getPackageManager();
5378            synchronized(this) {
5379                int appId = -1;
5380                try {
5381                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5382                } catch (RemoteException e) {
5383                }
5384                if (appId == -1) {
5385                    Slog.w(TAG, "Invalid packageName: " + packageName);
5386                    return;
5387                }
5388                killPackageProcessesLocked(packageName, appId, userId,
5389                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5390            }
5391        } finally {
5392            Binder.restoreCallingIdentity(callingId);
5393        }
5394    }
5395
5396    @Override
5397    public void killAllBackgroundProcesses() {
5398        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5399                != PackageManager.PERMISSION_GRANTED) {
5400            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5401                    + Binder.getCallingPid()
5402                    + ", uid=" + Binder.getCallingUid()
5403                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5404            Slog.w(TAG, msg);
5405            throw new SecurityException(msg);
5406        }
5407
5408        long callingId = Binder.clearCallingIdentity();
5409        try {
5410            synchronized(this) {
5411                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5412                final int NP = mProcessNames.getMap().size();
5413                for (int ip=0; ip<NP; ip++) {
5414                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5415                    final int NA = apps.size();
5416                    for (int ia=0; ia<NA; ia++) {
5417                        ProcessRecord app = apps.valueAt(ia);
5418                        if (app.persistent) {
5419                            // we don't kill persistent processes
5420                            continue;
5421                        }
5422                        if (app.removed) {
5423                            procs.add(app);
5424                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5425                            app.removed = true;
5426                            procs.add(app);
5427                        }
5428                    }
5429                }
5430
5431                int N = procs.size();
5432                for (int i=0; i<N; i++) {
5433                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5434                }
5435                mAllowLowerMemLevel = true;
5436                updateOomAdjLocked();
5437                doLowMemReportIfNeededLocked(null);
5438            }
5439        } finally {
5440            Binder.restoreCallingIdentity(callingId);
5441        }
5442    }
5443
5444    @Override
5445    public void forceStopPackage(final String packageName, int userId) {
5446        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5447                != PackageManager.PERMISSION_GRANTED) {
5448            String msg = "Permission Denial: forceStopPackage() from pid="
5449                    + Binder.getCallingPid()
5450                    + ", uid=" + Binder.getCallingUid()
5451                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5452            Slog.w(TAG, msg);
5453            throw new SecurityException(msg);
5454        }
5455        final int callingPid = Binder.getCallingPid();
5456        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5457                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5458        long callingId = Binder.clearCallingIdentity();
5459        try {
5460            IPackageManager pm = AppGlobals.getPackageManager();
5461            synchronized(this) {
5462                int[] users = userId == UserHandle.USER_ALL
5463                        ? mUserController.getUsers() : new int[] { userId };
5464                for (int user : users) {
5465                    int pkgUid = -1;
5466                    try {
5467                        pkgUid = pm.getPackageUid(packageName, user);
5468                    } catch (RemoteException e) {
5469                    }
5470                    if (pkgUid == -1) {
5471                        Slog.w(TAG, "Invalid packageName: " + packageName);
5472                        continue;
5473                    }
5474                    try {
5475                        pm.setPackageStoppedState(packageName, true, user);
5476                    } catch (RemoteException e) {
5477                    } catch (IllegalArgumentException e) {
5478                        Slog.w(TAG, "Failed trying to unstop package "
5479                                + packageName + ": " + e);
5480                    }
5481                    if (mUserController.isUserRunningLocked(user, 0)) {
5482                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5483                    }
5484                }
5485            }
5486        } finally {
5487            Binder.restoreCallingIdentity(callingId);
5488        }
5489    }
5490
5491    @Override
5492    public void addPackageDependency(String packageName) {
5493        synchronized (this) {
5494            int callingPid = Binder.getCallingPid();
5495            if (callingPid == Process.myPid()) {
5496                //  Yeah, um, no.
5497                return;
5498            }
5499            ProcessRecord proc;
5500            synchronized (mPidsSelfLocked) {
5501                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5502            }
5503            if (proc != null) {
5504                if (proc.pkgDeps == null) {
5505                    proc.pkgDeps = new ArraySet<String>(1);
5506                }
5507                proc.pkgDeps.add(packageName);
5508            }
5509        }
5510    }
5511
5512    /*
5513     * The pkg name and app id have to be specified.
5514     */
5515    @Override
5516    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5517        if (pkg == null) {
5518            return;
5519        }
5520        // Make sure the uid is valid.
5521        if (appid < 0) {
5522            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5523            return;
5524        }
5525        int callerUid = Binder.getCallingUid();
5526        // Only the system server can kill an application
5527        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5528            // Post an aysnc message to kill the application
5529            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5530            msg.arg1 = appid;
5531            msg.arg2 = 0;
5532            Bundle bundle = new Bundle();
5533            bundle.putString("pkg", pkg);
5534            bundle.putString("reason", reason);
5535            msg.obj = bundle;
5536            mHandler.sendMessage(msg);
5537        } else {
5538            throw new SecurityException(callerUid + " cannot kill pkg: " +
5539                    pkg);
5540        }
5541    }
5542
5543    @Override
5544    public void closeSystemDialogs(String reason) {
5545        enforceNotIsolatedCaller("closeSystemDialogs");
5546
5547        final int pid = Binder.getCallingPid();
5548        final int uid = Binder.getCallingUid();
5549        final long origId = Binder.clearCallingIdentity();
5550        try {
5551            synchronized (this) {
5552                // Only allow this from foreground processes, so that background
5553                // applications can't abuse it to prevent system UI from being shown.
5554                if (uid >= Process.FIRST_APPLICATION_UID) {
5555                    ProcessRecord proc;
5556                    synchronized (mPidsSelfLocked) {
5557                        proc = mPidsSelfLocked.get(pid);
5558                    }
5559                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5560                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5561                                + " from background process " + proc);
5562                        return;
5563                    }
5564                }
5565                closeSystemDialogsLocked(reason);
5566            }
5567        } finally {
5568            Binder.restoreCallingIdentity(origId);
5569        }
5570    }
5571
5572    void closeSystemDialogsLocked(String reason) {
5573        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5574        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5575                | Intent.FLAG_RECEIVER_FOREGROUND);
5576        if (reason != null) {
5577            intent.putExtra("reason", reason);
5578        }
5579        mWindowManager.closeSystemDialogs(reason);
5580
5581        mStackSupervisor.closeSystemDialogsLocked();
5582
5583        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5584                AppOpsManager.OP_NONE, null, false, false,
5585                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5586    }
5587
5588    @Override
5589    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5590        enforceNotIsolatedCaller("getProcessMemoryInfo");
5591        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5592        for (int i=pids.length-1; i>=0; i--) {
5593            ProcessRecord proc;
5594            int oomAdj;
5595            synchronized (this) {
5596                synchronized (mPidsSelfLocked) {
5597                    proc = mPidsSelfLocked.get(pids[i]);
5598                    oomAdj = proc != null ? proc.setAdj : 0;
5599                }
5600            }
5601            infos[i] = new Debug.MemoryInfo();
5602            Debug.getMemoryInfo(pids[i], infos[i]);
5603            if (proc != null) {
5604                synchronized (this) {
5605                    if (proc.thread != null && proc.setAdj == oomAdj) {
5606                        // Record this for posterity if the process has been stable.
5607                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5608                                infos[i].getTotalUss(), false, proc.pkgList);
5609                    }
5610                }
5611            }
5612        }
5613        return infos;
5614    }
5615
5616    @Override
5617    public long[] getProcessPss(int[] pids) {
5618        enforceNotIsolatedCaller("getProcessPss");
5619        long[] pss = new long[pids.length];
5620        for (int i=pids.length-1; i>=0; i--) {
5621            ProcessRecord proc;
5622            int oomAdj;
5623            synchronized (this) {
5624                synchronized (mPidsSelfLocked) {
5625                    proc = mPidsSelfLocked.get(pids[i]);
5626                    oomAdj = proc != null ? proc.setAdj : 0;
5627                }
5628            }
5629            long[] tmpUss = new long[1];
5630            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5631            if (proc != null) {
5632                synchronized (this) {
5633                    if (proc.thread != null && proc.setAdj == oomAdj) {
5634                        // Record this for posterity if the process has been stable.
5635                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5636                    }
5637                }
5638            }
5639        }
5640        return pss;
5641    }
5642
5643    @Override
5644    public void killApplicationProcess(String processName, int uid) {
5645        if (processName == null) {
5646            return;
5647        }
5648
5649        int callerUid = Binder.getCallingUid();
5650        // Only the system server can kill an application
5651        if (callerUid == Process.SYSTEM_UID) {
5652            synchronized (this) {
5653                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5654                if (app != null && app.thread != null) {
5655                    try {
5656                        app.thread.scheduleSuicide();
5657                    } catch (RemoteException e) {
5658                        // If the other end already died, then our work here is done.
5659                    }
5660                } else {
5661                    Slog.w(TAG, "Process/uid not found attempting kill of "
5662                            + processName + " / " + uid);
5663                }
5664            }
5665        } else {
5666            throw new SecurityException(callerUid + " cannot kill app process: " +
5667                    processName);
5668        }
5669    }
5670
5671    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5672        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5673                false, true, false, false, UserHandle.getUserId(uid), reason);
5674        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5675                Uri.fromParts("package", packageName, null));
5676        if (!mProcessesReady) {
5677            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5678                    | Intent.FLAG_RECEIVER_FOREGROUND);
5679        }
5680        intent.putExtra(Intent.EXTRA_UID, uid);
5681        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5682        broadcastIntentLocked(null, null, intent,
5683                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5684                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5685    }
5686
5687
5688    private final boolean killPackageProcessesLocked(String packageName, int appId,
5689            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5690            boolean doit, boolean evenPersistent, String reason) {
5691        ArrayList<ProcessRecord> procs = new ArrayList<>();
5692
5693        // Remove all processes this package may have touched: all with the
5694        // same UID (except for the system or root user), and all whose name
5695        // matches the package name.
5696        final int NP = mProcessNames.getMap().size();
5697        for (int ip=0; ip<NP; ip++) {
5698            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5699            final int NA = apps.size();
5700            for (int ia=0; ia<NA; ia++) {
5701                ProcessRecord app = apps.valueAt(ia);
5702                if (app.persistent && !evenPersistent) {
5703                    // we don't kill persistent processes
5704                    continue;
5705                }
5706                if (app.removed) {
5707                    if (doit) {
5708                        procs.add(app);
5709                    }
5710                    continue;
5711                }
5712
5713                // Skip process if it doesn't meet our oom adj requirement.
5714                if (app.setAdj < minOomAdj) {
5715                    continue;
5716                }
5717
5718                // If no package is specified, we call all processes under the
5719                // give user id.
5720                if (packageName == null) {
5721                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5722                        continue;
5723                    }
5724                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5725                        continue;
5726                    }
5727                // Package has been specified, we want to hit all processes
5728                // that match it.  We need to qualify this by the processes
5729                // that are running under the specified app and user ID.
5730                } else {
5731                    final boolean isDep = app.pkgDeps != null
5732                            && app.pkgDeps.contains(packageName);
5733                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5734                        continue;
5735                    }
5736                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5737                        continue;
5738                    }
5739                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5740                        continue;
5741                    }
5742                }
5743
5744                // Process has passed all conditions, kill it!
5745                if (!doit) {
5746                    return true;
5747                }
5748                app.removed = true;
5749                procs.add(app);
5750            }
5751        }
5752
5753        int N = procs.size();
5754        for (int i=0; i<N; i++) {
5755            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5756        }
5757        updateOomAdjLocked();
5758        return N > 0;
5759    }
5760
5761    private void cleanupDisabledPackageComponentsLocked(
5762            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5763
5764        Set<String> disabledClasses = null;
5765        boolean packageDisabled = false;
5766        IPackageManager pm = AppGlobals.getPackageManager();
5767
5768        if (changedClasses == null) {
5769            // Nothing changed...
5770            return;
5771        }
5772
5773        // Determine enable/disable state of the package and its components.
5774        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5775        for (int i = changedClasses.length - 1; i >= 0; i--) {
5776            final String changedClass = changedClasses[i];
5777
5778            if (changedClass.equals(packageName)) {
5779                try {
5780                    // Entire package setting changed
5781                    enabled = pm.getApplicationEnabledSetting(packageName,
5782                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5783                } catch (Exception e) {
5784                    // No such package/component; probably racing with uninstall.  In any
5785                    // event it means we have nothing further to do here.
5786                    return;
5787                }
5788                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5789                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5790                if (packageDisabled) {
5791                    // Entire package is disabled.
5792                    // No need to continue to check component states.
5793                    disabledClasses = null;
5794                    break;
5795                }
5796            } else {
5797                try {
5798                    enabled = pm.getComponentEnabledSetting(
5799                            new ComponentName(packageName, changedClass),
5800                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5801                } catch (Exception e) {
5802                    // As above, probably racing with uninstall.
5803                    return;
5804                }
5805                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5806                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5807                    if (disabledClasses == null) {
5808                        disabledClasses = new ArraySet<>(changedClasses.length);
5809                    }
5810                    disabledClasses.add(changedClass);
5811                }
5812            }
5813        }
5814
5815        if (!packageDisabled && disabledClasses == null) {
5816            // Nothing to do here...
5817            return;
5818        }
5819
5820        // Clean-up disabled activities.
5821        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5822                packageName, disabledClasses, true, false, userId) && mBooted) {
5823            mStackSupervisor.resumeTopActivitiesLocked();
5824            mStackSupervisor.scheduleIdleLocked();
5825        }
5826
5827        // Clean-up disabled tasks
5828        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5829
5830        // Clean-up disabled services.
5831        mServices.bringDownDisabledPackageServicesLocked(
5832                packageName, disabledClasses, userId, false, killProcess, true);
5833
5834        // Clean-up disabled providers.
5835        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5836        mProviderMap.collectPackageProvidersLocked(
5837                packageName, disabledClasses, true, false, userId, providers);
5838        for (int i = providers.size() - 1; i >= 0; i--) {
5839            removeDyingProviderLocked(null, providers.get(i), true);
5840        }
5841
5842        // Clean-up disabled broadcast receivers.
5843        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5844            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5845                    packageName, disabledClasses, userId, true);
5846        }
5847
5848    }
5849
5850    final boolean forceStopPackageLocked(String packageName, int appId,
5851            boolean callerWillRestart, boolean purgeCache, boolean doit,
5852            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5853        int i;
5854
5855        if (userId == UserHandle.USER_ALL && packageName == null) {
5856            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5857        }
5858
5859        if (appId < 0 && packageName != null) {
5860            try {
5861                appId = UserHandle.getAppId(
5862                        AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5863            } catch (RemoteException e) {
5864            }
5865        }
5866
5867        if (doit) {
5868            if (packageName != null) {
5869                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5870                        + " user=" + userId + ": " + reason);
5871            } else {
5872                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5873            }
5874
5875            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5876            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5877                SparseArray<Long> ba = pmap.valueAt(ip);
5878                for (i = ba.size() - 1; i >= 0; i--) {
5879                    boolean remove = false;
5880                    final int entUid = ba.keyAt(i);
5881                    if (packageName != null) {
5882                        if (userId == UserHandle.USER_ALL) {
5883                            if (UserHandle.getAppId(entUid) == appId) {
5884                                remove = true;
5885                            }
5886                        } else {
5887                            if (entUid == UserHandle.getUid(userId, appId)) {
5888                                remove = true;
5889                            }
5890                        }
5891                    } else if (UserHandle.getUserId(entUid) == userId) {
5892                        remove = true;
5893                    }
5894                    if (remove) {
5895                        ba.removeAt(i);
5896                    }
5897                }
5898                if (ba.size() == 0) {
5899                    pmap.removeAt(ip);
5900                }
5901            }
5902        }
5903
5904        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5905                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5906                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5907
5908        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5909                packageName, null, doit, evenPersistent, userId)) {
5910            if (!doit) {
5911                return true;
5912            }
5913            didSomething = true;
5914        }
5915
5916        if (mServices.bringDownDisabledPackageServicesLocked(
5917                packageName, null, userId, evenPersistent, true, doit)) {
5918            if (!doit) {
5919                return true;
5920            }
5921            didSomething = true;
5922        }
5923
5924        if (packageName == null) {
5925            // Remove all sticky broadcasts from this user.
5926            mStickyBroadcasts.remove(userId);
5927        }
5928
5929        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5930        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5931                userId, providers)) {
5932            if (!doit) {
5933                return true;
5934            }
5935            didSomething = true;
5936        }
5937        for (i = providers.size() - 1; i >= 0; i--) {
5938            removeDyingProviderLocked(null, providers.get(i), true);
5939        }
5940
5941        // Remove transient permissions granted from/to this package/user
5942        removeUriPermissionsForPackageLocked(packageName, userId, false);
5943
5944        if (doit) {
5945            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5946                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5947                        packageName, null, userId, doit);
5948            }
5949        }
5950
5951        if (packageName == null || uninstalling) {
5952            // Remove pending intents.  For now we only do this when force
5953            // stopping users, because we have some problems when doing this
5954            // for packages -- app widgets are not currently cleaned up for
5955            // such packages, so they can be left with bad pending intents.
5956            if (mIntentSenderRecords.size() > 0) {
5957                Iterator<WeakReference<PendingIntentRecord>> it
5958                        = mIntentSenderRecords.values().iterator();
5959                while (it.hasNext()) {
5960                    WeakReference<PendingIntentRecord> wpir = it.next();
5961                    if (wpir == null) {
5962                        it.remove();
5963                        continue;
5964                    }
5965                    PendingIntentRecord pir = wpir.get();
5966                    if (pir == null) {
5967                        it.remove();
5968                        continue;
5969                    }
5970                    if (packageName == null) {
5971                        // Stopping user, remove all objects for the user.
5972                        if (pir.key.userId != userId) {
5973                            // Not the same user, skip it.
5974                            continue;
5975                        }
5976                    } else {
5977                        if (UserHandle.getAppId(pir.uid) != appId) {
5978                            // Different app id, skip it.
5979                            continue;
5980                        }
5981                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5982                            // Different user, skip it.
5983                            continue;
5984                        }
5985                        if (!pir.key.packageName.equals(packageName)) {
5986                            // Different package, skip it.
5987                            continue;
5988                        }
5989                    }
5990                    if (!doit) {
5991                        return true;
5992                    }
5993                    didSomething = true;
5994                    it.remove();
5995                    pir.canceled = true;
5996                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5997                        pir.key.activity.pendingResults.remove(pir.ref);
5998                    }
5999                }
6000            }
6001        }
6002
6003        if (doit) {
6004            if (purgeCache && packageName != null) {
6005                AttributeCache ac = AttributeCache.instance();
6006                if (ac != null) {
6007                    ac.removePackage(packageName);
6008                }
6009            }
6010            if (mBooted) {
6011                mStackSupervisor.resumeTopActivitiesLocked();
6012                mStackSupervisor.scheduleIdleLocked();
6013            }
6014        }
6015
6016        return didSomething;
6017    }
6018
6019    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6020        ProcessRecord old = mProcessNames.remove(name, uid);
6021        if (old != null) {
6022            old.uidRecord.numProcs--;
6023            if (old.uidRecord.numProcs == 0) {
6024                // No more processes using this uid, tell clients it is gone.
6025                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6026                        "No more processes in " + old.uidRecord);
6027                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6028                mActiveUids.remove(uid);
6029                mBatteryStatsService.noteUidProcessState(uid,
6030                        ActivityManager.PROCESS_STATE_NONEXISTENT);
6031            }
6032            old.uidRecord = null;
6033        }
6034        mIsolatedProcesses.remove(uid);
6035        return old;
6036    }
6037
6038    private final void addProcessNameLocked(ProcessRecord proc) {
6039        // We shouldn't already have a process under this name, but just in case we
6040        // need to clean up whatever may be there now.
6041        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6042        if (old == proc && proc.persistent) {
6043            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6044            Slog.w(TAG, "Re-adding persistent process " + proc);
6045        } else if (old != null) {
6046            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6047        }
6048        UidRecord uidRec = mActiveUids.get(proc.uid);
6049        if (uidRec == null) {
6050            uidRec = new UidRecord(proc.uid);
6051            // This is the first appearance of the uid, report it now!
6052            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6053                    "Creating new process uid: " + uidRec);
6054            mActiveUids.put(proc.uid, uidRec);
6055            mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
6056            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6057        }
6058        proc.uidRecord = uidRec;
6059        uidRec.numProcs++;
6060        mProcessNames.put(proc.processName, proc.uid, proc);
6061        if (proc.isolated) {
6062            mIsolatedProcesses.put(proc.uid, proc);
6063        }
6064    }
6065
6066    private final boolean removeProcessLocked(ProcessRecord app,
6067            boolean callerWillRestart, boolean allowRestart, String reason) {
6068        final String name = app.processName;
6069        final int uid = app.uid;
6070        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6071            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6072
6073        removeProcessNameLocked(name, uid);
6074        if (mHeavyWeightProcess == app) {
6075            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6076                    mHeavyWeightProcess.userId, 0));
6077            mHeavyWeightProcess = null;
6078        }
6079        boolean needRestart = false;
6080        if (app.pid > 0 && app.pid != MY_PID) {
6081            int pid = app.pid;
6082            synchronized (mPidsSelfLocked) {
6083                mPidsSelfLocked.remove(pid);
6084                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6085            }
6086            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6087            if (app.isolated) {
6088                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6089            }
6090            boolean willRestart = false;
6091            if (app.persistent && !app.isolated) {
6092                if (!callerWillRestart) {
6093                    willRestart = true;
6094                } else {
6095                    needRestart = true;
6096                }
6097            }
6098            app.kill(reason, true);
6099            handleAppDiedLocked(app, willRestart, allowRestart);
6100            if (willRestart) {
6101                removeLruProcessLocked(app);
6102                addAppLocked(app.info, false, null /* ABI override */);
6103            }
6104        } else {
6105            mRemovedProcesses.add(app);
6106        }
6107
6108        return needRestart;
6109    }
6110
6111    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6112        cleanupAppInLaunchingProvidersLocked(app, true);
6113        removeProcessLocked(app, false, true, "timeout publishing content providers");
6114    }
6115
6116    private final void processStartTimedOutLocked(ProcessRecord app) {
6117        final int pid = app.pid;
6118        boolean gone = false;
6119        synchronized (mPidsSelfLocked) {
6120            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6121            if (knownApp != null && knownApp.thread == null) {
6122                mPidsSelfLocked.remove(pid);
6123                gone = true;
6124            }
6125        }
6126
6127        if (gone) {
6128            Slog.w(TAG, "Process " + app + " failed to attach");
6129            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6130                    pid, app.uid, app.processName);
6131            removeProcessNameLocked(app.processName, app.uid);
6132            if (mHeavyWeightProcess == app) {
6133                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6134                        mHeavyWeightProcess.userId, 0));
6135                mHeavyWeightProcess = null;
6136            }
6137            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6138            if (app.isolated) {
6139                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6140            }
6141            // Take care of any launching providers waiting for this process.
6142            cleanupAppInLaunchingProvidersLocked(app, true);
6143            // Take care of any services that are waiting for the process.
6144            mServices.processStartTimedOutLocked(app);
6145            app.kill("start timeout", true);
6146            removeLruProcessLocked(app);
6147            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6148                Slog.w(TAG, "Unattached app died before backup, skipping");
6149                try {
6150                    IBackupManager bm = IBackupManager.Stub.asInterface(
6151                            ServiceManager.getService(Context.BACKUP_SERVICE));
6152                    bm.agentDisconnected(app.info.packageName);
6153                } catch (RemoteException e) {
6154                    // Can't happen; the backup manager is local
6155                }
6156            }
6157            if (isPendingBroadcastProcessLocked(pid)) {
6158                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6159                skipPendingBroadcastLocked(pid);
6160            }
6161        } else {
6162            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6163        }
6164    }
6165
6166    private final boolean attachApplicationLocked(IApplicationThread thread,
6167            int pid) {
6168
6169        // Find the application record that is being attached...  either via
6170        // the pid if we are running in multiple processes, or just pull the
6171        // next app record if we are emulating process with anonymous threads.
6172        ProcessRecord app;
6173        if (pid != MY_PID && pid >= 0) {
6174            synchronized (mPidsSelfLocked) {
6175                app = mPidsSelfLocked.get(pid);
6176            }
6177        } else {
6178            app = null;
6179        }
6180
6181        if (app == null) {
6182            Slog.w(TAG, "No pending application record for pid " + pid
6183                    + " (IApplicationThread " + thread + "); dropping process");
6184            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6185            if (pid > 0 && pid != MY_PID) {
6186                Process.killProcessQuiet(pid);
6187                //TODO: killProcessGroup(app.info.uid, pid);
6188            } else {
6189                try {
6190                    thread.scheduleExit();
6191                } catch (Exception e) {
6192                    // Ignore exceptions.
6193                }
6194            }
6195            return false;
6196        }
6197
6198        // If this application record is still attached to a previous
6199        // process, clean it up now.
6200        if (app.thread != null) {
6201            handleAppDiedLocked(app, true, true);
6202        }
6203
6204        // Tell the process all about itself.
6205
6206        if (DEBUG_ALL) Slog.v(
6207                TAG, "Binding process pid " + pid + " to record " + app);
6208
6209        final String processName = app.processName;
6210        try {
6211            AppDeathRecipient adr = new AppDeathRecipient(
6212                    app, pid, thread);
6213            thread.asBinder().linkToDeath(adr, 0);
6214            app.deathRecipient = adr;
6215        } catch (RemoteException e) {
6216            app.resetPackageList(mProcessStats);
6217            startProcessLocked(app, "link fail", processName);
6218            return false;
6219        }
6220
6221        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6222
6223        app.makeActive(thread, mProcessStats);
6224        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6225        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6226        app.forcingToForeground = null;
6227        updateProcessForegroundLocked(app, false, false);
6228        app.hasShownUi = false;
6229        app.debugging = false;
6230        app.cached = false;
6231        app.killedByAm = false;
6232
6233        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6234
6235        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6236        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6237
6238        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6239            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6240            msg.obj = app;
6241            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6242        }
6243
6244        if (!normalMode) {
6245            Slog.i(TAG, "Launching preboot mode app: " + app);
6246        }
6247
6248        if (DEBUG_ALL) Slog.v(
6249            TAG, "New app record " + app
6250            + " thread=" + thread.asBinder() + " pid=" + pid);
6251        try {
6252            int testMode = IApplicationThread.DEBUG_OFF;
6253            if (mDebugApp != null && mDebugApp.equals(processName)) {
6254                testMode = mWaitForDebugger
6255                    ? IApplicationThread.DEBUG_WAIT
6256                    : IApplicationThread.DEBUG_ON;
6257                app.debugging = true;
6258                if (mDebugTransient) {
6259                    mDebugApp = mOrigDebugApp;
6260                    mWaitForDebugger = mOrigWaitForDebugger;
6261                }
6262            }
6263            String profileFile = app.instrumentationProfileFile;
6264            ParcelFileDescriptor profileFd = null;
6265            int samplingInterval = 0;
6266            boolean profileAutoStop = false;
6267            if (mProfileApp != null && mProfileApp.equals(processName)) {
6268                mProfileProc = app;
6269                profileFile = mProfileFile;
6270                profileFd = mProfileFd;
6271                samplingInterval = mSamplingInterval;
6272                profileAutoStop = mAutoStopProfiler;
6273            }
6274            boolean enableTrackAllocation = false;
6275            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6276                enableTrackAllocation = true;
6277                mTrackAllocationApp = null;
6278            }
6279
6280            // If the app is being launched for restore or full backup, set it up specially
6281            boolean isRestrictedBackupMode = false;
6282            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6283                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6284                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6285                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6286            }
6287
6288            notifyPackageUse(app.instrumentationInfo != null
6289                    ? app.instrumentationInfo.packageName
6290                    : app.info.packageName);
6291            if (app.instrumentationClass != null) {
6292                notifyPackageUse(app.instrumentationClass.getPackageName());
6293            }
6294            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6295                    + processName + " with config " + mConfiguration);
6296            ApplicationInfo appInfo = app.instrumentationInfo != null
6297                    ? app.instrumentationInfo : app.info;
6298            app.compat = compatibilityInfoForPackageLocked(appInfo);
6299            if (profileFd != null) {
6300                profileFd = profileFd.dup();
6301            }
6302            ProfilerInfo profilerInfo = profileFile == null ? null
6303                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6304            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6305                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6306                    app.instrumentationUiAutomationConnection, testMode,
6307                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6308                    isRestrictedBackupMode || !normalMode, app.persistent,
6309                    new Configuration(mConfiguration), app.compat,
6310                    getCommonServicesLocked(app.isolated),
6311                    mCoreSettingsObserver.getCoreSettingsLocked());
6312            updateLruProcessLocked(app, false, null);
6313            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6314        } catch (Exception e) {
6315            // todo: Yikes!  What should we do?  For now we will try to
6316            // start another process, but that could easily get us in
6317            // an infinite loop of restarting processes...
6318            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6319
6320            app.resetPackageList(mProcessStats);
6321            app.unlinkDeathRecipient();
6322            startProcessLocked(app, "bind fail", processName);
6323            return false;
6324        }
6325
6326        // Remove this record from the list of starting applications.
6327        mPersistentStartingProcesses.remove(app);
6328        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6329                "Attach application locked removing on hold: " + app);
6330        mProcessesOnHold.remove(app);
6331
6332        boolean badApp = false;
6333        boolean didSomething = false;
6334
6335        // See if the top visible activity is waiting to run in this process...
6336        if (normalMode) {
6337            try {
6338                if (mStackSupervisor.attachApplicationLocked(app)) {
6339                    didSomething = true;
6340                }
6341            } catch (Exception e) {
6342                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6343                badApp = true;
6344            }
6345        }
6346
6347        // Find any services that should be running in this process...
6348        if (!badApp) {
6349            try {
6350                didSomething |= mServices.attachApplicationLocked(app, processName);
6351            } catch (Exception e) {
6352                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6353                badApp = true;
6354            }
6355        }
6356
6357        // Check if a next-broadcast receiver is in this process...
6358        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6359            try {
6360                didSomething |= sendPendingBroadcastsLocked(app);
6361            } catch (Exception e) {
6362                // If the app died trying to launch the receiver we declare it 'bad'
6363                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6364                badApp = true;
6365            }
6366        }
6367
6368        // Check whether the next backup agent is in this process...
6369        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6370            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6371                    "New app is backup target, launching agent for " + app);
6372            notifyPackageUse(mBackupTarget.appInfo.packageName);
6373            try {
6374                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6375                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6376                        mBackupTarget.backupMode);
6377            } catch (Exception e) {
6378                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6379                badApp = true;
6380            }
6381        }
6382
6383        if (badApp) {
6384            app.kill("error during init", true);
6385            handleAppDiedLocked(app, false, true);
6386            return false;
6387        }
6388
6389        if (!didSomething) {
6390            updateOomAdjLocked();
6391        }
6392
6393        return true;
6394    }
6395
6396    @Override
6397    public final void attachApplication(IApplicationThread thread) {
6398        synchronized (this) {
6399            int callingPid = Binder.getCallingPid();
6400            final long origId = Binder.clearCallingIdentity();
6401            attachApplicationLocked(thread, callingPid);
6402            Binder.restoreCallingIdentity(origId);
6403        }
6404    }
6405
6406    @Override
6407    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6408        final long origId = Binder.clearCallingIdentity();
6409        synchronized (this) {
6410            ActivityStack stack = ActivityRecord.getStackLocked(token);
6411            if (stack != null) {
6412                ActivityRecord r =
6413                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6414                if (stopProfiling) {
6415                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6416                        try {
6417                            mProfileFd.close();
6418                        } catch (IOException e) {
6419                        }
6420                        clearProfilerLocked();
6421                    }
6422                }
6423            }
6424        }
6425        Binder.restoreCallingIdentity(origId);
6426    }
6427
6428    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6429        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6430                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6431    }
6432
6433    void enableScreenAfterBoot() {
6434        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6435                SystemClock.uptimeMillis());
6436        mWindowManager.enableScreenAfterBoot();
6437
6438        synchronized (this) {
6439            updateEventDispatchingLocked();
6440        }
6441    }
6442
6443    @Override
6444    public void showBootMessage(final CharSequence msg, final boolean always) {
6445        if (Binder.getCallingUid() != Process.myUid()) {
6446            // These days only the core system can call this, so apps can't get in
6447            // the way of what we show about running them.
6448        }
6449        mWindowManager.showBootMessage(msg, always);
6450    }
6451
6452    @Override
6453    public void keyguardWaitingForActivityDrawn() {
6454        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6455        final long token = Binder.clearCallingIdentity();
6456        try {
6457            synchronized (this) {
6458                if (DEBUG_LOCKSCREEN) logLockScreen("");
6459                mWindowManager.keyguardWaitingForActivityDrawn();
6460                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6461                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6462                    updateSleepIfNeededLocked();
6463                }
6464            }
6465        } finally {
6466            Binder.restoreCallingIdentity(token);
6467        }
6468    }
6469
6470    @Override
6471    public void keyguardGoingAway(boolean disableWindowAnimations,
6472            boolean keyguardGoingToNotificationShade) {
6473        enforceNotIsolatedCaller("keyguardGoingAway");
6474        final long token = Binder.clearCallingIdentity();
6475        try {
6476            synchronized (this) {
6477                if (DEBUG_LOCKSCREEN) logLockScreen("");
6478                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6479                        keyguardGoingToNotificationShade);
6480                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6481                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6482                    updateSleepIfNeededLocked();
6483                }
6484            }
6485        } finally {
6486            Binder.restoreCallingIdentity(token);
6487        }
6488    }
6489
6490    final void finishBooting() {
6491        synchronized (this) {
6492            if (!mBootAnimationComplete) {
6493                mCallFinishBooting = true;
6494                return;
6495            }
6496            mCallFinishBooting = false;
6497        }
6498
6499        ArraySet<String> completedIsas = new ArraySet<String>();
6500        for (String abi : Build.SUPPORTED_ABIS) {
6501            Process.establishZygoteConnectionForAbi(abi);
6502            final String instructionSet = VMRuntime.getInstructionSet(abi);
6503            if (!completedIsas.contains(instructionSet)) {
6504                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6505                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6506                }
6507                completedIsas.add(instructionSet);
6508            }
6509        }
6510
6511        IntentFilter pkgFilter = new IntentFilter();
6512        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6513        pkgFilter.addDataScheme("package");
6514        mContext.registerReceiver(new BroadcastReceiver() {
6515            @Override
6516            public void onReceive(Context context, Intent intent) {
6517                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6518                if (pkgs != null) {
6519                    for (String pkg : pkgs) {
6520                        synchronized (ActivityManagerService.this) {
6521                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6522                                    0, "query restart")) {
6523                                setResultCode(Activity.RESULT_OK);
6524                                return;
6525                            }
6526                        }
6527                    }
6528                }
6529            }
6530        }, pkgFilter);
6531
6532        IntentFilter dumpheapFilter = new IntentFilter();
6533        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6534        mContext.registerReceiver(new BroadcastReceiver() {
6535            @Override
6536            public void onReceive(Context context, Intent intent) {
6537                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6538                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6539                } else {
6540                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6541                }
6542            }
6543        }, dumpheapFilter);
6544
6545        // Let system services know.
6546        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6547
6548        synchronized (this) {
6549            // Ensure that any processes we had put on hold are now started
6550            // up.
6551            final int NP = mProcessesOnHold.size();
6552            if (NP > 0) {
6553                ArrayList<ProcessRecord> procs =
6554                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6555                for (int ip=0; ip<NP; ip++) {
6556                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6557                            + procs.get(ip));
6558                    startProcessLocked(procs.get(ip), "on-hold", null);
6559                }
6560            }
6561
6562            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6563                // Start looking for apps that are abusing wake locks.
6564                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6565                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6566                // Tell anyone interested that we are done booting!
6567                SystemProperties.set("sys.boot_completed", "1");
6568
6569                // And trigger dev.bootcomplete if we are not showing encryption progress
6570                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6571                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6572                    SystemProperties.set("dev.bootcomplete", "1");
6573                }
6574                mUserController.sendBootCompletedLocked(
6575                        new IIntentReceiver.Stub() {
6576                            @Override
6577                            public void performReceive(Intent intent, int resultCode,
6578                                    String data, Bundle extras, boolean ordered,
6579                                    boolean sticky, int sendingUser) {
6580                                synchronized (ActivityManagerService.this) {
6581                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6582                                            true, false);
6583                                }
6584                            }
6585                        });
6586                scheduleStartProfilesLocked();
6587            }
6588        }
6589    }
6590
6591    @Override
6592    public void bootAnimationComplete() {
6593        final boolean callFinishBooting;
6594        synchronized (this) {
6595            callFinishBooting = mCallFinishBooting;
6596            mBootAnimationComplete = true;
6597        }
6598        if (callFinishBooting) {
6599            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6600            finishBooting();
6601            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6602        }
6603    }
6604
6605    final void ensureBootCompleted() {
6606        boolean booting;
6607        boolean enableScreen;
6608        synchronized (this) {
6609            booting = mBooting;
6610            mBooting = false;
6611            enableScreen = !mBooted;
6612            mBooted = true;
6613        }
6614
6615        if (booting) {
6616            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6617            finishBooting();
6618            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6619        }
6620
6621        if (enableScreen) {
6622            enableScreenAfterBoot();
6623        }
6624    }
6625
6626    @Override
6627    public final void activityResumed(IBinder token) {
6628        final long origId = Binder.clearCallingIdentity();
6629        synchronized(this) {
6630            ActivityStack stack = ActivityRecord.getStackLocked(token);
6631            if (stack != null) {
6632                ActivityRecord.activityResumedLocked(token);
6633            }
6634        }
6635        Binder.restoreCallingIdentity(origId);
6636    }
6637
6638    @Override
6639    public final void activityPaused(IBinder token) {
6640        final long origId = Binder.clearCallingIdentity();
6641        synchronized(this) {
6642            ActivityStack stack = ActivityRecord.getStackLocked(token);
6643            if (stack != null) {
6644                stack.activityPausedLocked(token, false);
6645            }
6646        }
6647        Binder.restoreCallingIdentity(origId);
6648    }
6649
6650    @Override
6651    public final void activityStopped(IBinder token, Bundle icicle,
6652            PersistableBundle persistentState, CharSequence description) {
6653        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6654
6655        // Refuse possible leaked file descriptors
6656        if (icicle != null && icicle.hasFileDescriptors()) {
6657            throw new IllegalArgumentException("File descriptors passed in Bundle");
6658        }
6659
6660        final long origId = Binder.clearCallingIdentity();
6661
6662        synchronized (this) {
6663            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6664            if (r != null) {
6665                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6666            }
6667        }
6668
6669        trimApplications();
6670
6671        Binder.restoreCallingIdentity(origId);
6672    }
6673
6674    @Override
6675    public final void activityDestroyed(IBinder token) {
6676        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6677        synchronized (this) {
6678            ActivityStack stack = ActivityRecord.getStackLocked(token);
6679            if (stack != null) {
6680                stack.activityDestroyedLocked(token, "activityDestroyed");
6681            }
6682        }
6683    }
6684
6685    @Override
6686    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6687            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6688        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6689                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6690        synchronized (this) {
6691            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6692            if (record == null) {
6693                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6694                        + "found for: " + token);
6695            }
6696            record.setSizeConfigurations(horizontalSizeConfiguration,
6697                    verticalSizeConfigurations, smallestSizeConfigurations);
6698        }
6699    }
6700
6701    @Override
6702    public final void backgroundResourcesReleased(IBinder token) {
6703        final long origId = Binder.clearCallingIdentity();
6704        try {
6705            synchronized (this) {
6706                ActivityStack stack = ActivityRecord.getStackLocked(token);
6707                if (stack != null) {
6708                    stack.backgroundResourcesReleased();
6709                }
6710            }
6711        } finally {
6712            Binder.restoreCallingIdentity(origId);
6713        }
6714    }
6715
6716    @Override
6717    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6718        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6719    }
6720
6721    @Override
6722    public final void notifyEnterAnimationComplete(IBinder token) {
6723        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6724    }
6725
6726    @Override
6727    public String getCallingPackage(IBinder token) {
6728        synchronized (this) {
6729            ActivityRecord r = getCallingRecordLocked(token);
6730            return r != null ? r.info.packageName : null;
6731        }
6732    }
6733
6734    @Override
6735    public ComponentName getCallingActivity(IBinder token) {
6736        synchronized (this) {
6737            ActivityRecord r = getCallingRecordLocked(token);
6738            return r != null ? r.intent.getComponent() : null;
6739        }
6740    }
6741
6742    private ActivityRecord getCallingRecordLocked(IBinder token) {
6743        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6744        if (r == null) {
6745            return null;
6746        }
6747        return r.resultTo;
6748    }
6749
6750    @Override
6751    public ComponentName getActivityClassForToken(IBinder token) {
6752        synchronized(this) {
6753            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6754            if (r == null) {
6755                return null;
6756            }
6757            return r.intent.getComponent();
6758        }
6759    }
6760
6761    @Override
6762    public String getPackageForToken(IBinder token) {
6763        synchronized(this) {
6764            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6765            if (r == null) {
6766                return null;
6767            }
6768            return r.packageName;
6769        }
6770    }
6771
6772    @Override
6773    public boolean isRootVoiceInteraction(IBinder token) {
6774        synchronized(this) {
6775            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6776            if (r == null) {
6777                return false;
6778            }
6779            return r.rootVoiceInteraction;
6780        }
6781    }
6782
6783    @Override
6784    public IIntentSender getIntentSender(int type,
6785            String packageName, IBinder token, String resultWho,
6786            int requestCode, Intent[] intents, String[] resolvedTypes,
6787            int flags, Bundle bOptions, int userId) {
6788        enforceNotIsolatedCaller("getIntentSender");
6789        // Refuse possible leaked file descriptors
6790        if (intents != null) {
6791            if (intents.length < 1) {
6792                throw new IllegalArgumentException("Intents array length must be >= 1");
6793            }
6794            for (int i=0; i<intents.length; i++) {
6795                Intent intent = intents[i];
6796                if (intent != null) {
6797                    if (intent.hasFileDescriptors()) {
6798                        throw new IllegalArgumentException("File descriptors passed in Intent");
6799                    }
6800                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6801                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6802                        throw new IllegalArgumentException(
6803                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6804                    }
6805                    intents[i] = new Intent(intent);
6806                }
6807            }
6808            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6809                throw new IllegalArgumentException(
6810                        "Intent array length does not match resolvedTypes length");
6811            }
6812        }
6813        if (bOptions != null) {
6814            if (bOptions.hasFileDescriptors()) {
6815                throw new IllegalArgumentException("File descriptors passed in options");
6816            }
6817        }
6818
6819        synchronized(this) {
6820            int callingUid = Binder.getCallingUid();
6821            int origUserId = userId;
6822            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6823                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6824                    ALLOW_NON_FULL, "getIntentSender", null);
6825            if (origUserId == UserHandle.USER_CURRENT) {
6826                // We don't want to evaluate this until the pending intent is
6827                // actually executed.  However, we do want to always do the
6828                // security checking for it above.
6829                userId = UserHandle.USER_CURRENT;
6830            }
6831            try {
6832                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6833                    int uid = AppGlobals.getPackageManager()
6834                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6835                    if (!UserHandle.isSameApp(callingUid, uid)) {
6836                        String msg = "Permission Denial: getIntentSender() from pid="
6837                            + Binder.getCallingPid()
6838                            + ", uid=" + Binder.getCallingUid()
6839                            + ", (need uid=" + uid + ")"
6840                            + " is not allowed to send as package " + packageName;
6841                        Slog.w(TAG, msg);
6842                        throw new SecurityException(msg);
6843                    }
6844                }
6845
6846                return getIntentSenderLocked(type, packageName, callingUid, userId,
6847                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6848
6849            } catch (RemoteException e) {
6850                throw new SecurityException(e);
6851            }
6852        }
6853    }
6854
6855    IIntentSender getIntentSenderLocked(int type, String packageName,
6856            int callingUid, int userId, IBinder token, String resultWho,
6857            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6858            Bundle bOptions) {
6859        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6860        ActivityRecord activity = null;
6861        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6862            activity = ActivityRecord.isInStackLocked(token);
6863            if (activity == null) {
6864                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6865                return null;
6866            }
6867            if (activity.finishing) {
6868                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6869                return null;
6870            }
6871        }
6872
6873        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6874        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6875        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6876        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6877                |PendingIntent.FLAG_UPDATE_CURRENT);
6878
6879        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6880                type, packageName, activity, resultWho,
6881                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6882        WeakReference<PendingIntentRecord> ref;
6883        ref = mIntentSenderRecords.get(key);
6884        PendingIntentRecord rec = ref != null ? ref.get() : null;
6885        if (rec != null) {
6886            if (!cancelCurrent) {
6887                if (updateCurrent) {
6888                    if (rec.key.requestIntent != null) {
6889                        rec.key.requestIntent.replaceExtras(intents != null ?
6890                                intents[intents.length - 1] : null);
6891                    }
6892                    if (intents != null) {
6893                        intents[intents.length-1] = rec.key.requestIntent;
6894                        rec.key.allIntents = intents;
6895                        rec.key.allResolvedTypes = resolvedTypes;
6896                    } else {
6897                        rec.key.allIntents = null;
6898                        rec.key.allResolvedTypes = null;
6899                    }
6900                }
6901                return rec;
6902            }
6903            rec.canceled = true;
6904            mIntentSenderRecords.remove(key);
6905        }
6906        if (noCreate) {
6907            return rec;
6908        }
6909        rec = new PendingIntentRecord(this, key, callingUid);
6910        mIntentSenderRecords.put(key, rec.ref);
6911        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6912            if (activity.pendingResults == null) {
6913                activity.pendingResults
6914                        = new HashSet<WeakReference<PendingIntentRecord>>();
6915            }
6916            activity.pendingResults.add(rec.ref);
6917        }
6918        return rec;
6919    }
6920
6921    @Override
6922    public void cancelIntentSender(IIntentSender sender) {
6923        if (!(sender instanceof PendingIntentRecord)) {
6924            return;
6925        }
6926        synchronized(this) {
6927            PendingIntentRecord rec = (PendingIntentRecord)sender;
6928            try {
6929                int uid = AppGlobals.getPackageManager()
6930                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6931                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6932                    String msg = "Permission Denial: cancelIntentSender() from pid="
6933                        + Binder.getCallingPid()
6934                        + ", uid=" + Binder.getCallingUid()
6935                        + " is not allowed to cancel packges "
6936                        + rec.key.packageName;
6937                    Slog.w(TAG, msg);
6938                    throw new SecurityException(msg);
6939                }
6940            } catch (RemoteException e) {
6941                throw new SecurityException(e);
6942            }
6943            cancelIntentSenderLocked(rec, true);
6944        }
6945    }
6946
6947    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6948        rec.canceled = true;
6949        mIntentSenderRecords.remove(rec.key);
6950        if (cleanActivity && rec.key.activity != null) {
6951            rec.key.activity.pendingResults.remove(rec.ref);
6952        }
6953    }
6954
6955    @Override
6956    public String getPackageForIntentSender(IIntentSender pendingResult) {
6957        if (!(pendingResult instanceof PendingIntentRecord)) {
6958            return null;
6959        }
6960        try {
6961            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6962            return res.key.packageName;
6963        } catch (ClassCastException e) {
6964        }
6965        return null;
6966    }
6967
6968    @Override
6969    public int getUidForIntentSender(IIntentSender sender) {
6970        if (sender instanceof PendingIntentRecord) {
6971            try {
6972                PendingIntentRecord res = (PendingIntentRecord)sender;
6973                return res.uid;
6974            } catch (ClassCastException e) {
6975            }
6976        }
6977        return -1;
6978    }
6979
6980    @Override
6981    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6982        if (!(pendingResult instanceof PendingIntentRecord)) {
6983            return false;
6984        }
6985        try {
6986            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6987            if (res.key.allIntents == null) {
6988                return false;
6989            }
6990            for (int i=0; i<res.key.allIntents.length; i++) {
6991                Intent intent = res.key.allIntents[i];
6992                if (intent.getPackage() != null && intent.getComponent() != null) {
6993                    return false;
6994                }
6995            }
6996            return true;
6997        } catch (ClassCastException e) {
6998        }
6999        return false;
7000    }
7001
7002    @Override
7003    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7004        if (!(pendingResult instanceof PendingIntentRecord)) {
7005            return false;
7006        }
7007        try {
7008            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7009            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7010                return true;
7011            }
7012            return false;
7013        } catch (ClassCastException e) {
7014        }
7015        return false;
7016    }
7017
7018    @Override
7019    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7020        if (!(pendingResult instanceof PendingIntentRecord)) {
7021            return null;
7022        }
7023        try {
7024            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7025            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7026        } catch (ClassCastException e) {
7027        }
7028        return null;
7029    }
7030
7031    @Override
7032    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7033        if (!(pendingResult instanceof PendingIntentRecord)) {
7034            return null;
7035        }
7036        try {
7037            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7038            synchronized (this) {
7039                return getTagForIntentSenderLocked(res, prefix);
7040            }
7041        } catch (ClassCastException e) {
7042        }
7043        return null;
7044    }
7045
7046    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7047        final Intent intent = res.key.requestIntent;
7048        if (intent != null) {
7049            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7050                    || res.lastTagPrefix.equals(prefix))) {
7051                return res.lastTag;
7052            }
7053            res.lastTagPrefix = prefix;
7054            final StringBuilder sb = new StringBuilder(128);
7055            if (prefix != null) {
7056                sb.append(prefix);
7057            }
7058            if (intent.getAction() != null) {
7059                sb.append(intent.getAction());
7060            } else if (intent.getComponent() != null) {
7061                intent.getComponent().appendShortString(sb);
7062            } else {
7063                sb.append("?");
7064            }
7065            return res.lastTag = sb.toString();
7066        }
7067        return null;
7068    }
7069
7070    @Override
7071    public void setProcessLimit(int max) {
7072        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7073                "setProcessLimit()");
7074        synchronized (this) {
7075            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7076            mProcessLimitOverride = max;
7077        }
7078        trimApplications();
7079    }
7080
7081    @Override
7082    public int getProcessLimit() {
7083        synchronized (this) {
7084            return mProcessLimitOverride;
7085        }
7086    }
7087
7088    void foregroundTokenDied(ForegroundToken token) {
7089        synchronized (ActivityManagerService.this) {
7090            synchronized (mPidsSelfLocked) {
7091                ForegroundToken cur
7092                    = mForegroundProcesses.get(token.pid);
7093                if (cur != token) {
7094                    return;
7095                }
7096                mForegroundProcesses.remove(token.pid);
7097                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7098                if (pr == null) {
7099                    return;
7100                }
7101                pr.forcingToForeground = null;
7102                updateProcessForegroundLocked(pr, false, false);
7103            }
7104            updateOomAdjLocked();
7105        }
7106    }
7107
7108    @Override
7109    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7110        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7111                "setProcessForeground()");
7112        synchronized(this) {
7113            boolean changed = false;
7114
7115            synchronized (mPidsSelfLocked) {
7116                ProcessRecord pr = mPidsSelfLocked.get(pid);
7117                if (pr == null && isForeground) {
7118                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7119                    return;
7120                }
7121                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7122                if (oldToken != null) {
7123                    oldToken.token.unlinkToDeath(oldToken, 0);
7124                    mForegroundProcesses.remove(pid);
7125                    if (pr != null) {
7126                        pr.forcingToForeground = null;
7127                    }
7128                    changed = true;
7129                }
7130                if (isForeground && token != null) {
7131                    ForegroundToken newToken = new ForegroundToken() {
7132                        @Override
7133                        public void binderDied() {
7134                            foregroundTokenDied(this);
7135                        }
7136                    };
7137                    newToken.pid = pid;
7138                    newToken.token = token;
7139                    try {
7140                        token.linkToDeath(newToken, 0);
7141                        mForegroundProcesses.put(pid, newToken);
7142                        pr.forcingToForeground = token;
7143                        changed = true;
7144                    } catch (RemoteException e) {
7145                        // If the process died while doing this, we will later
7146                        // do the cleanup with the process death link.
7147                    }
7148                }
7149            }
7150
7151            if (changed) {
7152                updateOomAdjLocked();
7153            }
7154        }
7155    }
7156
7157    @Override
7158    public boolean inMultiWindowMode(IBinder token) {
7159        synchronized(this) {
7160            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7161            if (r == null) {
7162                return false;
7163            }
7164            // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7165            return !r.task.mFullscreen;
7166        }
7167    }
7168
7169    @Override
7170    public boolean inPictureInPictureMode(IBinder token) {
7171        synchronized(this) {
7172            final ActivityStack stack = ActivityRecord.getStackLocked(token);
7173            if (stack == null) {
7174                return false;
7175            }
7176            return stack.mStackId == PINNED_STACK_ID;
7177        }
7178    }
7179
7180    // =========================================================
7181    // PROCESS INFO
7182    // =========================================================
7183
7184    static class ProcessInfoService extends IProcessInfoService.Stub {
7185        final ActivityManagerService mActivityManagerService;
7186        ProcessInfoService(ActivityManagerService activityManagerService) {
7187            mActivityManagerService = activityManagerService;
7188        }
7189
7190        @Override
7191        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7192            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7193                    /*in*/ pids, /*out*/ states, null);
7194        }
7195
7196        @Override
7197        public void getProcessStatesAndOomScoresFromPids(
7198                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7199            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7200                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7201        }
7202    }
7203
7204    /**
7205     * For each PID in the given input array, write the current process state
7206     * for that process into the states array, or -1 to indicate that no
7207     * process with the given PID exists. If scores array is provided, write
7208     * the oom score for the process into the scores array, with INVALID_ADJ
7209     * indicating the PID doesn't exist.
7210     */
7211    public void getProcessStatesAndOomScoresForPIDs(
7212            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7213        if (scores != null) {
7214            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7215                    "getProcessStatesAndOomScoresForPIDs()");
7216        }
7217
7218        if (pids == null) {
7219            throw new NullPointerException("pids");
7220        } else if (states == null) {
7221            throw new NullPointerException("states");
7222        } else if (pids.length != states.length) {
7223            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7224        } else if (scores != null && pids.length != scores.length) {
7225            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7226        }
7227
7228        synchronized (mPidsSelfLocked) {
7229            for (int i = 0; i < pids.length; i++) {
7230                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7231                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7232                        pr.curProcState;
7233                if (scores != null) {
7234                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7235                }
7236            }
7237        }
7238    }
7239
7240    // =========================================================
7241    // PERMISSIONS
7242    // =========================================================
7243
7244    static class PermissionController extends IPermissionController.Stub {
7245        ActivityManagerService mActivityManagerService;
7246        PermissionController(ActivityManagerService activityManagerService) {
7247            mActivityManagerService = activityManagerService;
7248        }
7249
7250        @Override
7251        public boolean checkPermission(String permission, int pid, int uid) {
7252            return mActivityManagerService.checkPermission(permission, pid,
7253                    uid) == PackageManager.PERMISSION_GRANTED;
7254        }
7255
7256        @Override
7257        public String[] getPackagesForUid(int uid) {
7258            return mActivityManagerService.mContext.getPackageManager()
7259                    .getPackagesForUid(uid);
7260        }
7261
7262        @Override
7263        public boolean isRuntimePermission(String permission) {
7264            try {
7265                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7266                        .getPermissionInfo(permission, 0);
7267                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7268            } catch (NameNotFoundException nnfe) {
7269                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7270            }
7271            return false;
7272        }
7273    }
7274
7275    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7276        @Override
7277        public int checkComponentPermission(String permission, int pid, int uid,
7278                int owningUid, boolean exported) {
7279            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7280                    owningUid, exported);
7281        }
7282
7283        @Override
7284        public Object getAMSLock() {
7285            return ActivityManagerService.this;
7286        }
7287    }
7288
7289    /**
7290     * This can be called with or without the global lock held.
7291     */
7292    int checkComponentPermission(String permission, int pid, int uid,
7293            int owningUid, boolean exported) {
7294        if (pid == MY_PID) {
7295            return PackageManager.PERMISSION_GRANTED;
7296        }
7297        return ActivityManager.checkComponentPermission(permission, uid,
7298                owningUid, exported);
7299    }
7300
7301    /**
7302     * As the only public entry point for permissions checking, this method
7303     * can enforce the semantic that requesting a check on a null global
7304     * permission is automatically denied.  (Internally a null permission
7305     * string is used when calling {@link #checkComponentPermission} in cases
7306     * when only uid-based security is needed.)
7307     *
7308     * This can be called with or without the global lock held.
7309     */
7310    @Override
7311    public int checkPermission(String permission, int pid, int uid) {
7312        if (permission == null) {
7313            return PackageManager.PERMISSION_DENIED;
7314        }
7315        return checkComponentPermission(permission, pid, uid, -1, true);
7316    }
7317
7318    @Override
7319    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7320        if (permission == null) {
7321            return PackageManager.PERMISSION_DENIED;
7322        }
7323
7324        // We might be performing an operation on behalf of an indirect binder
7325        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7326        // client identity accordingly before proceeding.
7327        Identity tlsIdentity = sCallerIdentity.get();
7328        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7329            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7330                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7331            uid = tlsIdentity.uid;
7332            pid = tlsIdentity.pid;
7333        }
7334
7335        return checkComponentPermission(permission, pid, uid, -1, true);
7336    }
7337
7338    /**
7339     * Binder IPC calls go through the public entry point.
7340     * This can be called with or without the global lock held.
7341     */
7342    int checkCallingPermission(String permission) {
7343        return checkPermission(permission,
7344                Binder.getCallingPid(),
7345                UserHandle.getAppId(Binder.getCallingUid()));
7346    }
7347
7348    /**
7349     * This can be called with or without the global lock held.
7350     */
7351    void enforceCallingPermission(String permission, String func) {
7352        if (checkCallingPermission(permission)
7353                == PackageManager.PERMISSION_GRANTED) {
7354            return;
7355        }
7356
7357        String msg = "Permission Denial: " + func + " from pid="
7358                + Binder.getCallingPid()
7359                + ", uid=" + Binder.getCallingUid()
7360                + " requires " + permission;
7361        Slog.w(TAG, msg);
7362        throw new SecurityException(msg);
7363    }
7364
7365    /**
7366     * Determine if UID is holding permissions required to access {@link Uri} in
7367     * the given {@link ProviderInfo}. Final permission checking is always done
7368     * in {@link ContentProvider}.
7369     */
7370    private final boolean checkHoldingPermissionsLocked(
7371            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7372        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7373                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7374        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7375            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7376                    != PERMISSION_GRANTED) {
7377                return false;
7378            }
7379        }
7380        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7381    }
7382
7383    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7384            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7385        if (pi.applicationInfo.uid == uid) {
7386            return true;
7387        } else if (!pi.exported) {
7388            return false;
7389        }
7390
7391        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7392        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7393        try {
7394            // check if target holds top-level <provider> permissions
7395            if (!readMet && pi.readPermission != null && considerUidPermissions
7396                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7397                readMet = true;
7398            }
7399            if (!writeMet && pi.writePermission != null && considerUidPermissions
7400                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7401                writeMet = true;
7402            }
7403
7404            // track if unprotected read/write is allowed; any denied
7405            // <path-permission> below removes this ability
7406            boolean allowDefaultRead = pi.readPermission == null;
7407            boolean allowDefaultWrite = pi.writePermission == null;
7408
7409            // check if target holds any <path-permission> that match uri
7410            final PathPermission[] pps = pi.pathPermissions;
7411            if (pps != null) {
7412                final String path = grantUri.uri.getPath();
7413                int i = pps.length;
7414                while (i > 0 && (!readMet || !writeMet)) {
7415                    i--;
7416                    PathPermission pp = pps[i];
7417                    if (pp.match(path)) {
7418                        if (!readMet) {
7419                            final String pprperm = pp.getReadPermission();
7420                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7421                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7422                                    + ": match=" + pp.match(path)
7423                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7424                            if (pprperm != null) {
7425                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7426                                        == PERMISSION_GRANTED) {
7427                                    readMet = true;
7428                                } else {
7429                                    allowDefaultRead = false;
7430                                }
7431                            }
7432                        }
7433                        if (!writeMet) {
7434                            final String ppwperm = pp.getWritePermission();
7435                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7436                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7437                                    + ": match=" + pp.match(path)
7438                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7439                            if (ppwperm != null) {
7440                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7441                                        == PERMISSION_GRANTED) {
7442                                    writeMet = true;
7443                                } else {
7444                                    allowDefaultWrite = false;
7445                                }
7446                            }
7447                        }
7448                    }
7449                }
7450            }
7451
7452            // grant unprotected <provider> read/write, if not blocked by
7453            // <path-permission> above
7454            if (allowDefaultRead) readMet = true;
7455            if (allowDefaultWrite) writeMet = true;
7456
7457        } catch (RemoteException e) {
7458            return false;
7459        }
7460
7461        return readMet && writeMet;
7462    }
7463
7464    public int getAppStartMode(int uid, String packageName) {
7465        synchronized (this) {
7466            return checkAllowBackgroundLocked(uid, packageName, -1);
7467        }
7468    }
7469
7470    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid) {
7471        UidRecord uidRec = mActiveUids.get(uid);
7472        if (uidRec == null || uidRec.idle) {
7473            if (callingPid >= 0) {
7474                ProcessRecord proc;
7475                synchronized (mPidsSelfLocked) {
7476                    proc = mPidsSelfLocked.get(callingPid);
7477                }
7478                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7479                    // Whoever is instigating this is in the foreground, so we will allow it
7480                    // to go through.
7481                    return ActivityManager.APP_START_MODE_NORMAL;
7482                }
7483            }
7484            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7485                    != AppOpsManager.MODE_ALLOWED) {
7486                return ActivityManager.APP_START_MODE_DELAYED;
7487            }
7488        }
7489        return ActivityManager.APP_START_MODE_NORMAL;
7490    }
7491
7492    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7493        ProviderInfo pi = null;
7494        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7495        if (cpr != null) {
7496            pi = cpr.info;
7497        } else {
7498            try {
7499                pi = AppGlobals.getPackageManager().resolveContentProvider(
7500                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7501            } catch (RemoteException ex) {
7502            }
7503        }
7504        return pi;
7505    }
7506
7507    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7508        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7509        if (targetUris != null) {
7510            return targetUris.get(grantUri);
7511        }
7512        return null;
7513    }
7514
7515    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7516            String targetPkg, int targetUid, GrantUri grantUri) {
7517        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7518        if (targetUris == null) {
7519            targetUris = Maps.newArrayMap();
7520            mGrantedUriPermissions.put(targetUid, targetUris);
7521        }
7522
7523        UriPermission perm = targetUris.get(grantUri);
7524        if (perm == null) {
7525            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7526            targetUris.put(grantUri, perm);
7527        }
7528
7529        return perm;
7530    }
7531
7532    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7533            final int modeFlags) {
7534        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7535        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7536                : UriPermission.STRENGTH_OWNED;
7537
7538        // Root gets to do everything.
7539        if (uid == 0) {
7540            return true;
7541        }
7542
7543        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7544        if (perms == null) return false;
7545
7546        // First look for exact match
7547        final UriPermission exactPerm = perms.get(grantUri);
7548        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7549            return true;
7550        }
7551
7552        // No exact match, look for prefixes
7553        final int N = perms.size();
7554        for (int i = 0; i < N; i++) {
7555            final UriPermission perm = perms.valueAt(i);
7556            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7557                    && perm.getStrength(modeFlags) >= minStrength) {
7558                return true;
7559            }
7560        }
7561
7562        return false;
7563    }
7564
7565    /**
7566     * @param uri This uri must NOT contain an embedded userId.
7567     * @param userId The userId in which the uri is to be resolved.
7568     */
7569    @Override
7570    public int checkUriPermission(Uri uri, int pid, int uid,
7571            final int modeFlags, int userId, IBinder callerToken) {
7572        enforceNotIsolatedCaller("checkUriPermission");
7573
7574        // Another redirected-binder-call permissions check as in
7575        // {@link checkPermissionWithToken}.
7576        Identity tlsIdentity = sCallerIdentity.get();
7577        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7578            uid = tlsIdentity.uid;
7579            pid = tlsIdentity.pid;
7580        }
7581
7582        // Our own process gets to do everything.
7583        if (pid == MY_PID) {
7584            return PackageManager.PERMISSION_GRANTED;
7585        }
7586        synchronized (this) {
7587            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7588                    ? PackageManager.PERMISSION_GRANTED
7589                    : PackageManager.PERMISSION_DENIED;
7590        }
7591    }
7592
7593    /**
7594     * Check if the targetPkg can be granted permission to access uri by
7595     * the callingUid using the given modeFlags.  Throws a security exception
7596     * if callingUid is not allowed to do this.  Returns the uid of the target
7597     * if the URI permission grant should be performed; returns -1 if it is not
7598     * needed (for example targetPkg already has permission to access the URI).
7599     * If you already know the uid of the target, you can supply it in
7600     * lastTargetUid else set that to -1.
7601     */
7602    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7603            final int modeFlags, int lastTargetUid) {
7604        if (!Intent.isAccessUriMode(modeFlags)) {
7605            return -1;
7606        }
7607
7608        if (targetPkg != null) {
7609            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7610                    "Checking grant " + targetPkg + " permission to " + grantUri);
7611        }
7612
7613        final IPackageManager pm = AppGlobals.getPackageManager();
7614
7615        // If this is not a content: uri, we can't do anything with it.
7616        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7617            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7618                    "Can't grant URI permission for non-content URI: " + grantUri);
7619            return -1;
7620        }
7621
7622        final String authority = grantUri.uri.getAuthority();
7623        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7624        if (pi == null) {
7625            Slog.w(TAG, "No content provider found for permission check: " +
7626                    grantUri.uri.toSafeString());
7627            return -1;
7628        }
7629
7630        int targetUid = lastTargetUid;
7631        if (targetUid < 0 && targetPkg != null) {
7632            try {
7633                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7634                if (targetUid < 0) {
7635                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7636                            "Can't grant URI permission no uid for: " + targetPkg);
7637                    return -1;
7638                }
7639            } catch (RemoteException ex) {
7640                return -1;
7641            }
7642        }
7643
7644        if (targetUid >= 0) {
7645            // First...  does the target actually need this permission?
7646            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7647                // No need to grant the target this permission.
7648                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7649                        "Target " + targetPkg + " already has full permission to " + grantUri);
7650                return -1;
7651            }
7652        } else {
7653            // First...  there is no target package, so can anyone access it?
7654            boolean allowed = pi.exported;
7655            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7656                if (pi.readPermission != null) {
7657                    allowed = false;
7658                }
7659            }
7660            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7661                if (pi.writePermission != null) {
7662                    allowed = false;
7663                }
7664            }
7665            if (allowed) {
7666                return -1;
7667            }
7668        }
7669
7670        /* There is a special cross user grant if:
7671         * - The target is on another user.
7672         * - Apps on the current user can access the uri without any uid permissions.
7673         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7674         * grant uri permissions.
7675         */
7676        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7677                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7678                modeFlags, false /*without considering the uid permissions*/);
7679
7680        // Second...  is the provider allowing granting of URI permissions?
7681        if (!specialCrossUserGrant) {
7682            if (!pi.grantUriPermissions) {
7683                throw new SecurityException("Provider " + pi.packageName
7684                        + "/" + pi.name
7685                        + " does not allow granting of Uri permissions (uri "
7686                        + grantUri + ")");
7687            }
7688            if (pi.uriPermissionPatterns != null) {
7689                final int N = pi.uriPermissionPatterns.length;
7690                boolean allowed = false;
7691                for (int i=0; i<N; i++) {
7692                    if (pi.uriPermissionPatterns[i] != null
7693                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7694                        allowed = true;
7695                        break;
7696                    }
7697                }
7698                if (!allowed) {
7699                    throw new SecurityException("Provider " + pi.packageName
7700                            + "/" + pi.name
7701                            + " does not allow granting of permission to path of Uri "
7702                            + grantUri);
7703                }
7704            }
7705        }
7706
7707        // Third...  does the caller itself have permission to access
7708        // this uri?
7709        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7710            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7711                // Require they hold a strong enough Uri permission
7712                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7713                    throw new SecurityException("Uid " + callingUid
7714                            + " does not have permission to uri " + grantUri);
7715                }
7716            }
7717        }
7718        return targetUid;
7719    }
7720
7721    /**
7722     * @param uri This uri must NOT contain an embedded userId.
7723     * @param userId The userId in which the uri is to be resolved.
7724     */
7725    @Override
7726    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7727            final int modeFlags, int userId) {
7728        enforceNotIsolatedCaller("checkGrantUriPermission");
7729        synchronized(this) {
7730            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7731                    new GrantUri(userId, uri, false), modeFlags, -1);
7732        }
7733    }
7734
7735    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7736            final int modeFlags, UriPermissionOwner owner) {
7737        if (!Intent.isAccessUriMode(modeFlags)) {
7738            return;
7739        }
7740
7741        // So here we are: the caller has the assumed permission
7742        // to the uri, and the target doesn't.  Let's now give this to
7743        // the target.
7744
7745        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7746                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7747
7748        final String authority = grantUri.uri.getAuthority();
7749        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7750        if (pi == null) {
7751            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7752            return;
7753        }
7754
7755        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7756            grantUri.prefix = true;
7757        }
7758        final UriPermission perm = findOrCreateUriPermissionLocked(
7759                pi.packageName, targetPkg, targetUid, grantUri);
7760        perm.grantModes(modeFlags, owner);
7761    }
7762
7763    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7764            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7765        if (targetPkg == null) {
7766            throw new NullPointerException("targetPkg");
7767        }
7768        int targetUid;
7769        final IPackageManager pm = AppGlobals.getPackageManager();
7770        try {
7771            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7772        } catch (RemoteException ex) {
7773            return;
7774        }
7775
7776        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7777                targetUid);
7778        if (targetUid < 0) {
7779            return;
7780        }
7781
7782        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7783                owner);
7784    }
7785
7786    static class NeededUriGrants extends ArrayList<GrantUri> {
7787        final String targetPkg;
7788        final int targetUid;
7789        final int flags;
7790
7791        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7792            this.targetPkg = targetPkg;
7793            this.targetUid = targetUid;
7794            this.flags = flags;
7795        }
7796    }
7797
7798    /**
7799     * Like checkGrantUriPermissionLocked, but takes an Intent.
7800     */
7801    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7802            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7803        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7804                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7805                + " clip=" + (intent != null ? intent.getClipData() : null)
7806                + " from " + intent + "; flags=0x"
7807                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7808
7809        if (targetPkg == null) {
7810            throw new NullPointerException("targetPkg");
7811        }
7812
7813        if (intent == null) {
7814            return null;
7815        }
7816        Uri data = intent.getData();
7817        ClipData clip = intent.getClipData();
7818        if (data == null && clip == null) {
7819            return null;
7820        }
7821        // Default userId for uris in the intent (if they don't specify it themselves)
7822        int contentUserHint = intent.getContentUserHint();
7823        if (contentUserHint == UserHandle.USER_CURRENT) {
7824            contentUserHint = UserHandle.getUserId(callingUid);
7825        }
7826        final IPackageManager pm = AppGlobals.getPackageManager();
7827        int targetUid;
7828        if (needed != null) {
7829            targetUid = needed.targetUid;
7830        } else {
7831            try {
7832                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7833            } catch (RemoteException ex) {
7834                return null;
7835            }
7836            if (targetUid < 0) {
7837                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7838                        "Can't grant URI permission no uid for: " + targetPkg
7839                        + " on user " + targetUserId);
7840                return null;
7841            }
7842        }
7843        if (data != null) {
7844            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7845            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7846                    targetUid);
7847            if (targetUid > 0) {
7848                if (needed == null) {
7849                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7850                }
7851                needed.add(grantUri);
7852            }
7853        }
7854        if (clip != null) {
7855            for (int i=0; i<clip.getItemCount(); i++) {
7856                Uri uri = clip.getItemAt(i).getUri();
7857                if (uri != null) {
7858                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7859                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7860                            targetUid);
7861                    if (targetUid > 0) {
7862                        if (needed == null) {
7863                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7864                        }
7865                        needed.add(grantUri);
7866                    }
7867                } else {
7868                    Intent clipIntent = clip.getItemAt(i).getIntent();
7869                    if (clipIntent != null) {
7870                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7871                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7872                        if (newNeeded != null) {
7873                            needed = newNeeded;
7874                        }
7875                    }
7876                }
7877            }
7878        }
7879
7880        return needed;
7881    }
7882
7883    /**
7884     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7885     */
7886    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7887            UriPermissionOwner owner) {
7888        if (needed != null) {
7889            for (int i=0; i<needed.size(); i++) {
7890                GrantUri grantUri = needed.get(i);
7891                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7892                        grantUri, needed.flags, owner);
7893            }
7894        }
7895    }
7896
7897    void grantUriPermissionFromIntentLocked(int callingUid,
7898            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7899        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7900                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7901        if (needed == null) {
7902            return;
7903        }
7904
7905        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7906    }
7907
7908    /**
7909     * @param uri This uri must NOT contain an embedded userId.
7910     * @param userId The userId in which the uri is to be resolved.
7911     */
7912    @Override
7913    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7914            final int modeFlags, int userId) {
7915        enforceNotIsolatedCaller("grantUriPermission");
7916        GrantUri grantUri = new GrantUri(userId, uri, false);
7917        synchronized(this) {
7918            final ProcessRecord r = getRecordForAppLocked(caller);
7919            if (r == null) {
7920                throw new SecurityException("Unable to find app for caller "
7921                        + caller
7922                        + " when granting permission to uri " + grantUri);
7923            }
7924            if (targetPkg == null) {
7925                throw new IllegalArgumentException("null target");
7926            }
7927            if (grantUri == null) {
7928                throw new IllegalArgumentException("null uri");
7929            }
7930
7931            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7932                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7933                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7934                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7935
7936            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7937                    UserHandle.getUserId(r.uid));
7938        }
7939    }
7940
7941    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7942        if (perm.modeFlags == 0) {
7943            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7944                    perm.targetUid);
7945            if (perms != null) {
7946                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7947                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7948
7949                perms.remove(perm.uri);
7950                if (perms.isEmpty()) {
7951                    mGrantedUriPermissions.remove(perm.targetUid);
7952                }
7953            }
7954        }
7955    }
7956
7957    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7958        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7959                "Revoking all granted permissions to " + grantUri);
7960
7961        final IPackageManager pm = AppGlobals.getPackageManager();
7962        final String authority = grantUri.uri.getAuthority();
7963        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7964        if (pi == null) {
7965            Slog.w(TAG, "No content provider found for permission revoke: "
7966                    + grantUri.toSafeString());
7967            return;
7968        }
7969
7970        // Does the caller have this permission on the URI?
7971        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7972            // If they don't have direct access to the URI, then revoke any
7973            // ownerless URI permissions that have been granted to them.
7974            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7975            if (perms != null) {
7976                boolean persistChanged = false;
7977                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7978                    final UriPermission perm = it.next();
7979                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7980                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7981                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7982                                "Revoking non-owned " + perm.targetUid
7983                                + " permission to " + perm.uri);
7984                        persistChanged |= perm.revokeModes(
7985                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7986                        if (perm.modeFlags == 0) {
7987                            it.remove();
7988                        }
7989                    }
7990                }
7991                if (perms.isEmpty()) {
7992                    mGrantedUriPermissions.remove(callingUid);
7993                }
7994                if (persistChanged) {
7995                    schedulePersistUriGrants();
7996                }
7997            }
7998            return;
7999        }
8000
8001        boolean persistChanged = false;
8002
8003        // Go through all of the permissions and remove any that match.
8004        int N = mGrantedUriPermissions.size();
8005        for (int i = 0; i < N; i++) {
8006            final int targetUid = mGrantedUriPermissions.keyAt(i);
8007            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8008
8009            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8010                final UriPermission perm = it.next();
8011                if (perm.uri.sourceUserId == grantUri.sourceUserId
8012                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8013                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8014                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8015                    persistChanged |= perm.revokeModes(
8016                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8017                    if (perm.modeFlags == 0) {
8018                        it.remove();
8019                    }
8020                }
8021            }
8022
8023            if (perms.isEmpty()) {
8024                mGrantedUriPermissions.remove(targetUid);
8025                N--;
8026                i--;
8027            }
8028        }
8029
8030        if (persistChanged) {
8031            schedulePersistUriGrants();
8032        }
8033    }
8034
8035    /**
8036     * @param uri This uri must NOT contain an embedded userId.
8037     * @param userId The userId in which the uri is to be resolved.
8038     */
8039    @Override
8040    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8041            int userId) {
8042        enforceNotIsolatedCaller("revokeUriPermission");
8043        synchronized(this) {
8044            final ProcessRecord r = getRecordForAppLocked(caller);
8045            if (r == null) {
8046                throw new SecurityException("Unable to find app for caller "
8047                        + caller
8048                        + " when revoking permission to uri " + uri);
8049            }
8050            if (uri == null) {
8051                Slog.w(TAG, "revokeUriPermission: null uri");
8052                return;
8053            }
8054
8055            if (!Intent.isAccessUriMode(modeFlags)) {
8056                return;
8057            }
8058
8059            final String authority = uri.getAuthority();
8060            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8061            if (pi == null) {
8062                Slog.w(TAG, "No content provider found for permission revoke: "
8063                        + uri.toSafeString());
8064                return;
8065            }
8066
8067            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8068        }
8069    }
8070
8071    /**
8072     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8073     * given package.
8074     *
8075     * @param packageName Package name to match, or {@code null} to apply to all
8076     *            packages.
8077     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8078     *            to all users.
8079     * @param persistable If persistable grants should be removed.
8080     */
8081    private void removeUriPermissionsForPackageLocked(
8082            String packageName, int userHandle, boolean persistable) {
8083        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8084            throw new IllegalArgumentException("Must narrow by either package or user");
8085        }
8086
8087        boolean persistChanged = false;
8088
8089        int N = mGrantedUriPermissions.size();
8090        for (int i = 0; i < N; i++) {
8091            final int targetUid = mGrantedUriPermissions.keyAt(i);
8092            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8093
8094            // Only inspect grants matching user
8095            if (userHandle == UserHandle.USER_ALL
8096                    || userHandle == UserHandle.getUserId(targetUid)) {
8097                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8098                    final UriPermission perm = it.next();
8099
8100                    // Only inspect grants matching package
8101                    if (packageName == null || perm.sourcePkg.equals(packageName)
8102                            || perm.targetPkg.equals(packageName)) {
8103                        persistChanged |= perm.revokeModes(persistable
8104                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8105
8106                        // Only remove when no modes remain; any persisted grants
8107                        // will keep this alive.
8108                        if (perm.modeFlags == 0) {
8109                            it.remove();
8110                        }
8111                    }
8112                }
8113
8114                if (perms.isEmpty()) {
8115                    mGrantedUriPermissions.remove(targetUid);
8116                    N--;
8117                    i--;
8118                }
8119            }
8120        }
8121
8122        if (persistChanged) {
8123            schedulePersistUriGrants();
8124        }
8125    }
8126
8127    @Override
8128    public IBinder newUriPermissionOwner(String name) {
8129        enforceNotIsolatedCaller("newUriPermissionOwner");
8130        synchronized(this) {
8131            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8132            return owner.getExternalTokenLocked();
8133        }
8134    }
8135
8136    /**
8137     * @param uri This uri must NOT contain an embedded userId.
8138     * @param sourceUserId The userId in which the uri is to be resolved.
8139     * @param targetUserId The userId of the app that receives the grant.
8140     */
8141    @Override
8142    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8143            final int modeFlags, int sourceUserId, int targetUserId) {
8144        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8145                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8146                "grantUriPermissionFromOwner", null);
8147        synchronized(this) {
8148            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8149            if (owner == null) {
8150                throw new IllegalArgumentException("Unknown owner: " + token);
8151            }
8152            if (fromUid != Binder.getCallingUid()) {
8153                if (Binder.getCallingUid() != Process.myUid()) {
8154                    // Only system code can grant URI permissions on behalf
8155                    // of other users.
8156                    throw new SecurityException("nice try");
8157                }
8158            }
8159            if (targetPkg == null) {
8160                throw new IllegalArgumentException("null target");
8161            }
8162            if (uri == null) {
8163                throw new IllegalArgumentException("null uri");
8164            }
8165
8166            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8167                    modeFlags, owner, targetUserId);
8168        }
8169    }
8170
8171    /**
8172     * @param uri This uri must NOT contain an embedded userId.
8173     * @param userId The userId in which the uri is to be resolved.
8174     */
8175    @Override
8176    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8177        synchronized(this) {
8178            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8179            if (owner == null) {
8180                throw new IllegalArgumentException("Unknown owner: " + token);
8181            }
8182
8183            if (uri == null) {
8184                owner.removeUriPermissionsLocked(mode);
8185            } else {
8186                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8187            }
8188        }
8189    }
8190
8191    private void schedulePersistUriGrants() {
8192        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8193            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8194                    10 * DateUtils.SECOND_IN_MILLIS);
8195        }
8196    }
8197
8198    private void writeGrantedUriPermissions() {
8199        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8200
8201        // Snapshot permissions so we can persist without lock
8202        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8203        synchronized (this) {
8204            final int size = mGrantedUriPermissions.size();
8205            for (int i = 0; i < size; i++) {
8206                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8207                for (UriPermission perm : perms.values()) {
8208                    if (perm.persistedModeFlags != 0) {
8209                        persist.add(perm.snapshot());
8210                    }
8211                }
8212            }
8213        }
8214
8215        FileOutputStream fos = null;
8216        try {
8217            fos = mGrantFile.startWrite();
8218
8219            XmlSerializer out = new FastXmlSerializer();
8220            out.setOutput(fos, StandardCharsets.UTF_8.name());
8221            out.startDocument(null, true);
8222            out.startTag(null, TAG_URI_GRANTS);
8223            for (UriPermission.Snapshot perm : persist) {
8224                out.startTag(null, TAG_URI_GRANT);
8225                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8226                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8227                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8228                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8229                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8230                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8231                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8232                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8233                out.endTag(null, TAG_URI_GRANT);
8234            }
8235            out.endTag(null, TAG_URI_GRANTS);
8236            out.endDocument();
8237
8238            mGrantFile.finishWrite(fos);
8239        } catch (IOException e) {
8240            if (fos != null) {
8241                mGrantFile.failWrite(fos);
8242            }
8243        }
8244    }
8245
8246    private void readGrantedUriPermissionsLocked() {
8247        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8248
8249        final long now = System.currentTimeMillis();
8250
8251        FileInputStream fis = null;
8252        try {
8253            fis = mGrantFile.openRead();
8254            final XmlPullParser in = Xml.newPullParser();
8255            in.setInput(fis, StandardCharsets.UTF_8.name());
8256
8257            int type;
8258            while ((type = in.next()) != END_DOCUMENT) {
8259                final String tag = in.getName();
8260                if (type == START_TAG) {
8261                    if (TAG_URI_GRANT.equals(tag)) {
8262                        final int sourceUserId;
8263                        final int targetUserId;
8264                        final int userHandle = readIntAttribute(in,
8265                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8266                        if (userHandle != UserHandle.USER_NULL) {
8267                            // For backwards compatibility.
8268                            sourceUserId = userHandle;
8269                            targetUserId = userHandle;
8270                        } else {
8271                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8272                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8273                        }
8274                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8275                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8276                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8277                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8278                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8279                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8280
8281                        // Sanity check that provider still belongs to source package
8282                        final ProviderInfo pi = getProviderInfoLocked(
8283                                uri.getAuthority(), sourceUserId);
8284                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8285                            int targetUid = -1;
8286                            try {
8287                                targetUid = AppGlobals.getPackageManager()
8288                                        .getPackageUid(targetPkg, targetUserId);
8289                            } catch (RemoteException e) {
8290                            }
8291                            if (targetUid != -1) {
8292                                final UriPermission perm = findOrCreateUriPermissionLocked(
8293                                        sourcePkg, targetPkg, targetUid,
8294                                        new GrantUri(sourceUserId, uri, prefix));
8295                                perm.initPersistedModes(modeFlags, createdTime);
8296                            }
8297                        } else {
8298                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8299                                    + " but instead found " + pi);
8300                        }
8301                    }
8302                }
8303            }
8304        } catch (FileNotFoundException e) {
8305            // Missing grants is okay
8306        } catch (IOException e) {
8307            Slog.wtf(TAG, "Failed reading Uri grants", e);
8308        } catch (XmlPullParserException e) {
8309            Slog.wtf(TAG, "Failed reading Uri grants", e);
8310        } finally {
8311            IoUtils.closeQuietly(fis);
8312        }
8313    }
8314
8315    /**
8316     * @param uri This uri must NOT contain an embedded userId.
8317     * @param userId The userId in which the uri is to be resolved.
8318     */
8319    @Override
8320    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8321        enforceNotIsolatedCaller("takePersistableUriPermission");
8322
8323        Preconditions.checkFlagsArgument(modeFlags,
8324                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8325
8326        synchronized (this) {
8327            final int callingUid = Binder.getCallingUid();
8328            boolean persistChanged = false;
8329            GrantUri grantUri = new GrantUri(userId, uri, false);
8330
8331            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8332                    new GrantUri(userId, uri, false));
8333            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8334                    new GrantUri(userId, uri, true));
8335
8336            final boolean exactValid = (exactPerm != null)
8337                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8338            final boolean prefixValid = (prefixPerm != null)
8339                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8340
8341            if (!(exactValid || prefixValid)) {
8342                throw new SecurityException("No persistable permission grants found for UID "
8343                        + callingUid + " and Uri " + grantUri.toSafeString());
8344            }
8345
8346            if (exactValid) {
8347                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8348            }
8349            if (prefixValid) {
8350                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8351            }
8352
8353            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8354
8355            if (persistChanged) {
8356                schedulePersistUriGrants();
8357            }
8358        }
8359    }
8360
8361    /**
8362     * @param uri This uri must NOT contain an embedded userId.
8363     * @param userId The userId in which the uri is to be resolved.
8364     */
8365    @Override
8366    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8367        enforceNotIsolatedCaller("releasePersistableUriPermission");
8368
8369        Preconditions.checkFlagsArgument(modeFlags,
8370                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8371
8372        synchronized (this) {
8373            final int callingUid = Binder.getCallingUid();
8374            boolean persistChanged = false;
8375
8376            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8377                    new GrantUri(userId, uri, false));
8378            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8379                    new GrantUri(userId, uri, true));
8380            if (exactPerm == null && prefixPerm == null) {
8381                throw new SecurityException("No permission grants found for UID " + callingUid
8382                        + " and Uri " + uri.toSafeString());
8383            }
8384
8385            if (exactPerm != null) {
8386                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8387                removeUriPermissionIfNeededLocked(exactPerm);
8388            }
8389            if (prefixPerm != null) {
8390                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8391                removeUriPermissionIfNeededLocked(prefixPerm);
8392            }
8393
8394            if (persistChanged) {
8395                schedulePersistUriGrants();
8396            }
8397        }
8398    }
8399
8400    /**
8401     * Prune any older {@link UriPermission} for the given UID until outstanding
8402     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8403     *
8404     * @return if any mutations occured that require persisting.
8405     */
8406    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8407        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8408        if (perms == null) return false;
8409        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8410
8411        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8412        for (UriPermission perm : perms.values()) {
8413            if (perm.persistedModeFlags != 0) {
8414                persisted.add(perm);
8415            }
8416        }
8417
8418        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8419        if (trimCount <= 0) return false;
8420
8421        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8422        for (int i = 0; i < trimCount; i++) {
8423            final UriPermission perm = persisted.get(i);
8424
8425            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8426                    "Trimming grant created at " + perm.persistedCreateTime);
8427
8428            perm.releasePersistableModes(~0);
8429            removeUriPermissionIfNeededLocked(perm);
8430        }
8431
8432        return true;
8433    }
8434
8435    @Override
8436    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8437            String packageName, boolean incoming) {
8438        enforceNotIsolatedCaller("getPersistedUriPermissions");
8439        Preconditions.checkNotNull(packageName, "packageName");
8440
8441        final int callingUid = Binder.getCallingUid();
8442        final IPackageManager pm = AppGlobals.getPackageManager();
8443        try {
8444            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8445            if (packageUid != callingUid) {
8446                throw new SecurityException(
8447                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8448            }
8449        } catch (RemoteException e) {
8450            throw new SecurityException("Failed to verify package name ownership");
8451        }
8452
8453        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8454        synchronized (this) {
8455            if (incoming) {
8456                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8457                        callingUid);
8458                if (perms == null) {
8459                    Slog.w(TAG, "No permission grants found for " + packageName);
8460                } else {
8461                    for (UriPermission perm : perms.values()) {
8462                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8463                            result.add(perm.buildPersistedPublicApiObject());
8464                        }
8465                    }
8466                }
8467            } else {
8468                final int size = mGrantedUriPermissions.size();
8469                for (int i = 0; i < size; i++) {
8470                    final ArrayMap<GrantUri, UriPermission> perms =
8471                            mGrantedUriPermissions.valueAt(i);
8472                    for (UriPermission perm : perms.values()) {
8473                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8474                            result.add(perm.buildPersistedPublicApiObject());
8475                        }
8476                    }
8477                }
8478            }
8479        }
8480        return new ParceledListSlice<android.content.UriPermission>(result);
8481    }
8482
8483    @Override
8484    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8485        synchronized (this) {
8486            ProcessRecord app =
8487                who != null ? getRecordForAppLocked(who) : null;
8488            if (app == null) return;
8489
8490            Message msg = Message.obtain();
8491            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8492            msg.obj = app;
8493            msg.arg1 = waiting ? 1 : 0;
8494            mUiHandler.sendMessage(msg);
8495        }
8496    }
8497
8498    @Override
8499    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8500        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8501        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8502        outInfo.availMem = Process.getFreeMemory();
8503        outInfo.totalMem = Process.getTotalMemory();
8504        outInfo.threshold = homeAppMem;
8505        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8506        outInfo.hiddenAppThreshold = cachedAppMem;
8507        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8508                ProcessList.SERVICE_ADJ);
8509        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8510                ProcessList.VISIBLE_APP_ADJ);
8511        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8512                ProcessList.FOREGROUND_APP_ADJ);
8513    }
8514
8515    // =========================================================
8516    // TASK MANAGEMENT
8517    // =========================================================
8518
8519    @Override
8520    public List<IAppTask> getAppTasks(String callingPackage) {
8521        int callingUid = Binder.getCallingUid();
8522        long ident = Binder.clearCallingIdentity();
8523
8524        synchronized(this) {
8525            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8526            try {
8527                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8528
8529                final int N = mRecentTasks.size();
8530                for (int i = 0; i < N; i++) {
8531                    TaskRecord tr = mRecentTasks.get(i);
8532                    // Skip tasks that do not match the caller.  We don't need to verify
8533                    // callingPackage, because we are also limiting to callingUid and know
8534                    // that will limit to the correct security sandbox.
8535                    if (tr.effectiveUid != callingUid) {
8536                        continue;
8537                    }
8538                    Intent intent = tr.getBaseIntent();
8539                    if (intent == null ||
8540                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8541                        continue;
8542                    }
8543                    ActivityManager.RecentTaskInfo taskInfo =
8544                            createRecentTaskInfoFromTaskRecord(tr);
8545                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8546                    list.add(taskImpl);
8547                }
8548            } finally {
8549                Binder.restoreCallingIdentity(ident);
8550            }
8551            return list;
8552        }
8553    }
8554
8555    @Override
8556    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8557        final int callingUid = Binder.getCallingUid();
8558        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8559
8560        synchronized(this) {
8561            if (DEBUG_ALL) Slog.v(
8562                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8563
8564            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8565                    callingUid);
8566
8567            // TODO: Improve with MRU list from all ActivityStacks.
8568            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8569        }
8570
8571        return list;
8572    }
8573
8574    /**
8575     * Creates a new RecentTaskInfo from a TaskRecord.
8576     */
8577    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8578        // Update the task description to reflect any changes in the task stack
8579        tr.updateTaskDescription();
8580
8581        // Compose the recent task info
8582        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8583        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8584        rti.persistentId = tr.taskId;
8585        rti.baseIntent = new Intent(tr.getBaseIntent());
8586        rti.origActivity = tr.origActivity;
8587        rti.realActivity = tr.realActivity;
8588        rti.description = tr.lastDescription;
8589        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8590        rti.userId = tr.userId;
8591        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8592        rti.firstActiveTime = tr.firstActiveTime;
8593        rti.lastActiveTime = tr.lastActiveTime;
8594        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8595        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8596        rti.numActivities = 0;
8597        if (tr.mBounds != null) {
8598            rti.bounds = new Rect(tr.mBounds);
8599        }
8600
8601        ActivityRecord base = null;
8602        ActivityRecord top = null;
8603        ActivityRecord tmp;
8604
8605        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8606            tmp = tr.mActivities.get(i);
8607            if (tmp.finishing) {
8608                continue;
8609            }
8610            base = tmp;
8611            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8612                top = base;
8613            }
8614            rti.numActivities++;
8615        }
8616
8617        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8618        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8619
8620        return rti;
8621    }
8622
8623    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8624        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8625                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8626        if (!allowed) {
8627            if (checkPermission(android.Manifest.permission.GET_TASKS,
8628                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8629                // Temporary compatibility: some existing apps on the system image may
8630                // still be requesting the old permission and not switched to the new
8631                // one; if so, we'll still allow them full access.  This means we need
8632                // to see if they are holding the old permission and are a system app.
8633                try {
8634                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8635                        allowed = true;
8636                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8637                                + " is using old GET_TASKS but privileged; allowing");
8638                    }
8639                } catch (RemoteException e) {
8640                }
8641            }
8642        }
8643        if (!allowed) {
8644            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8645                    + " does not hold REAL_GET_TASKS; limiting output");
8646        }
8647        return allowed;
8648    }
8649
8650    @Override
8651    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8652        final int callingUid = Binder.getCallingUid();
8653        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8654                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8655
8656        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8657        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8658        synchronized (this) {
8659            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8660                    callingUid);
8661            final boolean detailed = checkCallingPermission(
8662                    android.Manifest.permission.GET_DETAILED_TASKS)
8663                    == PackageManager.PERMISSION_GRANTED;
8664
8665            final int recentsCount = mRecentTasks.size();
8666            ArrayList<ActivityManager.RecentTaskInfo> res =
8667                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8668
8669            final Set<Integer> includedUsers;
8670            if (includeProfiles) {
8671                includedUsers = mUserController.getProfileIds(userId);
8672            } else {
8673                includedUsers = new HashSet<>();
8674            }
8675            includedUsers.add(Integer.valueOf(userId));
8676
8677            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8678                TaskRecord tr = mRecentTasks.get(i);
8679                // Only add calling user or related users recent tasks
8680                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8681                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8682                    continue;
8683                }
8684
8685                // Return the entry if desired by the caller.  We always return
8686                // the first entry, because callers always expect this to be the
8687                // foreground app.  We may filter others if the caller has
8688                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8689                // we should exclude the entry.
8690
8691                if (i == 0
8692                        || withExcluded
8693                        || (tr.intent == null)
8694                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8695                                == 0)) {
8696                    if (!allowed) {
8697                        // If the caller doesn't have the GET_TASKS permission, then only
8698                        // allow them to see a small subset of tasks -- their own and home.
8699                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8700                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8701                            continue;
8702                        }
8703                    }
8704                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8705                        if (tr.stack != null && tr.stack.isHomeStack()) {
8706                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8707                                    "Skipping, home stack task: " + tr);
8708                            continue;
8709                        }
8710                    }
8711                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8712                        // Don't include auto remove tasks that are finished or finishing.
8713                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8714                                "Skipping, auto-remove without activity: " + tr);
8715                        continue;
8716                    }
8717                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8718                            && !tr.isAvailable) {
8719                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8720                                "Skipping, unavail real act: " + tr);
8721                        continue;
8722                    }
8723
8724                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8725                    if (!detailed) {
8726                        rti.baseIntent.replaceExtras((Bundle)null);
8727                    }
8728
8729                    res.add(rti);
8730                    maxNum--;
8731                }
8732            }
8733            return res;
8734        }
8735    }
8736
8737    @Override
8738    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8739        synchronized (this) {
8740            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8741                    "getTaskThumbnail()");
8742            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8743                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8744            if (tr != null) {
8745                return tr.getTaskThumbnailLocked();
8746            }
8747        }
8748        return null;
8749    }
8750
8751    @Override
8752    public int addAppTask(IBinder activityToken, Intent intent,
8753            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8754        final int callingUid = Binder.getCallingUid();
8755        final long callingIdent = Binder.clearCallingIdentity();
8756
8757        try {
8758            synchronized (this) {
8759                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8760                if (r == null) {
8761                    throw new IllegalArgumentException("Activity does not exist; token="
8762                            + activityToken);
8763                }
8764                ComponentName comp = intent.getComponent();
8765                if (comp == null) {
8766                    throw new IllegalArgumentException("Intent " + intent
8767                            + " must specify explicit component");
8768                }
8769                if (thumbnail.getWidth() != mThumbnailWidth
8770                        || thumbnail.getHeight() != mThumbnailHeight) {
8771                    throw new IllegalArgumentException("Bad thumbnail size: got "
8772                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8773                            + mThumbnailWidth + "x" + mThumbnailHeight);
8774                }
8775                if (intent.getSelector() != null) {
8776                    intent.setSelector(null);
8777                }
8778                if (intent.getSourceBounds() != null) {
8779                    intent.setSourceBounds(null);
8780                }
8781                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8782                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8783                        // The caller has added this as an auto-remove task...  that makes no
8784                        // sense, so turn off auto-remove.
8785                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8786                    }
8787                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8788                    // Must be a new task.
8789                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8790                }
8791                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8792                    mLastAddedTaskActivity = null;
8793                }
8794                ActivityInfo ainfo = mLastAddedTaskActivity;
8795                if (ainfo == null) {
8796                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8797                            comp, 0, UserHandle.getUserId(callingUid));
8798                    if (ainfo.applicationInfo.uid != callingUid) {
8799                        throw new SecurityException(
8800                                "Can't add task for another application: target uid="
8801                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8802                    }
8803                }
8804
8805                // Use the full screen as the context for the task thumbnail
8806                final Point displaySize = new Point();
8807                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
8808                r.task.stack.getDisplaySize(displaySize);
8809                thumbnailInfo.taskWidth = displaySize.x;
8810                thumbnailInfo.taskHeight = displaySize.y;
8811                thumbnailInfo.screenOrientation = mConfiguration.orientation;
8812
8813                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8814                        intent, description, thumbnailInfo);
8815
8816                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8817                if (trimIdx >= 0) {
8818                    // If this would have caused a trim, then we'll abort because that
8819                    // means it would be added at the end of the list but then just removed.
8820                    return INVALID_TASK_ID;
8821                }
8822
8823                final int N = mRecentTasks.size();
8824                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8825                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8826                    tr.removedFromRecents();
8827                }
8828
8829                task.inRecents = true;
8830                mRecentTasks.add(task);
8831                r.task.stack.addTask(task, false, "addAppTask");
8832
8833                task.setLastThumbnailLocked(thumbnail);
8834                task.freeLastThumbnail();
8835
8836                return task.taskId;
8837            }
8838        } finally {
8839            Binder.restoreCallingIdentity(callingIdent);
8840        }
8841    }
8842
8843    @Override
8844    public Point getAppTaskThumbnailSize() {
8845        synchronized (this) {
8846            return new Point(mThumbnailWidth,  mThumbnailHeight);
8847        }
8848    }
8849
8850    @Override
8851    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8852        synchronized (this) {
8853            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8854            if (r != null) {
8855                r.setTaskDescription(td);
8856                r.task.updateTaskDescription();
8857            }
8858        }
8859    }
8860
8861    @Override
8862    public void setTaskResizeable(int taskId, boolean resizeable) {
8863        synchronized (this) {
8864            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
8865                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8866            if (task == null) {
8867                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8868                return;
8869            }
8870            if (task.mResizeable != resizeable) {
8871                task.mResizeable = resizeable;
8872                mWindowManager.setTaskResizeable(taskId, resizeable);
8873                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
8874                mStackSupervisor.resumeTopActivitiesLocked();
8875            }
8876        }
8877    }
8878
8879    @Override
8880    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
8881        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8882                "resizeTask()");
8883        long ident = Binder.clearCallingIdentity();
8884        try {
8885            synchronized (this) {
8886                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8887                if (task == null) {
8888                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8889                    return;
8890                }
8891                int stackId = task.stack.mStackId;
8892                // First, check if this is a non-resizeble task in docked stack or if the task size
8893                // is affected by the docked stack changing size. If so, instead of resizing, we
8894                // can only scroll the task. No need to update configuration.
8895                if (bounds != null && !task.mResizeable
8896                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
8897                    mWindowManager.scrollTask(task.taskId, bounds);
8898                    return;
8899                }
8900
8901                // Place the task in the right stack if it isn't there already based on
8902                // the requested bounds.
8903                // The stack transition logic is:
8904                // - a null bounds on a freeform task moves that task to fullscreen
8905                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
8906                //   that task to freeform
8907                // - otherwise the task is not moved
8908                if (!StackId.isTaskResizeAllowed(stackId)) {
8909                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
8910                }
8911                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
8912                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
8913                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
8914                    stackId = FREEFORM_WORKSPACE_STACK_ID;
8915                }
8916                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
8917                if (stackId != task.stack.mStackId) {
8918                    mStackSupervisor.moveTaskToStackUncheckedLocked(
8919                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
8920                    preserveWindow = false;
8921                }
8922
8923                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow);
8924            }
8925        } finally {
8926            Binder.restoreCallingIdentity(ident);
8927        }
8928    }
8929
8930    @Override
8931    public Rect getTaskBounds(int taskId) {
8932        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8933                "getTaskBounds()");
8934        long ident = Binder.clearCallingIdentity();
8935        Rect rect = new Rect();
8936        try {
8937            synchronized (this) {
8938                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
8939                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8940                if (task == null) {
8941                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
8942                    return rect;
8943                }
8944                if (task.stack != null) {
8945                    // Return the bounds from window manager since it will be adjusted for various
8946                    // things like the presense of a docked stack for tasks that aren't resizeable.
8947                    mWindowManager.getTaskBounds(task.taskId, rect);
8948                } else {
8949                    // Task isn't in window manager yet since it isn't associated with a stack.
8950                    // Return the persist value from activity manager
8951                    if (task.mBounds != null) {
8952                        rect.set(task.mBounds);
8953                    } else if (task.mLastNonFullscreenBounds != null) {
8954                        rect.set(task.mLastNonFullscreenBounds);
8955                    }
8956                }
8957            }
8958        } finally {
8959            Binder.restoreCallingIdentity(ident);
8960        }
8961        return rect;
8962    }
8963
8964    @Override
8965    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
8966        if (userId != UserHandle.getCallingUserId()) {
8967            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8968                    "getTaskDescriptionIcon");
8969        }
8970        final File passedIconFile = new File(filePath);
8971        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
8972                passedIconFile.getName());
8973        if (!legitIconFile.getPath().equals(filePath)
8974                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8975            throw new IllegalArgumentException("Bad file path: " + filePath);
8976        }
8977        return mTaskPersister.getTaskDescriptionIcon(filePath);
8978    }
8979
8980    @Override
8981    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8982            throws RemoteException {
8983        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8984                opts.getCustomInPlaceResId() == 0) {
8985            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8986                    "with valid animation");
8987        }
8988        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8989        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8990                opts.getCustomInPlaceResId());
8991        mWindowManager.executeAppTransition();
8992    }
8993
8994    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
8995            boolean removeFromRecents) {
8996        if (removeFromRecents) {
8997            mRecentTasks.remove(tr);
8998            tr.removedFromRecents();
8999        }
9000        ComponentName component = tr.getBaseIntent().getComponent();
9001        if (component == null) {
9002            Slog.w(TAG, "No component for base intent of task: " + tr);
9003            return;
9004        }
9005
9006        // Find any running services associated with this app and stop if needed.
9007        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9008
9009        if (!killProcess) {
9010            return;
9011        }
9012
9013        // Determine if the process(es) for this task should be killed.
9014        final String pkg = component.getPackageName();
9015        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9016        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9017        for (int i = 0; i < pmap.size(); i++) {
9018
9019            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9020            for (int j = 0; j < uids.size(); j++) {
9021                ProcessRecord proc = uids.valueAt(j);
9022                if (proc.userId != tr.userId) {
9023                    // Don't kill process for a different user.
9024                    continue;
9025                }
9026                if (proc == mHomeProcess) {
9027                    // Don't kill the home process along with tasks from the same package.
9028                    continue;
9029                }
9030                if (!proc.pkgList.containsKey(pkg)) {
9031                    // Don't kill process that is not associated with this task.
9032                    continue;
9033                }
9034
9035                for (int k = 0; k < proc.activities.size(); k++) {
9036                    TaskRecord otherTask = proc.activities.get(k).task;
9037                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9038                        // Don't kill process(es) that has an activity in a different task that is
9039                        // also in recents.
9040                        return;
9041                    }
9042                }
9043
9044                if (proc.foregroundServices) {
9045                    // Don't kill process(es) with foreground service.
9046                    return;
9047                }
9048
9049                // Add process to kill list.
9050                procsToKill.add(proc);
9051            }
9052        }
9053
9054        // Kill the running processes.
9055        for (int i = 0; i < procsToKill.size(); i++) {
9056            ProcessRecord pr = procsToKill.get(i);
9057            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
9058                    && pr.curReceiver == null) {
9059                pr.kill("remove task", true);
9060            } else {
9061                // We delay killing processes that are not in the background or running a receiver.
9062                pr.waitingToKill = "remove task";
9063            }
9064        }
9065    }
9066
9067    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9068        // Remove all tasks with activities in the specified package from the list of recent tasks
9069        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9070            TaskRecord tr = mRecentTasks.get(i);
9071            if (tr.userId != userId) continue;
9072
9073            ComponentName cn = tr.intent.getComponent();
9074            if (cn != null && cn.getPackageName().equals(packageName)) {
9075                // If the package name matches, remove the task.
9076                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9077            }
9078        }
9079    }
9080
9081    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9082            int userId) {
9083
9084        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9085            TaskRecord tr = mRecentTasks.get(i);
9086            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9087                continue;
9088            }
9089
9090            ComponentName cn = tr.intent.getComponent();
9091            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9092                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9093            if (sameComponent) {
9094                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9095            }
9096        }
9097    }
9098
9099    /**
9100     * Removes the task with the specified task id.
9101     *
9102     * @param taskId Identifier of the task to be removed.
9103     * @param killProcess Kill any process associated with the task if possible.
9104     * @param removeFromRecents Whether to also remove the task from recents.
9105     * @return Returns true if the given task was found and removed.
9106     */
9107    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9108            boolean removeFromRecents) {
9109        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9110                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9111        if (tr != null) {
9112            tr.removeTaskActivitiesLocked();
9113            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9114            if (tr.isPersistable) {
9115                notifyTaskPersisterLocked(null, true);
9116            }
9117            return true;
9118        }
9119        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9120        return false;
9121    }
9122
9123    @Override
9124    public boolean removeTask(int taskId) {
9125        synchronized (this) {
9126            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
9127                    "removeTask()");
9128            long ident = Binder.clearCallingIdentity();
9129            try {
9130                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9131            } finally {
9132                Binder.restoreCallingIdentity(ident);
9133            }
9134        }
9135    }
9136
9137    /**
9138     * TODO: Add mController hook
9139     */
9140    @Override
9141    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9142        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9143
9144        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9145        synchronized(this) {
9146            moveTaskToFrontLocked(taskId, flags, bOptions);
9147        }
9148    }
9149
9150    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9151        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9152
9153        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9154                Binder.getCallingUid(), -1, -1, "Task to front")) {
9155            ActivityOptions.abort(options);
9156            return;
9157        }
9158        final long origId = Binder.clearCallingIdentity();
9159        try {
9160            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9161            if (task == null) {
9162                Slog.d(TAG, "Could not find task for id: "+ taskId);
9163                return;
9164            }
9165            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9166                mStackSupervisor.showLockTaskToast();
9167                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9168                return;
9169            }
9170            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9171            if (prev != null && prev.isRecentsActivity()) {
9172                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9173            }
9174            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
9175        } finally {
9176            Binder.restoreCallingIdentity(origId);
9177        }
9178        ActivityOptions.abort(options);
9179    }
9180
9181    /**
9182     * Moves an activity, and all of the other activities within the same task, to the bottom
9183     * of the history stack.  The activity's order within the task is unchanged.
9184     *
9185     * @param token A reference to the activity we wish to move
9186     * @param nonRoot If false then this only works if the activity is the root
9187     *                of a task; if true it will work for any activity in a task.
9188     * @return Returns true if the move completed, false if not.
9189     */
9190    @Override
9191    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9192        enforceNotIsolatedCaller("moveActivityTaskToBack");
9193        synchronized(this) {
9194            final long origId = Binder.clearCallingIdentity();
9195            try {
9196                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9197                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9198                if (task != null) {
9199                    if (mStackSupervisor.isLockedTask(task)) {
9200                        mStackSupervisor.showLockTaskToast();
9201                        return false;
9202                    }
9203                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9204                }
9205            } finally {
9206                Binder.restoreCallingIdentity(origId);
9207            }
9208        }
9209        return false;
9210    }
9211
9212    @Override
9213    public void moveTaskBackwards(int task) {
9214        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9215                "moveTaskBackwards()");
9216
9217        synchronized(this) {
9218            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9219                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9220                return;
9221            }
9222            final long origId = Binder.clearCallingIdentity();
9223            moveTaskBackwardsLocked(task);
9224            Binder.restoreCallingIdentity(origId);
9225        }
9226    }
9227
9228    private final void moveTaskBackwardsLocked(int task) {
9229        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9230    }
9231
9232    @Override
9233    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9234            IActivityContainerCallback callback) throws RemoteException {
9235        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9236                "createActivityContainer()");
9237        synchronized (this) {
9238            if (parentActivityToken == null) {
9239                throw new IllegalArgumentException("parent token must not be null");
9240            }
9241            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9242            if (r == null) {
9243                return null;
9244            }
9245            if (callback == null) {
9246                throw new IllegalArgumentException("callback must not be null");
9247            }
9248            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9249        }
9250    }
9251
9252    @Override
9253    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9254        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9255                "deleteActivityContainer()");
9256        synchronized (this) {
9257            mStackSupervisor.deleteActivityContainer(container);
9258        }
9259    }
9260
9261    @Override
9262    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9263        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9264                "createStackOnDisplay()");
9265        synchronized (this) {
9266            final int stackId = mStackSupervisor.getNextStackId();
9267            final ActivityStack stack =
9268                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9269            if (stack == null) {
9270                return null;
9271            }
9272            return stack.mActivityContainer;
9273        }
9274    }
9275
9276    @Override
9277    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9278        synchronized (this) {
9279            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9280            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9281                return stack.mActivityContainer.getDisplayId();
9282            }
9283            return Display.DEFAULT_DISPLAY;
9284        }
9285    }
9286
9287    @Override
9288    public int getActivityStackId(IBinder token) throws RemoteException {
9289        synchronized (this) {
9290            ActivityStack stack = ActivityRecord.getStackLocked(token);
9291            if (stack == null) {
9292                return INVALID_STACK_ID;
9293            }
9294            return stack.mStackId;
9295        }
9296    }
9297
9298    @Override
9299    public void moveActivityToStack(IBinder token, int stackId) throws RemoteException {
9300        if (stackId == HOME_STACK_ID) {
9301            throw new IllegalArgumentException(
9302                    "moveActivityToStack: Attempt to move token " + token + " to home stack");
9303        }
9304        synchronized (this) {
9305            long ident = Binder.clearCallingIdentity();
9306            try {
9307                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9308                if (r == null) {
9309                    throw new IllegalArgumentException(
9310                            "moveActivityToStack: No activity record matching token=" + token);
9311                }
9312                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveActivityToStack: moving r=" + r
9313                        + " to stackId=" + stackId);
9314                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, stackId, ON_TOP, !FORCE_FOCUS,
9315                        "moveActivityToStack", true /* animate */);
9316            } finally {
9317                Binder.restoreCallingIdentity(ident);
9318            }
9319        }
9320    }
9321
9322    @Override
9323    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9324        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9325                "moveTaskToStack()");
9326        if (stackId == HOME_STACK_ID) {
9327            throw new IllegalArgumentException(
9328                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9329        }
9330        synchronized (this) {
9331            long ident = Binder.clearCallingIdentity();
9332            try {
9333                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9334                        + " to stackId=" + stackId + " toTop=" + toTop);
9335                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9336                        "moveTaskToStack", true /* animate */);
9337            } finally {
9338                Binder.restoreCallingIdentity(ident);
9339            }
9340        }
9341    }
9342
9343    /**
9344     * Moves the input task to the docked stack.
9345     *
9346     * @param taskId Id of task to move.
9347     * @param createMode The mode the docked stack should be created in if it doesn't exist
9348     *                   already. See
9349     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9350     *                   and
9351     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9352     * @param toTop If the task and stack should be moved to the top.
9353     * @param animate Whether we should play an animation for the moving the task
9354     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9355     *                      docked stack. Pass {@code null} to use default bounds.
9356     */
9357    @Override
9358    public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9359            Rect initialBounds) {
9360        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9361                "moveTaskToDockedStack()");
9362        synchronized (this) {
9363            long ident = Binder.clearCallingIdentity();
9364            try {
9365                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9366                        + " to createMode=" + createMode + " toTop=" + toTop);
9367                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9368                mStackSupervisor.moveTaskToStackLocked(taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9369                        "moveTaskToDockedStack", animate);
9370            } finally {
9371                Binder.restoreCallingIdentity(ident);
9372            }
9373        }
9374    }
9375
9376    /**
9377     * Moves the top activity in the input stackId to the pinned stack.
9378     *
9379     * @param stackId Id of stack to move the top activity to pinned stack.
9380     * @param bounds Bounds to use for pinned stack.
9381     *
9382     * @return True if the top activity of the input stack was successfully moved to the pinned
9383     *          stack.
9384     */
9385    @Override
9386    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9387        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9388                "moveTopActivityToPinnedStack()");
9389        synchronized (this) {
9390            long ident = Binder.clearCallingIdentity();
9391            try {
9392                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9393            } finally {
9394                Binder.restoreCallingIdentity(ident);
9395            }
9396        }
9397    }
9398
9399    @Override
9400    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode) {
9401        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9402                "resizeStack()");
9403        long ident = Binder.clearCallingIdentity();
9404        try {
9405            synchronized (this) {
9406                mStackSupervisor.resizeStackLocked(
9407                        stackId, bounds, !PRESERVE_WINDOWS, allowResizeInDockedMode);
9408            }
9409        } finally {
9410            Binder.restoreCallingIdentity(ident);
9411        }
9412    }
9413
9414    @Override
9415    public void positionTaskInStack(int taskId, int stackId, int position) {
9416        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9417                "positionTaskInStack()");
9418        if (stackId == HOME_STACK_ID) {
9419            throw new IllegalArgumentException(
9420                    "positionTaskInStack: Attempt to change the position of task "
9421                    + taskId + " in/to home stack");
9422        }
9423        synchronized (this) {
9424            long ident = Binder.clearCallingIdentity();
9425            try {
9426                if (DEBUG_STACK) Slog.d(TAG_STACK,
9427                        "positionTaskInStack: positioning task=" + taskId
9428                        + " in stackId=" + stackId + " at position=" + position);
9429                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9430            } finally {
9431                Binder.restoreCallingIdentity(ident);
9432            }
9433        }
9434    }
9435
9436    @Override
9437    public List<StackInfo> getAllStackInfos() {
9438        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9439                "getAllStackInfos()");
9440        long ident = Binder.clearCallingIdentity();
9441        try {
9442            synchronized (this) {
9443                return mStackSupervisor.getAllStackInfosLocked();
9444            }
9445        } finally {
9446            Binder.restoreCallingIdentity(ident);
9447        }
9448    }
9449
9450    @Override
9451    public StackInfo getStackInfo(int stackId) {
9452        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9453                "getStackInfo()");
9454        long ident = Binder.clearCallingIdentity();
9455        try {
9456            synchronized (this) {
9457                return mStackSupervisor.getStackInfoLocked(stackId);
9458            }
9459        } finally {
9460            Binder.restoreCallingIdentity(ident);
9461        }
9462    }
9463
9464    @Override
9465    public boolean isInHomeStack(int taskId) {
9466        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9467                "getStackInfo()");
9468        long ident = Binder.clearCallingIdentity();
9469        try {
9470            synchronized (this) {
9471                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9472                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9473                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9474            }
9475        } finally {
9476            Binder.restoreCallingIdentity(ident);
9477        }
9478    }
9479
9480    @Override
9481    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9482        synchronized(this) {
9483            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9484        }
9485    }
9486
9487    @Override
9488    public void updateDeviceOwner(String packageName) {
9489        final int callingUid = Binder.getCallingUid();
9490        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9491            throw new SecurityException("updateDeviceOwner called from non-system process");
9492        }
9493        synchronized (this) {
9494            mDeviceOwnerName = packageName;
9495        }
9496    }
9497
9498    @Override
9499    public void updateLockTaskPackages(int userId, String[] packages) {
9500        final int callingUid = Binder.getCallingUid();
9501        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9502            throw new SecurityException("updateLockTaskPackage called from non-system process");
9503        }
9504        synchronized (this) {
9505            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9506                    Arrays.toString(packages));
9507            mLockTaskPackages.put(userId, packages);
9508            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9509        }
9510    }
9511
9512
9513    void startLockTaskModeLocked(TaskRecord task) {
9514        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9515        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9516            return;
9517        }
9518
9519        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9520        // is initiated by system after the pinning request was shown and locked mode is initiated
9521        // by an authorized app directly
9522        final int callingUid = Binder.getCallingUid();
9523        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9524        long ident = Binder.clearCallingIdentity();
9525        try {
9526            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9527            if (!isSystemInitiated) {
9528                task.mLockTaskUid = callingUid;
9529                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9530                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9531                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9532                    StatusBarManagerInternal statusBarManager =
9533                            LocalServices.getService(StatusBarManagerInternal.class);
9534                    if (statusBarManager != null) {
9535                        statusBarManager.showScreenPinningRequest();
9536                    }
9537                    return;
9538                }
9539
9540                if (stack == null || task != stack.topTask()) {
9541                    throw new IllegalArgumentException("Invalid task, not in foreground");
9542                }
9543            }
9544            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9545                    "Locking fully");
9546            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9547                    ActivityManager.LOCK_TASK_MODE_PINNED :
9548                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9549                    "startLockTask", true);
9550        } finally {
9551            Binder.restoreCallingIdentity(ident);
9552        }
9553    }
9554
9555    @Override
9556    public void startLockTaskMode(int taskId) {
9557        synchronized (this) {
9558            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9559            if (task != null) {
9560                startLockTaskModeLocked(task);
9561            }
9562        }
9563    }
9564
9565    @Override
9566    public void startLockTaskMode(IBinder token) {
9567        synchronized (this) {
9568            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9569            if (r == null) {
9570                return;
9571            }
9572            final TaskRecord task = r.task;
9573            if (task != null) {
9574                startLockTaskModeLocked(task);
9575            }
9576        }
9577    }
9578
9579    @Override
9580    public void startLockTaskModeOnCurrent() throws RemoteException {
9581        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9582                "startLockTaskModeOnCurrent");
9583        long ident = Binder.clearCallingIdentity();
9584        try {
9585            synchronized (this) {
9586                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9587                if (r != null) {
9588                    startLockTaskModeLocked(r.task);
9589                }
9590            }
9591        } finally {
9592            Binder.restoreCallingIdentity(ident);
9593        }
9594    }
9595
9596    @Override
9597    public void stopLockTaskMode() {
9598        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9599        if (lockTask == null) {
9600            // Our work here is done.
9601            return;
9602        }
9603
9604        final int callingUid = Binder.getCallingUid();
9605        final int lockTaskUid = lockTask.mLockTaskUid;
9606        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9607        // It is possible lockTaskMode was started by the system process because
9608        // android:lockTaskMode is set to a locking value in the application manifest instead of
9609        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9610        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9611        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9612                callingUid != lockTaskUid
9613                && (lockTaskUid != 0
9614                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9615            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9616                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9617        }
9618
9619        long ident = Binder.clearCallingIdentity();
9620        try {
9621            Log.d(TAG, "stopLockTaskMode");
9622            // Stop lock task
9623            synchronized (this) {
9624                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9625                        "stopLockTask", true);
9626            }
9627        } finally {
9628            Binder.restoreCallingIdentity(ident);
9629        }
9630    }
9631
9632    @Override
9633    public void stopLockTaskModeOnCurrent() throws RemoteException {
9634        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9635                "stopLockTaskModeOnCurrent");
9636        long ident = Binder.clearCallingIdentity();
9637        try {
9638            stopLockTaskMode();
9639        } finally {
9640            Binder.restoreCallingIdentity(ident);
9641        }
9642    }
9643
9644    @Override
9645    public boolean isInLockTaskMode() {
9646        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9647    }
9648
9649    @Override
9650    public int getLockTaskModeState() {
9651        synchronized (this) {
9652            return mStackSupervisor.getLockTaskModeState();
9653        }
9654    }
9655
9656    @Override
9657    public void showLockTaskEscapeMessage(IBinder token) {
9658        synchronized (this) {
9659            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9660            if (r == null) {
9661                return;
9662            }
9663            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9664        }
9665    }
9666
9667    // =========================================================
9668    // CONTENT PROVIDERS
9669    // =========================================================
9670
9671    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9672        List<ProviderInfo> providers = null;
9673        try {
9674            ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
9675                queryContentProviders(app.processName, app.uid,
9676                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9677            providers = slice != null ? slice.getList() : null;
9678        } catch (RemoteException ex) {
9679        }
9680        if (DEBUG_MU) Slog.v(TAG_MU,
9681                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9682        int userId = app.userId;
9683        if (providers != null) {
9684            int N = providers.size();
9685            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9686            for (int i=0; i<N; i++) {
9687                ProviderInfo cpi =
9688                    (ProviderInfo)providers.get(i);
9689                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9690                        cpi.name, cpi.flags);
9691                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
9692                    // This is a singleton provider, but a user besides the
9693                    // default user is asking to initialize a process it runs
9694                    // in...  well, no, it doesn't actually run in this process,
9695                    // it runs in the process of the default user.  Get rid of it.
9696                    providers.remove(i);
9697                    N--;
9698                    i--;
9699                    continue;
9700                }
9701
9702                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9703                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9704                if (cpr == null) {
9705                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9706                    mProviderMap.putProviderByClass(comp, cpr);
9707                }
9708                if (DEBUG_MU) Slog.v(TAG_MU,
9709                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9710                app.pubProviders.put(cpi.name, cpr);
9711                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9712                    // Don't add this if it is a platform component that is marked
9713                    // to run in multiple processes, because this is actually
9714                    // part of the framework so doesn't make sense to track as a
9715                    // separate apk in the process.
9716                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9717                            mProcessStats);
9718                }
9719                notifyPackageUse(cpi.applicationInfo.packageName);
9720            }
9721        }
9722        return providers;
9723    }
9724
9725    /**
9726     * Check if {@link ProcessRecord} has a possible chance at accessing the
9727     * given {@link ProviderInfo}. Final permission checking is always done
9728     * in {@link ContentProvider}.
9729     */
9730    private final String checkContentProviderPermissionLocked(
9731            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9732        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9733        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9734        boolean checkedGrants = false;
9735        if (checkUser) {
9736            // Looking for cross-user grants before enforcing the typical cross-users permissions
9737            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
9738            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9739                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9740                    return null;
9741                }
9742                checkedGrants = true;
9743            }
9744            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
9745                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
9746            if (userId != tmpTargetUserId) {
9747                // When we actually went to determine the final targer user ID, this ended
9748                // up different than our initial check for the authority.  This is because
9749                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9750                // SELF.  So we need to re-check the grants again.
9751                checkedGrants = false;
9752            }
9753        }
9754        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9755                cpi.applicationInfo.uid, cpi.exported)
9756                == PackageManager.PERMISSION_GRANTED) {
9757            return null;
9758        }
9759        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9760                cpi.applicationInfo.uid, cpi.exported)
9761                == PackageManager.PERMISSION_GRANTED) {
9762            return null;
9763        }
9764
9765        PathPermission[] pps = cpi.pathPermissions;
9766        if (pps != null) {
9767            int i = pps.length;
9768            while (i > 0) {
9769                i--;
9770                PathPermission pp = pps[i];
9771                String pprperm = pp.getReadPermission();
9772                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9773                        cpi.applicationInfo.uid, cpi.exported)
9774                        == PackageManager.PERMISSION_GRANTED) {
9775                    return null;
9776                }
9777                String ppwperm = pp.getWritePermission();
9778                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9779                        cpi.applicationInfo.uid, cpi.exported)
9780                        == PackageManager.PERMISSION_GRANTED) {
9781                    return null;
9782                }
9783            }
9784        }
9785        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9786            return null;
9787        }
9788
9789        String msg;
9790        if (!cpi.exported) {
9791            msg = "Permission Denial: opening provider " + cpi.name
9792                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9793                    + ", uid=" + callingUid + ") that is not exported from uid "
9794                    + cpi.applicationInfo.uid;
9795        } else {
9796            msg = "Permission Denial: opening provider " + cpi.name
9797                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9798                    + ", uid=" + callingUid + ") requires "
9799                    + cpi.readPermission + " or " + cpi.writePermission;
9800        }
9801        Slog.w(TAG, msg);
9802        return msg;
9803    }
9804
9805    /**
9806     * Returns if the ContentProvider has granted a uri to callingUid
9807     */
9808    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9809        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9810        if (perms != null) {
9811            for (int i=perms.size()-1; i>=0; i--) {
9812                GrantUri grantUri = perms.keyAt(i);
9813                if (grantUri.sourceUserId == userId || !checkUser) {
9814                    if (matchesProvider(grantUri.uri, cpi)) {
9815                        return true;
9816                    }
9817                }
9818            }
9819        }
9820        return false;
9821    }
9822
9823    /**
9824     * Returns true if the uri authority is one of the authorities specified in the provider.
9825     */
9826    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9827        String uriAuth = uri.getAuthority();
9828        String cpiAuth = cpi.authority;
9829        if (cpiAuth.indexOf(';') == -1) {
9830            return cpiAuth.equals(uriAuth);
9831        }
9832        String[] cpiAuths = cpiAuth.split(";");
9833        int length = cpiAuths.length;
9834        for (int i = 0; i < length; i++) {
9835            if (cpiAuths[i].equals(uriAuth)) return true;
9836        }
9837        return false;
9838    }
9839
9840    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9841            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9842        if (r != null) {
9843            for (int i=0; i<r.conProviders.size(); i++) {
9844                ContentProviderConnection conn = r.conProviders.get(i);
9845                if (conn.provider == cpr) {
9846                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9847                            "Adding provider requested by "
9848                            + r.processName + " from process "
9849                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9850                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9851                    if (stable) {
9852                        conn.stableCount++;
9853                        conn.numStableIncs++;
9854                    } else {
9855                        conn.unstableCount++;
9856                        conn.numUnstableIncs++;
9857                    }
9858                    return conn;
9859                }
9860            }
9861            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9862            if (stable) {
9863                conn.stableCount = 1;
9864                conn.numStableIncs = 1;
9865            } else {
9866                conn.unstableCount = 1;
9867                conn.numUnstableIncs = 1;
9868            }
9869            cpr.connections.add(conn);
9870            r.conProviders.add(conn);
9871            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9872            return conn;
9873        }
9874        cpr.addExternalProcessHandleLocked(externalProcessToken);
9875        return null;
9876    }
9877
9878    boolean decProviderCountLocked(ContentProviderConnection conn,
9879            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9880        if (conn != null) {
9881            cpr = conn.provider;
9882            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9883                    "Removing provider requested by "
9884                    + conn.client.processName + " from process "
9885                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9886                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9887            if (stable) {
9888                conn.stableCount--;
9889            } else {
9890                conn.unstableCount--;
9891            }
9892            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9893                cpr.connections.remove(conn);
9894                conn.client.conProviders.remove(conn);
9895                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
9896                    // The client is more important than last activity -- note the time this
9897                    // is happening, so we keep the old provider process around a bit as last
9898                    // activity to avoid thrashing it.
9899                    if (cpr.proc != null) {
9900                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
9901                    }
9902                }
9903                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9904                return true;
9905            }
9906            return false;
9907        }
9908        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9909        return false;
9910    }
9911
9912    private void checkTime(long startTime, String where) {
9913        long now = SystemClock.elapsedRealtime();
9914        if ((now-startTime) > 1000) {
9915            // If we are taking more than a second, log about it.
9916            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9917        }
9918    }
9919
9920    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9921            String name, IBinder token, boolean stable, int userId) {
9922        ContentProviderRecord cpr;
9923        ContentProviderConnection conn = null;
9924        ProviderInfo cpi = null;
9925
9926        synchronized(this) {
9927            long startTime = SystemClock.elapsedRealtime();
9928
9929            ProcessRecord r = null;
9930            if (caller != null) {
9931                r = getRecordForAppLocked(caller);
9932                if (r == null) {
9933                    throw new SecurityException(
9934                            "Unable to find app for caller " + caller
9935                          + " (pid=" + Binder.getCallingPid()
9936                          + ") when getting content provider " + name);
9937                }
9938            }
9939
9940            boolean checkCrossUser = true;
9941
9942            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9943
9944            // First check if this content provider has been published...
9945            cpr = mProviderMap.getProviderByName(name, userId);
9946            // If that didn't work, check if it exists for user 0 and then
9947            // verify that it's a singleton provider before using it.
9948            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
9949                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
9950                if (cpr != null) {
9951                    cpi = cpr.info;
9952                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9953                            cpi.name, cpi.flags)
9954                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9955                        userId = UserHandle.USER_SYSTEM;
9956                        checkCrossUser = false;
9957                    } else {
9958                        cpr = null;
9959                        cpi = null;
9960                    }
9961                }
9962            }
9963
9964            boolean providerRunning = cpr != null;
9965            if (providerRunning) {
9966                cpi = cpr.info;
9967                String msg;
9968                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9969                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9970                        != null) {
9971                    throw new SecurityException(msg);
9972                }
9973                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9974
9975                if (r != null && cpr.canRunHere(r)) {
9976                    // This provider has been published or is in the process
9977                    // of being published...  but it is also allowed to run
9978                    // in the caller's process, so don't make a connection
9979                    // and just let the caller instantiate its own instance.
9980                    ContentProviderHolder holder = cpr.newHolder(null);
9981                    // don't give caller the provider object, it needs
9982                    // to make its own.
9983                    holder.provider = null;
9984                    return holder;
9985                }
9986
9987                final long origId = Binder.clearCallingIdentity();
9988
9989                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9990
9991                // In this case the provider instance already exists, so we can
9992                // return it right away.
9993                conn = incProviderCountLocked(r, cpr, token, stable);
9994                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9995                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9996                        // If this is a perceptible app accessing the provider,
9997                        // make sure to count it as being accessed and thus
9998                        // back up on the LRU list.  This is good because
9999                        // content providers are often expensive to start.
10000                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10001                        updateLruProcessLocked(cpr.proc, false, null);
10002                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10003                    }
10004                }
10005
10006                if (cpr.proc != null) {
10007                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10008                    boolean success = updateOomAdjLocked(cpr.proc);
10009                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10010                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10011                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10012                    // NOTE: there is still a race here where a signal could be
10013                    // pending on the process even though we managed to update its
10014                    // adj level.  Not sure what to do about this, but at least
10015                    // the race is now smaller.
10016                    if (!success) {
10017                        // Uh oh...  it looks like the provider's process
10018                        // has been killed on us.  We need to wait for a new
10019                        // process to be started, and make sure its death
10020                        // doesn't kill our process.
10021                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10022                                + " is crashing; detaching " + r);
10023                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10024                        checkTime(startTime, "getContentProviderImpl: before appDied");
10025                        appDiedLocked(cpr.proc);
10026                        checkTime(startTime, "getContentProviderImpl: after appDied");
10027                        if (!lastRef) {
10028                            // This wasn't the last ref our process had on
10029                            // the provider...  we have now been killed, bail.
10030                            return null;
10031                        }
10032                        providerRunning = false;
10033                        conn = null;
10034                    }
10035                }
10036
10037                Binder.restoreCallingIdentity(origId);
10038            }
10039
10040            if (!providerRunning) {
10041                try {
10042                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10043                    cpi = AppGlobals.getPackageManager().
10044                        resolveContentProvider(name,
10045                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10046                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10047                } catch (RemoteException ex) {
10048                }
10049                if (cpi == null) {
10050                    return null;
10051                }
10052                // If the provider is a singleton AND
10053                // (it's a call within the same user || the provider is a
10054                // privileged app)
10055                // Then allow connecting to the singleton provider
10056                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10057                        cpi.name, cpi.flags)
10058                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10059                if (singleton) {
10060                    userId = UserHandle.USER_SYSTEM;
10061                }
10062                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10063                checkTime(startTime, "getContentProviderImpl: got app info for user");
10064
10065                String msg;
10066                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10067                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10068                        != null) {
10069                    throw new SecurityException(msg);
10070                }
10071                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10072
10073                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
10074                        && !cpi.processName.equals("system")) {
10075                    // If this content provider does not run in the system
10076                    // process, and the system is not yet ready to run other
10077                    // processes, then fail fast instead of hanging.
10078                    throw new IllegalArgumentException(
10079                            "Attempt to launch content provider before system ready");
10080                }
10081
10082                // Make sure that the user who owns this provider is running.  If not,
10083                // we don't want to allow it to run.
10084                if (!mUserController.isUserRunningLocked(userId, 0)) {
10085                    Slog.w(TAG, "Unable to launch app "
10086                            + cpi.applicationInfo.packageName + "/"
10087                            + cpi.applicationInfo.uid + " for provider "
10088                            + name + ": user " + userId + " is stopped");
10089                    return null;
10090                }
10091
10092                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10093                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10094                cpr = mProviderMap.getProviderByClass(comp, userId);
10095                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10096                final boolean firstClass = cpr == null;
10097                if (firstClass) {
10098                    final long ident = Binder.clearCallingIdentity();
10099
10100                    // If permissions need a review before any of the app components can run,
10101                    // we return no provider and launch a review activity if the calling app
10102                    // is in the foreground.
10103                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10104                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10105                            return null;
10106                        }
10107                    }
10108
10109                    try {
10110                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10111                        ApplicationInfo ai =
10112                            AppGlobals.getPackageManager().
10113                                getApplicationInfo(
10114                                        cpi.applicationInfo.packageName,
10115                                        STOCK_PM_FLAGS, userId);
10116                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10117                        if (ai == null) {
10118                            Slog.w(TAG, "No package info for content provider "
10119                                    + cpi.name);
10120                            return null;
10121                        }
10122                        ai = getAppInfoForUser(ai, userId);
10123                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10124                    } catch (RemoteException ex) {
10125                        // pm is in same process, this will never happen.
10126                    } finally {
10127                        Binder.restoreCallingIdentity(ident);
10128                    }
10129                }
10130
10131                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10132
10133                if (r != null && cpr.canRunHere(r)) {
10134                    // If this is a multiprocess provider, then just return its
10135                    // info and allow the caller to instantiate it.  Only do
10136                    // this if the provider is the same user as the caller's
10137                    // process, or can run as root (so can be in any process).
10138                    return cpr.newHolder(null);
10139                }
10140
10141                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10142                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10143                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10144
10145                // This is single process, and our app is now connecting to it.
10146                // See if we are already in the process of launching this
10147                // provider.
10148                final int N = mLaunchingProviders.size();
10149                int i;
10150                for (i = 0; i < N; i++) {
10151                    if (mLaunchingProviders.get(i) == cpr) {
10152                        break;
10153                    }
10154                }
10155
10156                // If the provider is not already being launched, then get it
10157                // started.
10158                if (i >= N) {
10159                    final long origId = Binder.clearCallingIdentity();
10160
10161                    try {
10162                        // Content provider is now in use, its package can't be stopped.
10163                        try {
10164                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10165                            AppGlobals.getPackageManager().setPackageStoppedState(
10166                                    cpr.appInfo.packageName, false, userId);
10167                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10168                        } catch (RemoteException e) {
10169                        } catch (IllegalArgumentException e) {
10170                            Slog.w(TAG, "Failed trying to unstop package "
10171                                    + cpr.appInfo.packageName + ": " + e);
10172                        }
10173
10174                        // Use existing process if already started
10175                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10176                        ProcessRecord proc = getProcessRecordLocked(
10177                                cpi.processName, cpr.appInfo.uid, false);
10178                        if (proc != null && proc.thread != null) {
10179                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10180                                    "Installing in existing process " + proc);
10181                            if (!proc.pubProviders.containsKey(cpi.name)) {
10182                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10183                                proc.pubProviders.put(cpi.name, cpr);
10184                                try {
10185                                    proc.thread.scheduleInstallProvider(cpi);
10186                                } catch (RemoteException e) {
10187                                }
10188                            }
10189                        } else {
10190                            checkTime(startTime, "getContentProviderImpl: before start process");
10191                            proc = startProcessLocked(cpi.processName,
10192                                    cpr.appInfo, false, 0, "content provider",
10193                                    new ComponentName(cpi.applicationInfo.packageName,
10194                                            cpi.name), false, false, false);
10195                            checkTime(startTime, "getContentProviderImpl: after start process");
10196                            if (proc == null) {
10197                                Slog.w(TAG, "Unable to launch app "
10198                                        + cpi.applicationInfo.packageName + "/"
10199                                        + cpi.applicationInfo.uid + " for provider "
10200                                        + name + ": process is bad");
10201                                return null;
10202                            }
10203                        }
10204                        cpr.launchingApp = proc;
10205                        mLaunchingProviders.add(cpr);
10206                    } finally {
10207                        Binder.restoreCallingIdentity(origId);
10208                    }
10209                }
10210
10211                checkTime(startTime, "getContentProviderImpl: updating data structures");
10212
10213                // Make sure the provider is published (the same provider class
10214                // may be published under multiple names).
10215                if (firstClass) {
10216                    mProviderMap.putProviderByClass(comp, cpr);
10217                }
10218
10219                mProviderMap.putProviderByName(name, cpr);
10220                conn = incProviderCountLocked(r, cpr, token, stable);
10221                if (conn != null) {
10222                    conn.waiting = true;
10223                }
10224            }
10225            checkTime(startTime, "getContentProviderImpl: done!");
10226        }
10227
10228        // Wait for the provider to be published...
10229        synchronized (cpr) {
10230            while (cpr.provider == null) {
10231                if (cpr.launchingApp == null) {
10232                    Slog.w(TAG, "Unable to launch app "
10233                            + cpi.applicationInfo.packageName + "/"
10234                            + cpi.applicationInfo.uid + " for provider "
10235                            + name + ": launching app became null");
10236                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10237                            UserHandle.getUserId(cpi.applicationInfo.uid),
10238                            cpi.applicationInfo.packageName,
10239                            cpi.applicationInfo.uid, name);
10240                    return null;
10241                }
10242                try {
10243                    if (DEBUG_MU) Slog.v(TAG_MU,
10244                            "Waiting to start provider " + cpr
10245                            + " launchingApp=" + cpr.launchingApp);
10246                    if (conn != null) {
10247                        conn.waiting = true;
10248                    }
10249                    cpr.wait();
10250                } catch (InterruptedException ex) {
10251                } finally {
10252                    if (conn != null) {
10253                        conn.waiting = false;
10254                    }
10255                }
10256            }
10257        }
10258        return cpr != null ? cpr.newHolder(conn) : null;
10259    }
10260
10261    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10262            ProcessRecord r, final int userId) {
10263        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10264                cpi.packageName, r.userId)) {
10265
10266            final boolean callerForeground = r != null ? r.setSchedGroup
10267                    != Process.THREAD_GROUP_BG_NONINTERACTIVE : true;
10268
10269            // Show a permission review UI only for starting from a foreground app
10270            if (!callerForeground) {
10271                Slog.w(TAG, "u" + r.userId + " Instantiating a provider in package"
10272                        + cpi.packageName + " requires a permissions review");
10273                return false;
10274            }
10275
10276            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10277            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10278                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10279            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10280
10281            if (DEBUG_PERMISSIONS_REVIEW) {
10282                Slog.i(TAG, "u" + r.userId + " Launching permission review "
10283                        + "for package " + cpi.packageName);
10284            }
10285
10286            final UserHandle userHandle = new UserHandle(userId);
10287            mHandler.post(new Runnable() {
10288                @Override
10289                public void run() {
10290                    mContext.startActivityAsUser(intent, userHandle);
10291                }
10292            });
10293
10294            return false;
10295        }
10296
10297        return true;
10298    }
10299
10300    PackageManagerInternal getPackageManagerInternalLocked() {
10301        if (mPackageManagerInt == null) {
10302            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10303        }
10304        return mPackageManagerInt;
10305    }
10306
10307    @Override
10308    public final ContentProviderHolder getContentProvider(
10309            IApplicationThread caller, String name, int userId, boolean stable) {
10310        enforceNotIsolatedCaller("getContentProvider");
10311        if (caller == null) {
10312            String msg = "null IApplicationThread when getting content provider "
10313                    + name;
10314            Slog.w(TAG, msg);
10315            throw new SecurityException(msg);
10316        }
10317        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10318        // with cross-user grant.
10319        return getContentProviderImpl(caller, name, null, stable, userId);
10320    }
10321
10322    public ContentProviderHolder getContentProviderExternal(
10323            String name, int userId, IBinder token) {
10324        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10325            "Do not have permission in call getContentProviderExternal()");
10326        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10327                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10328        return getContentProviderExternalUnchecked(name, token, userId);
10329    }
10330
10331    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10332            IBinder token, int userId) {
10333        return getContentProviderImpl(null, name, token, true, userId);
10334    }
10335
10336    /**
10337     * Drop a content provider from a ProcessRecord's bookkeeping
10338     */
10339    public void removeContentProvider(IBinder connection, boolean stable) {
10340        enforceNotIsolatedCaller("removeContentProvider");
10341        long ident = Binder.clearCallingIdentity();
10342        try {
10343            synchronized (this) {
10344                ContentProviderConnection conn;
10345                try {
10346                    conn = (ContentProviderConnection)connection;
10347                } catch (ClassCastException e) {
10348                    String msg ="removeContentProvider: " + connection
10349                            + " not a ContentProviderConnection";
10350                    Slog.w(TAG, msg);
10351                    throw new IllegalArgumentException(msg);
10352                }
10353                if (conn == null) {
10354                    throw new NullPointerException("connection is null");
10355                }
10356                if (decProviderCountLocked(conn, null, null, stable)) {
10357                    updateOomAdjLocked();
10358                }
10359            }
10360        } finally {
10361            Binder.restoreCallingIdentity(ident);
10362        }
10363    }
10364
10365    public void removeContentProviderExternal(String name, IBinder token) {
10366        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10367            "Do not have permission in call removeContentProviderExternal()");
10368        int userId = UserHandle.getCallingUserId();
10369        long ident = Binder.clearCallingIdentity();
10370        try {
10371            removeContentProviderExternalUnchecked(name, token, userId);
10372        } finally {
10373            Binder.restoreCallingIdentity(ident);
10374        }
10375    }
10376
10377    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10378        synchronized (this) {
10379            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10380            if(cpr == null) {
10381                //remove from mProvidersByClass
10382                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10383                return;
10384            }
10385
10386            //update content provider record entry info
10387            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10388            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10389            if (localCpr.hasExternalProcessHandles()) {
10390                if (localCpr.removeExternalProcessHandleLocked(token)) {
10391                    updateOomAdjLocked();
10392                } else {
10393                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10394                            + " with no external reference for token: "
10395                            + token + ".");
10396                }
10397            } else {
10398                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10399                        + " with no external references.");
10400            }
10401        }
10402    }
10403
10404    public final void publishContentProviders(IApplicationThread caller,
10405            List<ContentProviderHolder> providers) {
10406        if (providers == null) {
10407            return;
10408        }
10409
10410        enforceNotIsolatedCaller("publishContentProviders");
10411        synchronized (this) {
10412            final ProcessRecord r = getRecordForAppLocked(caller);
10413            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10414            if (r == null) {
10415                throw new SecurityException(
10416                        "Unable to find app for caller " + caller
10417                      + " (pid=" + Binder.getCallingPid()
10418                      + ") when publishing content providers");
10419            }
10420
10421            final long origId = Binder.clearCallingIdentity();
10422
10423            final int N = providers.size();
10424            for (int i = 0; i < N; i++) {
10425                ContentProviderHolder src = providers.get(i);
10426                if (src == null || src.info == null || src.provider == null) {
10427                    continue;
10428                }
10429                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10430                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10431                if (dst != null) {
10432                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10433                    mProviderMap.putProviderByClass(comp, dst);
10434                    String names[] = dst.info.authority.split(";");
10435                    for (int j = 0; j < names.length; j++) {
10436                        mProviderMap.putProviderByName(names[j], dst);
10437                    }
10438
10439                    int launchingCount = mLaunchingProviders.size();
10440                    int j;
10441                    boolean wasInLaunchingProviders = false;
10442                    for (j = 0; j < launchingCount; j++) {
10443                        if (mLaunchingProviders.get(j) == dst) {
10444                            mLaunchingProviders.remove(j);
10445                            wasInLaunchingProviders = true;
10446                            j--;
10447                            launchingCount--;
10448                        }
10449                    }
10450                    if (wasInLaunchingProviders) {
10451                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10452                    }
10453                    synchronized (dst) {
10454                        dst.provider = src.provider;
10455                        dst.proc = r;
10456                        dst.notifyAll();
10457                    }
10458                    updateOomAdjLocked(r);
10459                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10460                            src.info.authority);
10461                }
10462            }
10463
10464            Binder.restoreCallingIdentity(origId);
10465        }
10466    }
10467
10468    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10469        ContentProviderConnection conn;
10470        try {
10471            conn = (ContentProviderConnection)connection;
10472        } catch (ClassCastException e) {
10473            String msg ="refContentProvider: " + connection
10474                    + " not a ContentProviderConnection";
10475            Slog.w(TAG, msg);
10476            throw new IllegalArgumentException(msg);
10477        }
10478        if (conn == null) {
10479            throw new NullPointerException("connection is null");
10480        }
10481
10482        synchronized (this) {
10483            if (stable > 0) {
10484                conn.numStableIncs += stable;
10485            }
10486            stable = conn.stableCount + stable;
10487            if (stable < 0) {
10488                throw new IllegalStateException("stableCount < 0: " + stable);
10489            }
10490
10491            if (unstable > 0) {
10492                conn.numUnstableIncs += unstable;
10493            }
10494            unstable = conn.unstableCount + unstable;
10495            if (unstable < 0) {
10496                throw new IllegalStateException("unstableCount < 0: " + unstable);
10497            }
10498
10499            if ((stable+unstable) <= 0) {
10500                throw new IllegalStateException("ref counts can't go to zero here: stable="
10501                        + stable + " unstable=" + unstable);
10502            }
10503            conn.stableCount = stable;
10504            conn.unstableCount = unstable;
10505            return !conn.dead;
10506        }
10507    }
10508
10509    public void unstableProviderDied(IBinder connection) {
10510        ContentProviderConnection conn;
10511        try {
10512            conn = (ContentProviderConnection)connection;
10513        } catch (ClassCastException e) {
10514            String msg ="refContentProvider: " + connection
10515                    + " not a ContentProviderConnection";
10516            Slog.w(TAG, msg);
10517            throw new IllegalArgumentException(msg);
10518        }
10519        if (conn == null) {
10520            throw new NullPointerException("connection is null");
10521        }
10522
10523        // Safely retrieve the content provider associated with the connection.
10524        IContentProvider provider;
10525        synchronized (this) {
10526            provider = conn.provider.provider;
10527        }
10528
10529        if (provider == null) {
10530            // Um, yeah, we're way ahead of you.
10531            return;
10532        }
10533
10534        // Make sure the caller is being honest with us.
10535        if (provider.asBinder().pingBinder()) {
10536            // Er, no, still looks good to us.
10537            synchronized (this) {
10538                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10539                        + " says " + conn + " died, but we don't agree");
10540                return;
10541            }
10542        }
10543
10544        // Well look at that!  It's dead!
10545        synchronized (this) {
10546            if (conn.provider.provider != provider) {
10547                // But something changed...  good enough.
10548                return;
10549            }
10550
10551            ProcessRecord proc = conn.provider.proc;
10552            if (proc == null || proc.thread == null) {
10553                // Seems like the process is already cleaned up.
10554                return;
10555            }
10556
10557            // As far as we're concerned, this is just like receiving a
10558            // death notification...  just a bit prematurely.
10559            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10560                    + ") early provider death");
10561            final long ident = Binder.clearCallingIdentity();
10562            try {
10563                appDiedLocked(proc);
10564            } finally {
10565                Binder.restoreCallingIdentity(ident);
10566            }
10567        }
10568    }
10569
10570    @Override
10571    public void appNotRespondingViaProvider(IBinder connection) {
10572        enforceCallingPermission(
10573                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10574
10575        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10576        if (conn == null) {
10577            Slog.w(TAG, "ContentProviderConnection is null");
10578            return;
10579        }
10580
10581        final ProcessRecord host = conn.provider.proc;
10582        if (host == null) {
10583            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10584            return;
10585        }
10586
10587        final long token = Binder.clearCallingIdentity();
10588        try {
10589            appNotResponding(host, null, null, false, "ContentProvider not responding");
10590        } finally {
10591            Binder.restoreCallingIdentity(token);
10592        }
10593    }
10594
10595    public final void installSystemProviders() {
10596        List<ProviderInfo> providers;
10597        synchronized (this) {
10598            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10599            providers = generateApplicationProvidersLocked(app);
10600            if (providers != null) {
10601                for (int i=providers.size()-1; i>=0; i--) {
10602                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10603                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10604                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10605                                + ": not system .apk");
10606                        providers.remove(i);
10607                    }
10608                }
10609            }
10610        }
10611        if (providers != null) {
10612            mSystemThread.installSystemProviders(providers);
10613        }
10614
10615        mCoreSettingsObserver = new CoreSettingsObserver(this);
10616
10617        //mUsageStatsService.monitorPackages();
10618    }
10619
10620    /**
10621     * Allows apps to retrieve the MIME type of a URI.
10622     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10623     * users, then it does not need permission to access the ContentProvider.
10624     * Either, it needs cross-user uri grants.
10625     *
10626     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10627     *
10628     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10629     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10630     */
10631    public String getProviderMimeType(Uri uri, int userId) {
10632        enforceNotIsolatedCaller("getProviderMimeType");
10633        final String name = uri.getAuthority();
10634        int callingUid = Binder.getCallingUid();
10635        int callingPid = Binder.getCallingPid();
10636        long ident = 0;
10637        boolean clearedIdentity = false;
10638        synchronized (this) {
10639            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
10640        }
10641        if (canClearIdentity(callingPid, callingUid, userId)) {
10642            clearedIdentity = true;
10643            ident = Binder.clearCallingIdentity();
10644        }
10645        ContentProviderHolder holder = null;
10646        try {
10647            holder = getContentProviderExternalUnchecked(name, null, userId);
10648            if (holder != null) {
10649                return holder.provider.getType(uri);
10650            }
10651        } catch (RemoteException e) {
10652            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10653            return null;
10654        } finally {
10655            // We need to clear the identity to call removeContentProviderExternalUnchecked
10656            if (!clearedIdentity) {
10657                ident = Binder.clearCallingIdentity();
10658            }
10659            try {
10660                if (holder != null) {
10661                    removeContentProviderExternalUnchecked(name, null, userId);
10662                }
10663            } finally {
10664                Binder.restoreCallingIdentity(ident);
10665            }
10666        }
10667
10668        return null;
10669    }
10670
10671    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10672        if (UserHandle.getUserId(callingUid) == userId) {
10673            return true;
10674        }
10675        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10676                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10677                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10678                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10679                return true;
10680        }
10681        return false;
10682    }
10683
10684    // =========================================================
10685    // GLOBAL MANAGEMENT
10686    // =========================================================
10687
10688    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10689            boolean isolated, int isolatedUid) {
10690        String proc = customProcess != null ? customProcess : info.processName;
10691        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10692        final int userId = UserHandle.getUserId(info.uid);
10693        int uid = info.uid;
10694        if (isolated) {
10695            if (isolatedUid == 0) {
10696                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10697                while (true) {
10698                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10699                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10700                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10701                    }
10702                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10703                    mNextIsolatedProcessUid++;
10704                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10705                        // No process for this uid, use it.
10706                        break;
10707                    }
10708                    stepsLeft--;
10709                    if (stepsLeft <= 0) {
10710                        return null;
10711                    }
10712                }
10713            } else {
10714                // Special case for startIsolatedProcess (internal only), where
10715                // the uid of the isolated process is specified by the caller.
10716                uid = isolatedUid;
10717            }
10718        }
10719        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10720        if (!mBooted && !mBooting
10721                && userId == UserHandle.USER_SYSTEM
10722                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10723            r.persistent = true;
10724        }
10725        addProcessNameLocked(r);
10726        return r;
10727    }
10728
10729    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10730            String abiOverride) {
10731        ProcessRecord app;
10732        if (!isolated) {
10733            app = getProcessRecordLocked(info.processName, info.uid, true);
10734        } else {
10735            app = null;
10736        }
10737
10738        if (app == null) {
10739            app = newProcessRecordLocked(info, null, isolated, 0);
10740            updateLruProcessLocked(app, false, null);
10741            updateOomAdjLocked();
10742        }
10743
10744        // This package really, really can not be stopped.
10745        try {
10746            AppGlobals.getPackageManager().setPackageStoppedState(
10747                    info.packageName, false, UserHandle.getUserId(app.uid));
10748        } catch (RemoteException e) {
10749        } catch (IllegalArgumentException e) {
10750            Slog.w(TAG, "Failed trying to unstop package "
10751                    + info.packageName + ": " + e);
10752        }
10753
10754        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10755            app.persistent = true;
10756            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10757        }
10758        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10759            mPersistentStartingProcesses.add(app);
10760            startProcessLocked(app, "added application", app.processName, abiOverride,
10761                    null /* entryPoint */, null /* entryPointArgs */);
10762        }
10763
10764        return app;
10765    }
10766
10767    public void unhandledBack() {
10768        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10769                "unhandledBack()");
10770
10771        synchronized(this) {
10772            final long origId = Binder.clearCallingIdentity();
10773            try {
10774                getFocusedStack().unhandledBackLocked();
10775            } finally {
10776                Binder.restoreCallingIdentity(origId);
10777            }
10778        }
10779    }
10780
10781    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10782        enforceNotIsolatedCaller("openContentUri");
10783        final int userId = UserHandle.getCallingUserId();
10784        String name = uri.getAuthority();
10785        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10786        ParcelFileDescriptor pfd = null;
10787        if (cph != null) {
10788            // We record the binder invoker's uid in thread-local storage before
10789            // going to the content provider to open the file.  Later, in the code
10790            // that handles all permissions checks, we look for this uid and use
10791            // that rather than the Activity Manager's own uid.  The effect is that
10792            // we do the check against the caller's permissions even though it looks
10793            // to the content provider like the Activity Manager itself is making
10794            // the request.
10795            Binder token = new Binder();
10796            sCallerIdentity.set(new Identity(
10797                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10798            try {
10799                pfd = cph.provider.openFile(null, uri, "r", null, token);
10800            } catch (FileNotFoundException e) {
10801                // do nothing; pfd will be returned null
10802            } finally {
10803                // Ensure that whatever happens, we clean up the identity state
10804                sCallerIdentity.remove();
10805                // Ensure we're done with the provider.
10806                removeContentProviderExternalUnchecked(name, null, userId);
10807            }
10808        } else {
10809            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10810        }
10811        return pfd;
10812    }
10813
10814    // Actually is sleeping or shutting down or whatever else in the future
10815    // is an inactive state.
10816    public boolean isSleepingOrShuttingDown() {
10817        return isSleeping() || mShuttingDown;
10818    }
10819
10820    public boolean isSleeping() {
10821        return mSleeping;
10822    }
10823
10824    void onWakefulnessChanged(int wakefulness) {
10825        synchronized(this) {
10826            mWakefulness = wakefulness;
10827            updateSleepIfNeededLocked();
10828        }
10829    }
10830
10831    void finishRunningVoiceLocked() {
10832        if (mRunningVoice != null) {
10833            mRunningVoice = null;
10834            mVoiceWakeLock.release();
10835            updateSleepIfNeededLocked();
10836        }
10837    }
10838
10839    void startTimeTrackingFocusedActivityLocked() {
10840        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10841            mCurAppTimeTracker.start(mFocusedActivity.packageName);
10842        }
10843    }
10844
10845    void updateSleepIfNeededLocked() {
10846        if (mSleeping && !shouldSleepLocked()) {
10847            mSleeping = false;
10848            startTimeTrackingFocusedActivityLocked();
10849            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10850            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10851            updateOomAdjLocked();
10852        } else if (!mSleeping && shouldSleepLocked()) {
10853            mSleeping = true;
10854            if (mCurAppTimeTracker != null) {
10855                mCurAppTimeTracker.stop();
10856            }
10857            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10858            mStackSupervisor.goingToSleepLocked();
10859            updateOomAdjLocked();
10860
10861            // Initialize the wake times of all processes.
10862            checkExcessivePowerUsageLocked(false);
10863            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10864            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10865            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10866        }
10867    }
10868
10869    private boolean shouldSleepLocked() {
10870        // Resume applications while running a voice interactor.
10871        if (mRunningVoice != null) {
10872            return false;
10873        }
10874
10875        // TODO: Transform the lock screen state into a sleep token instead.
10876        switch (mWakefulness) {
10877            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10878            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10879            case PowerManagerInternal.WAKEFULNESS_DOZING:
10880                // Pause applications whenever the lock screen is shown or any sleep
10881                // tokens have been acquired.
10882                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10883            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10884            default:
10885                // If we're asleep then pause applications unconditionally.
10886                return true;
10887        }
10888    }
10889
10890    /** Pokes the task persister. */
10891    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10892        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10893            // Never persist the home stack.
10894            return;
10895        }
10896        mTaskPersister.wakeup(task, flush);
10897    }
10898
10899    /** Notifies all listeners when the task stack has changed. */
10900    void notifyTaskStackChangedLocked() {
10901        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10902        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10903        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10904    }
10905
10906    @Override
10907    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10908        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10909    }
10910
10911    @Override
10912    public boolean shutdown(int timeout) {
10913        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10914                != PackageManager.PERMISSION_GRANTED) {
10915            throw new SecurityException("Requires permission "
10916                    + android.Manifest.permission.SHUTDOWN);
10917        }
10918
10919        boolean timedout = false;
10920
10921        synchronized(this) {
10922            mShuttingDown = true;
10923            updateEventDispatchingLocked();
10924            timedout = mStackSupervisor.shutdownLocked(timeout);
10925        }
10926
10927        mAppOpsService.shutdown();
10928        if (mUsageStatsService != null) {
10929            mUsageStatsService.prepareShutdown();
10930        }
10931        mBatteryStatsService.shutdown();
10932        synchronized (this) {
10933            mProcessStats.shutdownLocked();
10934            notifyTaskPersisterLocked(null, true);
10935        }
10936
10937        return timedout;
10938    }
10939
10940    public final void activitySlept(IBinder token) {
10941        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10942
10943        final long origId = Binder.clearCallingIdentity();
10944
10945        synchronized (this) {
10946            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10947            if (r != null) {
10948                mStackSupervisor.activitySleptLocked(r);
10949            }
10950        }
10951
10952        Binder.restoreCallingIdentity(origId);
10953    }
10954
10955    private String lockScreenShownToString() {
10956        switch (mLockScreenShown) {
10957            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10958            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10959            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10960            default: return "Unknown=" + mLockScreenShown;
10961        }
10962    }
10963
10964    void logLockScreen(String msg) {
10965        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10966                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10967                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10968                + " mSleeping=" + mSleeping);
10969    }
10970
10971    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10972        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10973        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10974            boolean wasRunningVoice = mRunningVoice != null;
10975            mRunningVoice = session;
10976            if (!wasRunningVoice) {
10977                mVoiceWakeLock.acquire();
10978                updateSleepIfNeededLocked();
10979            }
10980        }
10981    }
10982
10983    private void updateEventDispatchingLocked() {
10984        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10985    }
10986
10987    public void setLockScreenShown(boolean shown) {
10988        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10989                != PackageManager.PERMISSION_GRANTED) {
10990            throw new SecurityException("Requires permission "
10991                    + android.Manifest.permission.DEVICE_POWER);
10992        }
10993
10994        synchronized(this) {
10995            long ident = Binder.clearCallingIdentity();
10996            try {
10997                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10998                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10999                updateSleepIfNeededLocked();
11000            } finally {
11001                Binder.restoreCallingIdentity(ident);
11002            }
11003        }
11004    }
11005
11006    @Override
11007    public void stopAppSwitches() {
11008        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11009                != PackageManager.PERMISSION_GRANTED) {
11010            throw new SecurityException("viewquires permission "
11011                    + android.Manifest.permission.STOP_APP_SWITCHES);
11012        }
11013
11014        synchronized(this) {
11015            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11016                    + APP_SWITCH_DELAY_TIME;
11017            mDidAppSwitch = false;
11018            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11019            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11020            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11021        }
11022    }
11023
11024    public void resumeAppSwitches() {
11025        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11026                != PackageManager.PERMISSION_GRANTED) {
11027            throw new SecurityException("Requires permission "
11028                    + android.Manifest.permission.STOP_APP_SWITCHES);
11029        }
11030
11031        synchronized(this) {
11032            // Note that we don't execute any pending app switches... we will
11033            // let those wait until either the timeout, or the next start
11034            // activity request.
11035            mAppSwitchesAllowedTime = 0;
11036        }
11037    }
11038
11039    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11040            int callingPid, int callingUid, String name) {
11041        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11042            return true;
11043        }
11044
11045        int perm = checkComponentPermission(
11046                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11047                sourceUid, -1, true);
11048        if (perm == PackageManager.PERMISSION_GRANTED) {
11049            return true;
11050        }
11051
11052        // If the actual IPC caller is different from the logical source, then
11053        // also see if they are allowed to control app switches.
11054        if (callingUid != -1 && callingUid != sourceUid) {
11055            perm = checkComponentPermission(
11056                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11057                    callingUid, -1, true);
11058            if (perm == PackageManager.PERMISSION_GRANTED) {
11059                return true;
11060            }
11061        }
11062
11063        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11064        return false;
11065    }
11066
11067    public void setDebugApp(String packageName, boolean waitForDebugger,
11068            boolean persistent) {
11069        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11070                "setDebugApp()");
11071
11072        long ident = Binder.clearCallingIdentity();
11073        try {
11074            // Note that this is not really thread safe if there are multiple
11075            // callers into it at the same time, but that's not a situation we
11076            // care about.
11077            if (persistent) {
11078                final ContentResolver resolver = mContext.getContentResolver();
11079                Settings.Global.putString(
11080                    resolver, Settings.Global.DEBUG_APP,
11081                    packageName);
11082                Settings.Global.putInt(
11083                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11084                    waitForDebugger ? 1 : 0);
11085            }
11086
11087            synchronized (this) {
11088                if (!persistent) {
11089                    mOrigDebugApp = mDebugApp;
11090                    mOrigWaitForDebugger = mWaitForDebugger;
11091                }
11092                mDebugApp = packageName;
11093                mWaitForDebugger = waitForDebugger;
11094                mDebugTransient = !persistent;
11095                if (packageName != null) {
11096                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11097                            false, UserHandle.USER_ALL, "set debug app");
11098                }
11099            }
11100        } finally {
11101            Binder.restoreCallingIdentity(ident);
11102        }
11103    }
11104
11105    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11106        synchronized (this) {
11107            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11108            if (!isDebuggable) {
11109                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11110                    throw new SecurityException("Process not debuggable: " + app.packageName);
11111                }
11112            }
11113
11114            mTrackAllocationApp = processName;
11115        }
11116    }
11117
11118    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11119        synchronized (this) {
11120            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11121            if (!isDebuggable) {
11122                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11123                    throw new SecurityException("Process not debuggable: " + app.packageName);
11124                }
11125            }
11126            mProfileApp = processName;
11127            mProfileFile = profilerInfo.profileFile;
11128            if (mProfileFd != null) {
11129                try {
11130                    mProfileFd.close();
11131                } catch (IOException e) {
11132                }
11133                mProfileFd = null;
11134            }
11135            mProfileFd = profilerInfo.profileFd;
11136            mSamplingInterval = profilerInfo.samplingInterval;
11137            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11138            mProfileType = 0;
11139        }
11140    }
11141
11142    @Override
11143    public void setAlwaysFinish(boolean enabled) {
11144        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11145                "setAlwaysFinish()");
11146
11147        Settings.Global.putInt(
11148                mContext.getContentResolver(),
11149                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11150
11151        synchronized (this) {
11152            mAlwaysFinishActivities = enabled;
11153        }
11154    }
11155
11156    @Override
11157    public void setActivityController(IActivityController controller) {
11158        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11159                "setActivityController()");
11160        synchronized (this) {
11161            mController = controller;
11162            Watchdog.getInstance().setActivityController(controller);
11163        }
11164    }
11165
11166    @Override
11167    public void setUserIsMonkey(boolean userIsMonkey) {
11168        synchronized (this) {
11169            synchronized (mPidsSelfLocked) {
11170                final int callingPid = Binder.getCallingPid();
11171                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11172                if (precessRecord == null) {
11173                    throw new SecurityException("Unknown process: " + callingPid);
11174                }
11175                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11176                    throw new SecurityException("Only an instrumentation process "
11177                            + "with a UiAutomation can call setUserIsMonkey");
11178                }
11179            }
11180            mUserIsMonkey = userIsMonkey;
11181        }
11182    }
11183
11184    @Override
11185    public boolean isUserAMonkey() {
11186        synchronized (this) {
11187            // If there is a controller also implies the user is a monkey.
11188            return (mUserIsMonkey || mController != null);
11189        }
11190    }
11191
11192    public void requestBugReport(boolean progress) {
11193        final String service = progress ? "bugreportplus" : "bugreport";
11194        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11195        SystemProperties.set("ctl.start", service);
11196    }
11197
11198    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11199        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11200    }
11201
11202    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11203        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11204            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11205        }
11206        return KEY_DISPATCHING_TIMEOUT;
11207    }
11208
11209    @Override
11210    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11211        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11212                != PackageManager.PERMISSION_GRANTED) {
11213            throw new SecurityException("Requires permission "
11214                    + android.Manifest.permission.FILTER_EVENTS);
11215        }
11216        ProcessRecord proc;
11217        long timeout;
11218        synchronized (this) {
11219            synchronized (mPidsSelfLocked) {
11220                proc = mPidsSelfLocked.get(pid);
11221            }
11222            timeout = getInputDispatchingTimeoutLocked(proc);
11223        }
11224
11225        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11226            return -1;
11227        }
11228
11229        return timeout;
11230    }
11231
11232    /**
11233     * Handle input dispatching timeouts.
11234     * Returns whether input dispatching should be aborted or not.
11235     */
11236    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11237            final ActivityRecord activity, final ActivityRecord parent,
11238            final boolean aboveSystem, String reason) {
11239        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11240                != PackageManager.PERMISSION_GRANTED) {
11241            throw new SecurityException("Requires permission "
11242                    + android.Manifest.permission.FILTER_EVENTS);
11243        }
11244
11245        final String annotation;
11246        if (reason == null) {
11247            annotation = "Input dispatching timed out";
11248        } else {
11249            annotation = "Input dispatching timed out (" + reason + ")";
11250        }
11251
11252        if (proc != null) {
11253            synchronized (this) {
11254                if (proc.debugging) {
11255                    return false;
11256                }
11257
11258                if (mDidDexOpt) {
11259                    // Give more time since we were dexopting.
11260                    mDidDexOpt = false;
11261                    return false;
11262                }
11263
11264                if (proc.instrumentationClass != null) {
11265                    Bundle info = new Bundle();
11266                    info.putString("shortMsg", "keyDispatchingTimedOut");
11267                    info.putString("longMsg", annotation);
11268                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11269                    return true;
11270                }
11271            }
11272            mHandler.post(new Runnable() {
11273                @Override
11274                public void run() {
11275                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
11276                }
11277            });
11278        }
11279
11280        return true;
11281    }
11282
11283    @Override
11284    public Bundle getAssistContextExtras(int requestType) {
11285        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11286                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11287        if (pae == null) {
11288            return null;
11289        }
11290        synchronized (pae) {
11291            while (!pae.haveResult) {
11292                try {
11293                    pae.wait();
11294                } catch (InterruptedException e) {
11295                }
11296            }
11297        }
11298        synchronized (this) {
11299            buildAssistBundleLocked(pae, pae.result);
11300            mPendingAssistExtras.remove(pae);
11301            mUiHandler.removeCallbacks(pae);
11302        }
11303        return pae.extras;
11304    }
11305
11306    @Override
11307    public boolean isAssistDataAllowedOnCurrentActivity() {
11308        int userId;
11309        synchronized (this) {
11310            userId = mUserController.getCurrentUserIdLocked();
11311            ActivityRecord activity = getFocusedStack().topActivity();
11312            if (activity == null) {
11313                return false;
11314            }
11315            userId = activity.userId;
11316        }
11317        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11318                Context.DEVICE_POLICY_SERVICE);
11319        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11320    }
11321
11322    @Override
11323    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11324        long ident = Binder.clearCallingIdentity();
11325        try {
11326            synchronized (this) {
11327                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11328                ActivityRecord top = getFocusedStack().topActivity();
11329                if (top != caller) {
11330                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11331                            + " is not current top " + top);
11332                    return false;
11333                }
11334                if (!top.nowVisible) {
11335                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11336                            + " is not visible");
11337                    return false;
11338                }
11339            }
11340            AssistUtils utils = new AssistUtils(mContext);
11341            return utils.showSessionForActiveService(args,
11342                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11343        } finally {
11344            Binder.restoreCallingIdentity(ident);
11345        }
11346    }
11347
11348    @Override
11349    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11350            IBinder activityToken) {
11351        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11352                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11353    }
11354
11355    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11356            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11357            long timeout) {
11358        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11359                "enqueueAssistContext()");
11360        synchronized (this) {
11361            ActivityRecord activity = getFocusedStack().topActivity();
11362            if (activity == null) {
11363                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11364                return null;
11365            }
11366            if (activity.app == null || activity.app.thread == null) {
11367                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11368                return null;
11369            }
11370            if (activityToken != null) {
11371                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11372                if (activity != caller) {
11373                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11374                            + " is not current top " + activity);
11375                    return null;
11376                }
11377            }
11378            PendingAssistExtras pae;
11379            Bundle extras = new Bundle();
11380            if (args != null) {
11381                extras.putAll(args);
11382            }
11383            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11384            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11385            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11386            try {
11387                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11388                        requestType);
11389                mPendingAssistExtras.add(pae);
11390                mUiHandler.postDelayed(pae, timeout);
11391            } catch (RemoteException e) {
11392                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11393                return null;
11394            }
11395            return pae;
11396        }
11397    }
11398
11399    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11400        IResultReceiver receiver;
11401        synchronized (this) {
11402            mPendingAssistExtras.remove(pae);
11403            receiver = pae.receiver;
11404        }
11405        if (receiver != null) {
11406            // Caller wants result sent back to them.
11407            try {
11408                pae.receiver.send(0, null);
11409            } catch (RemoteException e) {
11410            }
11411        }
11412    }
11413
11414    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11415        if (result != null) {
11416            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11417        }
11418        if (pae.hint != null) {
11419            pae.extras.putBoolean(pae.hint, true);
11420        }
11421    }
11422
11423    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11424            AssistContent content, Uri referrer) {
11425        PendingAssistExtras pae = (PendingAssistExtras)token;
11426        synchronized (pae) {
11427            pae.result = extras;
11428            pae.structure = structure;
11429            pae.content = content;
11430            if (referrer != null) {
11431                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11432            }
11433            pae.haveResult = true;
11434            pae.notifyAll();
11435            if (pae.intent == null && pae.receiver == null) {
11436                // Caller is just waiting for the result.
11437                return;
11438            }
11439        }
11440
11441        // We are now ready to launch the assist activity.
11442        IResultReceiver sendReceiver = null;
11443        Bundle sendBundle = null;
11444        synchronized (this) {
11445            buildAssistBundleLocked(pae, extras);
11446            boolean exists = mPendingAssistExtras.remove(pae);
11447            mUiHandler.removeCallbacks(pae);
11448            if (!exists) {
11449                // Timed out.
11450                return;
11451            }
11452            if ((sendReceiver=pae.receiver) != null) {
11453                // Caller wants result sent back to them.
11454                sendBundle = new Bundle();
11455                sendBundle.putBundle("data", pae.extras);
11456                sendBundle.putParcelable("structure", pae.structure);
11457                sendBundle.putParcelable("content", pae.content);
11458            }
11459        }
11460        if (sendReceiver != null) {
11461            try {
11462                sendReceiver.send(0, sendBundle);
11463            } catch (RemoteException e) {
11464            }
11465            return;
11466        }
11467
11468        long ident = Binder.clearCallingIdentity();
11469        try {
11470            pae.intent.replaceExtras(pae.extras);
11471            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11472                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
11473                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11474            closeSystemDialogs("assist");
11475            try {
11476                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11477            } catch (ActivityNotFoundException e) {
11478                Slog.w(TAG, "No activity to handle assist action.", e);
11479            }
11480        } finally {
11481            Binder.restoreCallingIdentity(ident);
11482        }
11483    }
11484
11485    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
11486            Bundle args) {
11487        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
11488                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
11489    }
11490
11491    public void registerProcessObserver(IProcessObserver observer) {
11492        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11493                "registerProcessObserver()");
11494        synchronized (this) {
11495            mProcessObservers.register(observer);
11496        }
11497    }
11498
11499    @Override
11500    public void unregisterProcessObserver(IProcessObserver observer) {
11501        synchronized (this) {
11502            mProcessObservers.unregister(observer);
11503        }
11504    }
11505
11506    @Override
11507    public void registerUidObserver(IUidObserver observer, int which) {
11508        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11509                "registerUidObserver()");
11510        synchronized (this) {
11511            mUidObservers.register(observer, which);
11512        }
11513    }
11514
11515    @Override
11516    public void unregisterUidObserver(IUidObserver observer) {
11517        synchronized (this) {
11518            mUidObservers.unregister(observer);
11519        }
11520    }
11521
11522    @Override
11523    public boolean convertFromTranslucent(IBinder token) {
11524        final long origId = Binder.clearCallingIdentity();
11525        try {
11526            synchronized (this) {
11527                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11528                if (r == null) {
11529                    return false;
11530                }
11531                final boolean translucentChanged = r.changeWindowTranslucency(true);
11532                if (translucentChanged) {
11533                    r.task.stack.releaseBackgroundResources(r);
11534                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11535                }
11536                mWindowManager.setAppFullscreen(token, true);
11537                return translucentChanged;
11538            }
11539        } finally {
11540            Binder.restoreCallingIdentity(origId);
11541        }
11542    }
11543
11544    @Override
11545    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11546        final long origId = Binder.clearCallingIdentity();
11547        try {
11548            synchronized (this) {
11549                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11550                if (r == null) {
11551                    return false;
11552                }
11553                int index = r.task.mActivities.lastIndexOf(r);
11554                if (index > 0) {
11555                    ActivityRecord under = r.task.mActivities.get(index - 1);
11556                    under.returningOptions = options;
11557                }
11558                final boolean translucentChanged = r.changeWindowTranslucency(false);
11559                if (translucentChanged) {
11560                    r.task.stack.convertActivityToTranslucent(r);
11561                }
11562                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11563                mWindowManager.setAppFullscreen(token, false);
11564                return translucentChanged;
11565            }
11566        } finally {
11567            Binder.restoreCallingIdentity(origId);
11568        }
11569    }
11570
11571    @Override
11572    public boolean requestVisibleBehind(IBinder token, boolean visible) {
11573        final long origId = Binder.clearCallingIdentity();
11574        try {
11575            synchronized (this) {
11576                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11577                if (r != null) {
11578                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11579                }
11580            }
11581            return false;
11582        } finally {
11583            Binder.restoreCallingIdentity(origId);
11584        }
11585    }
11586
11587    @Override
11588    public boolean isBackgroundVisibleBehind(IBinder token) {
11589        final long origId = Binder.clearCallingIdentity();
11590        try {
11591            synchronized (this) {
11592                final ActivityStack stack = ActivityRecord.getStackLocked(token);
11593                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11594                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11595                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11596                return visible;
11597            }
11598        } finally {
11599            Binder.restoreCallingIdentity(origId);
11600        }
11601    }
11602
11603    @Override
11604    public ActivityOptions getActivityOptions(IBinder token) {
11605        final long origId = Binder.clearCallingIdentity();
11606        try {
11607            synchronized (this) {
11608                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11609                if (r != null) {
11610                    final ActivityOptions activityOptions = r.pendingOptions;
11611                    r.pendingOptions = null;
11612                    return activityOptions;
11613                }
11614                return null;
11615            }
11616        } finally {
11617            Binder.restoreCallingIdentity(origId);
11618        }
11619    }
11620
11621    @Override
11622    public void setImmersive(IBinder token, boolean immersive) {
11623        synchronized(this) {
11624            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11625            if (r == null) {
11626                throw new IllegalArgumentException();
11627            }
11628            r.immersive = immersive;
11629
11630            // update associated state if we're frontmost
11631            if (r == mFocusedActivity) {
11632                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11633                applyUpdateLockStateLocked(r);
11634            }
11635        }
11636    }
11637
11638    @Override
11639    public boolean isImmersive(IBinder token) {
11640        synchronized (this) {
11641            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11642            if (r == null) {
11643                throw new IllegalArgumentException();
11644            }
11645            return r.immersive;
11646        }
11647    }
11648
11649    public boolean isTopActivityImmersive() {
11650        enforceNotIsolatedCaller("startActivity");
11651        synchronized (this) {
11652            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
11653            return (r != null) ? r.immersive : false;
11654        }
11655    }
11656
11657    @Override
11658    public boolean isTopOfTask(IBinder token) {
11659        synchronized (this) {
11660            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11661            if (r == null) {
11662                throw new IllegalArgumentException();
11663            }
11664            return r.task.getTopActivity() == r;
11665        }
11666    }
11667
11668    public final void enterSafeMode() {
11669        synchronized(this) {
11670            // It only makes sense to do this before the system is ready
11671            // and started launching other packages.
11672            if (!mSystemReady) {
11673                try {
11674                    AppGlobals.getPackageManager().enterSafeMode();
11675                } catch (RemoteException e) {
11676                }
11677            }
11678
11679            mSafeMode = true;
11680        }
11681    }
11682
11683    public final void showSafeModeOverlay() {
11684        View v = LayoutInflater.from(mContext).inflate(
11685                com.android.internal.R.layout.safe_mode, null);
11686        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11687        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11688        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11689        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11690        lp.gravity = Gravity.BOTTOM | Gravity.START;
11691        lp.format = v.getBackground().getOpacity();
11692        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11693                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11694        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11695        ((WindowManager)mContext.getSystemService(
11696                Context.WINDOW_SERVICE)).addView(v, lp);
11697    }
11698
11699    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11700        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11701            return;
11702        }
11703        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11704        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11705        synchronized (stats) {
11706            if (mBatteryStatsService.isOnBattery()) {
11707                mBatteryStatsService.enforceCallingPermission();
11708                int MY_UID = Binder.getCallingUid();
11709                final int uid;
11710                if (sender == null) {
11711                    uid = sourceUid;
11712                } else {
11713                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11714                }
11715                BatteryStatsImpl.Uid.Pkg pkg =
11716                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11717                            sourcePkg != null ? sourcePkg : rec.key.packageName);
11718                pkg.noteWakeupAlarmLocked(tag);
11719            }
11720        }
11721    }
11722
11723    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11724        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11725            return;
11726        }
11727        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11728        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11729        synchronized (stats) {
11730            mBatteryStatsService.enforceCallingPermission();
11731            int MY_UID = Binder.getCallingUid();
11732            final int uid;
11733            if (sender == null) {
11734                uid = sourceUid;
11735            } else {
11736                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11737            }
11738            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11739        }
11740    }
11741
11742    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11743        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11744            return;
11745        }
11746        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11747        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11748        synchronized (stats) {
11749            mBatteryStatsService.enforceCallingPermission();
11750            int MY_UID = Binder.getCallingUid();
11751            final int uid;
11752            if (sender == null) {
11753                uid = sourceUid;
11754            } else {
11755                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11756            }
11757            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11758        }
11759    }
11760
11761    public boolean killPids(int[] pids, String pReason, boolean secure) {
11762        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11763            throw new SecurityException("killPids only available to the system");
11764        }
11765        String reason = (pReason == null) ? "Unknown" : pReason;
11766        // XXX Note: don't acquire main activity lock here, because the window
11767        // manager calls in with its locks held.
11768
11769        boolean killed = false;
11770        synchronized (mPidsSelfLocked) {
11771            int[] types = new int[pids.length];
11772            int worstType = 0;
11773            for (int i=0; i<pids.length; i++) {
11774                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11775                if (proc != null) {
11776                    int type = proc.setAdj;
11777                    types[i] = type;
11778                    if (type > worstType) {
11779                        worstType = type;
11780                    }
11781                }
11782            }
11783
11784            // If the worst oom_adj is somewhere in the cached proc LRU range,
11785            // then constrain it so we will kill all cached procs.
11786            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11787                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11788                worstType = ProcessList.CACHED_APP_MIN_ADJ;
11789            }
11790
11791            // If this is not a secure call, don't let it kill processes that
11792            // are important.
11793            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11794                worstType = ProcessList.SERVICE_ADJ;
11795            }
11796
11797            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11798            for (int i=0; i<pids.length; i++) {
11799                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11800                if (proc == null) {
11801                    continue;
11802                }
11803                int adj = proc.setAdj;
11804                if (adj >= worstType && !proc.killedByAm) {
11805                    proc.kill(reason, true);
11806                    killed = true;
11807                }
11808            }
11809        }
11810        return killed;
11811    }
11812
11813    @Override
11814    public void killUid(int appId, int userId, String reason) {
11815        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11816        synchronized (this) {
11817            final long identity = Binder.clearCallingIdentity();
11818            try {
11819                killPackageProcessesLocked(null, appId, userId,
11820                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11821                        reason != null ? reason : "kill uid");
11822            } finally {
11823                Binder.restoreCallingIdentity(identity);
11824            }
11825        }
11826    }
11827
11828    @Override
11829    public boolean killProcessesBelowForeground(String reason) {
11830        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11831            throw new SecurityException("killProcessesBelowForeground() only available to system");
11832        }
11833
11834        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11835    }
11836
11837    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11838        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11839            throw new SecurityException("killProcessesBelowAdj() only available to system");
11840        }
11841
11842        boolean killed = false;
11843        synchronized (mPidsSelfLocked) {
11844            final int size = mPidsSelfLocked.size();
11845            for (int i = 0; i < size; i++) {
11846                final int pid = mPidsSelfLocked.keyAt(i);
11847                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11848                if (proc == null) continue;
11849
11850                final int adj = proc.setAdj;
11851                if (adj > belowAdj && !proc.killedByAm) {
11852                    proc.kill(reason, true);
11853                    killed = true;
11854                }
11855            }
11856        }
11857        return killed;
11858    }
11859
11860    @Override
11861    public void hang(final IBinder who, boolean allowRestart) {
11862        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11863                != PackageManager.PERMISSION_GRANTED) {
11864            throw new SecurityException("Requires permission "
11865                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11866        }
11867
11868        final IBinder.DeathRecipient death = new DeathRecipient() {
11869            @Override
11870            public void binderDied() {
11871                synchronized (this) {
11872                    notifyAll();
11873                }
11874            }
11875        };
11876
11877        try {
11878            who.linkToDeath(death, 0);
11879        } catch (RemoteException e) {
11880            Slog.w(TAG, "hang: given caller IBinder is already dead.");
11881            return;
11882        }
11883
11884        synchronized (this) {
11885            Watchdog.getInstance().setAllowRestart(allowRestart);
11886            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11887            synchronized (death) {
11888                while (who.isBinderAlive()) {
11889                    try {
11890                        death.wait();
11891                    } catch (InterruptedException e) {
11892                    }
11893                }
11894            }
11895            Watchdog.getInstance().setAllowRestart(true);
11896        }
11897    }
11898
11899    @Override
11900    public void restart() {
11901        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11902                != PackageManager.PERMISSION_GRANTED) {
11903            throw new SecurityException("Requires permission "
11904                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11905        }
11906
11907        Log.i(TAG, "Sending shutdown broadcast...");
11908
11909        BroadcastReceiver br = new BroadcastReceiver() {
11910            @Override public void onReceive(Context context, Intent intent) {
11911                // Now the broadcast is done, finish up the low-level shutdown.
11912                Log.i(TAG, "Shutting down activity manager...");
11913                shutdown(10000);
11914                Log.i(TAG, "Shutdown complete, restarting!");
11915                Process.killProcess(Process.myPid());
11916                System.exit(10);
11917            }
11918        };
11919
11920        // First send the high-level shut down broadcast.
11921        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11922        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11923        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11924        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11925        mContext.sendOrderedBroadcastAsUser(intent,
11926                UserHandle.ALL, null, br, mHandler, 0, null, null);
11927        */
11928        br.onReceive(mContext, intent);
11929    }
11930
11931    private long getLowRamTimeSinceIdle(long now) {
11932        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11933    }
11934
11935    @Override
11936    public void performIdleMaintenance() {
11937        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11938                != PackageManager.PERMISSION_GRANTED) {
11939            throw new SecurityException("Requires permission "
11940                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11941        }
11942
11943        synchronized (this) {
11944            final long now = SystemClock.uptimeMillis();
11945            final long timeSinceLastIdle = now - mLastIdleTime;
11946            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11947            mLastIdleTime = now;
11948            mLowRamTimeSinceLastIdle = 0;
11949            if (mLowRamStartTime != 0) {
11950                mLowRamStartTime = now;
11951            }
11952
11953            StringBuilder sb = new StringBuilder(128);
11954            sb.append("Idle maintenance over ");
11955            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11956            sb.append(" low RAM for ");
11957            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11958            Slog.i(TAG, sb.toString());
11959
11960            // If at least 1/3 of our time since the last idle period has been spent
11961            // with RAM low, then we want to kill processes.
11962            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11963
11964            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11965                ProcessRecord proc = mLruProcesses.get(i);
11966                if (proc.notCachedSinceIdle) {
11967                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11968                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11969                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11970                        if (doKilling && proc.initialIdlePss != 0
11971                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11972                            sb = new StringBuilder(128);
11973                            sb.append("Kill");
11974                            sb.append(proc.processName);
11975                            sb.append(" in idle maint: pss=");
11976                            sb.append(proc.lastPss);
11977                            sb.append(", initialPss=");
11978                            sb.append(proc.initialIdlePss);
11979                            sb.append(", period=");
11980                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11981                            sb.append(", lowRamPeriod=");
11982                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11983                            Slog.wtfQuiet(TAG, sb.toString());
11984                            proc.kill("idle maint (pss " + proc.lastPss
11985                                    + " from " + proc.initialIdlePss + ")", true);
11986                        }
11987                    }
11988                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11989                    proc.notCachedSinceIdle = true;
11990                    proc.initialIdlePss = 0;
11991                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11992                            mTestPssMode, isSleeping(), now);
11993                }
11994            }
11995
11996            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11997            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11998        }
11999    }
12000
12001    private void retrieveSettings() {
12002        final ContentResolver resolver = mContext.getContentResolver();
12003        final boolean freeformWindowManagement =
12004                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT);
12005
12006        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12007        final String fsScreenshots = Settings.Secure.getString(resolver,
12008                "overview_fullscreen_thumbnails");
12009        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12010        final boolean alwaysFinishActivities =
12011                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12012        final boolean takeFullscreenScreenshots = fsScreenshots != null &&
12013                Integer.parseInt(fsScreenshots) != 0;
12014        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12015        final int defaultForceResizable = Build.IS_DEBUGGABLE ? 1 : 0;
12016        final boolean forceResizable = Settings.Global.getInt(
12017                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, defaultForceResizable) != 0;
12018        // Transfer any global setting for forcing RTL layout, into a System Property
12019        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12020
12021        final Configuration configuration = new Configuration();
12022        Settings.System.getConfiguration(resolver, configuration);
12023        if (forceRtl) {
12024            // This will take care of setting the correct layout direction flags
12025            configuration.setLayoutDirection(configuration.locale);
12026        }
12027
12028        synchronized (this) {
12029            mDebugApp = mOrigDebugApp = debugApp;
12030            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12031            mAlwaysFinishActivities = alwaysFinishActivities;
12032            mForceResizableActivities = forceResizable;
12033            mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12034            mTakeFullscreenScreenshots = takeFullscreenScreenshots;
12035            // This happens before any activities are started, so we can
12036            // change mConfiguration in-place.
12037            updateConfigurationLocked(configuration, null, true);
12038            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12039                    "Initial config: " + mConfiguration);
12040        }
12041    }
12042
12043    /** Loads resources after the current configuration has been set. */
12044    private void loadResourcesOnSystemReady() {
12045        final Resources res = mContext.getResources();
12046        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12047        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
12048        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
12049    }
12050
12051    public boolean testIsSystemReady() {
12052        // no need to synchronize(this) just to read & return the value
12053        return mSystemReady;
12054    }
12055
12056    private static File getCalledPreBootReceiversFile() {
12057        File dataDir = Environment.getDataDirectory();
12058        File systemDir = new File(dataDir, "system");
12059        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
12060        return fname;
12061    }
12062
12063    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
12064        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
12065        File file = getCalledPreBootReceiversFile();
12066        FileInputStream fis = null;
12067        try {
12068            fis = new FileInputStream(file);
12069            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
12070            int fvers = dis.readInt();
12071            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
12072                String vers = dis.readUTF();
12073                String codename = dis.readUTF();
12074                String build = dis.readUTF();
12075                if (android.os.Build.VERSION.RELEASE.equals(vers)
12076                        && android.os.Build.VERSION.CODENAME.equals(codename)
12077                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
12078                    int num = dis.readInt();
12079                    while (num > 0) {
12080                        num--;
12081                        String pkg = dis.readUTF();
12082                        String cls = dis.readUTF();
12083                        lastDoneReceivers.add(new ComponentName(pkg, cls));
12084                    }
12085                }
12086            }
12087        } catch (FileNotFoundException e) {
12088        } catch (IOException e) {
12089            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
12090        } finally {
12091            if (fis != null) {
12092                try {
12093                    fis.close();
12094                } catch (IOException e) {
12095                }
12096            }
12097        }
12098        return lastDoneReceivers;
12099    }
12100
12101    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
12102        File file = getCalledPreBootReceiversFile();
12103        FileOutputStream fos = null;
12104        DataOutputStream dos = null;
12105        try {
12106            fos = new FileOutputStream(file);
12107            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
12108            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
12109            dos.writeUTF(android.os.Build.VERSION.RELEASE);
12110            dos.writeUTF(android.os.Build.VERSION.CODENAME);
12111            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
12112            dos.writeInt(list.size());
12113            for (int i=0; i<list.size(); i++) {
12114                dos.writeUTF(list.get(i).getPackageName());
12115                dos.writeUTF(list.get(i).getClassName());
12116            }
12117        } catch (IOException e) {
12118            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
12119            file.delete();
12120        } finally {
12121            FileUtils.sync(fos);
12122            if (dos != null) {
12123                try {
12124                    dos.close();
12125                } catch (IOException e) {
12126                    // TODO Auto-generated catch block
12127                    e.printStackTrace();
12128                }
12129            }
12130        }
12131    }
12132
12133    final class PreBootContinuation extends IIntentReceiver.Stub {
12134        final Intent intent;
12135        final Runnable onFinishCallback;
12136        final ArrayList<ComponentName> doneReceivers;
12137        final List<ResolveInfo> ris;
12138        final int[] users;
12139        int lastRi = -1;
12140        int curRi = 0;
12141        int curUser = 0;
12142
12143        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
12144                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
12145            intent = _intent;
12146            onFinishCallback = _onFinishCallback;
12147            doneReceivers = _doneReceivers;
12148            ris = _ris;
12149            users = _users;
12150        }
12151
12152        void go() {
12153            if (lastRi != curRi) {
12154                ActivityInfo ai = ris.get(curRi).activityInfo;
12155                ComponentName comp = new ComponentName(ai.packageName, ai.name);
12156                intent.setComponent(comp);
12157                doneReceivers.add(comp);
12158                lastRi = curRi;
12159                CharSequence label = ai.loadLabel(mContext.getPackageManager());
12160                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
12161            }
12162            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
12163                    + " for user " + users[curUser]);
12164            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
12165            broadcastIntentLocked(null, null, intent, null, this,
12166                    0, null, null, null, AppOpsManager.OP_NONE,
12167                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
12168        }
12169
12170        public void performReceive(Intent intent, int resultCode,
12171                String data, Bundle extras, boolean ordered,
12172                boolean sticky, int sendingUser) {
12173            curUser++;
12174            if (curUser >= users.length) {
12175                curUser = 0;
12176                curRi++;
12177                if (curRi >= ris.size()) {
12178                    // All done sending broadcasts!
12179                    if (onFinishCallback != null) {
12180                        // The raw IIntentReceiver interface is called
12181                        // with the AM lock held, so redispatch to
12182                        // execute our code without the lock.
12183                        mHandler.post(onFinishCallback);
12184                    }
12185                    return;
12186                }
12187            }
12188            go();
12189        }
12190    }
12191
12192    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
12193            ArrayList<ComponentName> doneReceivers) {
12194        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
12195        List<ResolveInfo> ris = null;
12196        try {
12197            ris = AppGlobals.getPackageManager().queryIntentReceivers(
12198                    intent, null, 0, UserHandle.USER_SYSTEM);
12199        } catch (RemoteException e) {
12200        }
12201        if (ris == null) {
12202            return false;
12203        }
12204        for (int i=ris.size()-1; i>=0; i--) {
12205            if ((ris.get(i).activityInfo.applicationInfo.flags
12206                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
12207                ris.remove(i);
12208            }
12209        }
12210        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
12211
12212        ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
12213        for (int i=0; i<ris.size(); i++) {
12214            ActivityInfo ai = ris.get(i).activityInfo;
12215            ComponentName comp = new ComponentName(ai.packageName, ai.name);
12216            if (lastDoneReceivers.contains(comp)) {
12217                // We already did the pre boot receiver for this app with the current
12218                // platform version, so don't do it again...
12219                ris.remove(i);
12220                i--;
12221                // ...however, do keep it as one that has been done, so we don't
12222                // forget about it when rewriting the file of last done receivers.
12223                doneReceivers.add(comp);
12224            }
12225        }
12226
12227        if (ris.size() <= 0) {
12228            return false;
12229        }
12230
12231        // TODO: can we still do this with per user encryption?
12232        final int[] users = mUserController.getUsers();
12233        if (users.length <= 0) {
12234            return false;
12235        }
12236
12237        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
12238                ris, users);
12239        cont.go();
12240        return true;
12241    }
12242
12243    public void systemReady(final Runnable goingCallback) {
12244        synchronized(this) {
12245            if (mSystemReady) {
12246                // If we're done calling all the receivers, run the next "boot phase" passed in
12247                // by the SystemServer
12248                if (goingCallback != null) {
12249                    goingCallback.run();
12250                }
12251                return;
12252            }
12253
12254            mLocalDeviceIdleController
12255                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12256
12257            // Make sure we have the current profile info, since it is needed for
12258            // security checks.
12259            mUserController.updateCurrentProfileIdsLocked();
12260
12261            mRecentTasks.clear();
12262            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked(mUserController.getUserIds()));
12263            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
12264            mTaskPersister.startPersisting();
12265
12266            // Check to see if there are any update receivers to run.
12267            if (!mDidUpdate) {
12268                if (mWaitingUpdate) {
12269                    return;
12270                }
12271                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
12272                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
12273                    public void run() {
12274                        synchronized (ActivityManagerService.this) {
12275                            mDidUpdate = true;
12276                        }
12277                        showBootMessage(mContext.getText(
12278                                R.string.android_upgrading_complete),
12279                                false);
12280                        writeLastDonePreBootReceivers(doneReceivers);
12281                        systemReady(goingCallback);
12282                    }
12283                }, doneReceivers);
12284
12285                if (mWaitingUpdate) {
12286                    return;
12287                }
12288                mDidUpdate = true;
12289            }
12290
12291            mAppOpsService.systemReady();
12292            mSystemReady = true;
12293        }
12294
12295        ArrayList<ProcessRecord> procsToKill = null;
12296        synchronized(mPidsSelfLocked) {
12297            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12298                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12299                if (!isAllowedWhileBooting(proc.info)){
12300                    if (procsToKill == null) {
12301                        procsToKill = new ArrayList<ProcessRecord>();
12302                    }
12303                    procsToKill.add(proc);
12304                }
12305            }
12306        }
12307
12308        synchronized(this) {
12309            if (procsToKill != null) {
12310                for (int i=procsToKill.size()-1; i>=0; i--) {
12311                    ProcessRecord proc = procsToKill.get(i);
12312                    Slog.i(TAG, "Removing system update proc: " + proc);
12313                    removeProcessLocked(proc, true, false, "system update done");
12314                }
12315            }
12316
12317            // Now that we have cleaned up any update processes, we
12318            // are ready to start launching real processes and know that
12319            // we won't trample on them any more.
12320            mProcessesReady = true;
12321        }
12322
12323        Slog.i(TAG, "System now ready");
12324        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12325            SystemClock.uptimeMillis());
12326
12327        synchronized(this) {
12328            // Make sure we have no pre-ready processes sitting around.
12329
12330            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12331                ResolveInfo ri = mContext.getPackageManager()
12332                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12333                                STOCK_PM_FLAGS);
12334                CharSequence errorMsg = null;
12335                if (ri != null) {
12336                    ActivityInfo ai = ri.activityInfo;
12337                    ApplicationInfo app = ai.applicationInfo;
12338                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12339                        mTopAction = Intent.ACTION_FACTORY_TEST;
12340                        mTopData = null;
12341                        mTopComponent = new ComponentName(app.packageName,
12342                                ai.name);
12343                    } else {
12344                        errorMsg = mContext.getResources().getText(
12345                                com.android.internal.R.string.factorytest_not_system);
12346                    }
12347                } else {
12348                    errorMsg = mContext.getResources().getText(
12349                            com.android.internal.R.string.factorytest_no_action);
12350                }
12351                if (errorMsg != null) {
12352                    mTopAction = null;
12353                    mTopData = null;
12354                    mTopComponent = null;
12355                    Message msg = Message.obtain();
12356                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12357                    msg.getData().putCharSequence("msg", errorMsg);
12358                    mUiHandler.sendMessage(msg);
12359                }
12360            }
12361        }
12362
12363        retrieveSettings();
12364        loadResourcesOnSystemReady();
12365        final int currentUserId;
12366        synchronized (this) {
12367            currentUserId = mUserController.getCurrentUserIdLocked();
12368            readGrantedUriPermissionsLocked();
12369        }
12370
12371        if (goingCallback != null) goingCallback.run();
12372
12373
12374        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12375                Integer.toString(currentUserId), currentUserId);
12376        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12377                Integer.toString(currentUserId), currentUserId);
12378        mSystemServiceManager.startUser(currentUserId);
12379
12380        synchronized (this) {
12381            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12382                try {
12383                    List apps = AppGlobals.getPackageManager().
12384                        getPersistentApplications(STOCK_PM_FLAGS);
12385                    if (apps != null) {
12386                        int N = apps.size();
12387                        int i;
12388                        for (i=0; i<N; i++) {
12389                            ApplicationInfo info
12390                                = (ApplicationInfo)apps.get(i);
12391                            if (info != null &&
12392                                    !info.packageName.equals("android")) {
12393                                addAppLocked(info, false, null /* ABI override */);
12394                            }
12395                        }
12396                    }
12397                } catch (RemoteException ex) {
12398                    // pm is in same process, this will never happen.
12399                }
12400            }
12401
12402            // Start up initial activity.
12403            mBooting = true;
12404            // Enable home activity for system user, so that the system can always boot
12405            if (UserManager.isSplitSystemUser()) {
12406                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12407                try {
12408                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12409                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12410                            UserHandle.USER_SYSTEM);
12411                } catch (RemoteException e) {
12412                    e.rethrowAsRuntimeException();
12413                }
12414            }
12415            startHomeActivityLocked(currentUserId, "systemReady");
12416
12417            try {
12418                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12419                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12420                            + " data partition or your device will be unstable.");
12421                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12422                }
12423            } catch (RemoteException e) {
12424            }
12425
12426            if (!Build.isBuildConsistent()) {
12427                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12428                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12429            }
12430
12431            long ident = Binder.clearCallingIdentity();
12432            try {
12433                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12434                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12435                        | Intent.FLAG_RECEIVER_FOREGROUND);
12436                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12437                broadcastIntentLocked(null, null, intent,
12438                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12439                        null, false, false, MY_PID, Process.SYSTEM_UID,
12440                        currentUserId);
12441                intent = new Intent(Intent.ACTION_USER_STARTING);
12442                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12443                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12444                broadcastIntentLocked(null, null, intent,
12445                        null, new IIntentReceiver.Stub() {
12446                            @Override
12447                            public void performReceive(Intent intent, int resultCode, String data,
12448                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12449                                    throws RemoteException {
12450                            }
12451                        }, 0, null, null,
12452                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12453                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12454            } catch (Throwable t) {
12455                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12456            } finally {
12457                Binder.restoreCallingIdentity(ident);
12458            }
12459            mStackSupervisor.resumeTopActivitiesLocked();
12460            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12461        }
12462    }
12463
12464    private boolean makeAppCrashingLocked(ProcessRecord app,
12465            String shortMsg, String longMsg, String stackTrace) {
12466        app.crashing = true;
12467        app.crashingReport = generateProcessError(app,
12468                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
12469        startAppProblemLocked(app);
12470        app.stopFreezingAllLocked();
12471        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
12472    }
12473
12474    private void makeAppNotRespondingLocked(ProcessRecord app,
12475            String activity, String shortMsg, String longMsg) {
12476        app.notResponding = true;
12477        app.notRespondingReport = generateProcessError(app,
12478                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
12479                activity, shortMsg, longMsg, null);
12480        startAppProblemLocked(app);
12481        app.stopFreezingAllLocked();
12482    }
12483
12484    /**
12485     * Generate a process error record, suitable for attachment to a ProcessRecord.
12486     *
12487     * @param app The ProcessRecord in which the error occurred.
12488     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
12489     *                      ActivityManager.AppErrorStateInfo
12490     * @param activity The activity associated with the crash, if known.
12491     * @param shortMsg Short message describing the crash.
12492     * @param longMsg Long message describing the crash.
12493     * @param stackTrace Full crash stack trace, may be null.
12494     *
12495     * @return Returns a fully-formed AppErrorStateInfo record.
12496     */
12497    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
12498            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
12499        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
12500
12501        report.condition = condition;
12502        report.processName = app.processName;
12503        report.pid = app.pid;
12504        report.uid = app.info.uid;
12505        report.tag = activity;
12506        report.shortMsg = shortMsg;
12507        report.longMsg = longMsg;
12508        report.stackTrace = stackTrace;
12509
12510        return report;
12511    }
12512
12513    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12514        synchronized (this) {
12515            app.crashing = false;
12516            app.crashingReport = null;
12517            app.notResponding = false;
12518            app.notRespondingReport = null;
12519            if (app.anrDialog == fromDialog) {
12520                app.anrDialog = null;
12521            }
12522            if (app.waitDialog == fromDialog) {
12523                app.waitDialog = null;
12524            }
12525            if (app.pid > 0 && app.pid != MY_PID) {
12526                handleAppCrashLocked(app, "user-terminated" /*reason*/,
12527                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
12528                app.kill("user request after error", true);
12529            }
12530        }
12531    }
12532
12533    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
12534            String shortMsg, String longMsg, String stackTrace) {
12535        long now = SystemClock.uptimeMillis();
12536
12537        Long crashTime;
12538        if (!app.isolated) {
12539            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
12540        } else {
12541            crashTime = null;
12542        }
12543        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
12544            // This process loses!
12545            Slog.w(TAG, "Process " + app.info.processName
12546                    + " has crashed too many times: killing!");
12547            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
12548                    app.userId, app.info.processName, app.uid);
12549            mStackSupervisor.handleAppCrashLocked(app);
12550            if (!app.persistent) {
12551                // We don't want to start this process again until the user
12552                // explicitly does so...  but for persistent process, we really
12553                // need to keep it running.  If a persistent process is actually
12554                // repeatedly crashing, then badness for everyone.
12555                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
12556                        app.info.processName);
12557                if (!app.isolated) {
12558                    // XXX We don't have a way to mark isolated processes
12559                    // as bad, since they don't have a peristent identity.
12560                    mBadProcesses.put(app.info.processName, app.uid,
12561                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
12562                    mProcessCrashTimes.remove(app.info.processName, app.uid);
12563                }
12564                app.bad = true;
12565                app.removed = true;
12566                // Don't let services in this process be restarted and potentially
12567                // annoy the user repeatedly.  Unless it is persistent, since those
12568                // processes run critical code.
12569                removeProcessLocked(app, false, false, "crash");
12570                mStackSupervisor.resumeTopActivitiesLocked();
12571                return false;
12572            }
12573            mStackSupervisor.resumeTopActivitiesLocked();
12574        } else {
12575            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
12576        }
12577
12578        // Bump up the crash count of any services currently running in the proc.
12579        for (int i=app.services.size()-1; i>=0; i--) {
12580            // Any services running in the application need to be placed
12581            // back in the pending list.
12582            ServiceRecord sr = app.services.valueAt(i);
12583            sr.crashCount++;
12584        }
12585
12586        // If the crashing process is what we consider to be the "home process" and it has been
12587        // replaced by a third-party app, clear the package preferred activities from packages
12588        // with a home activity running in the process to prevent a repeatedly crashing app
12589        // from blocking the user to manually clear the list.
12590        final ArrayList<ActivityRecord> activities = app.activities;
12591        if (app == mHomeProcess && activities.size() > 0
12592                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
12593            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
12594                final ActivityRecord r = activities.get(activityNdx);
12595                if (r.isHomeActivity()) {
12596                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
12597                    try {
12598                        ActivityThread.getPackageManager()
12599                                .clearPackagePreferredActivities(r.packageName);
12600                    } catch (RemoteException c) {
12601                        // pm is in same process, this will never happen.
12602                    }
12603                }
12604            }
12605        }
12606
12607        if (!app.isolated) {
12608            // XXX Can't keep track of crash times for isolated processes,
12609            // because they don't have a perisistent identity.
12610            mProcessCrashTimes.put(app.info.processName, app.uid, now);
12611        }
12612
12613        if (app.crashHandler != null) mHandler.post(app.crashHandler);
12614        return true;
12615    }
12616
12617    void startAppProblemLocked(ProcessRecord app) {
12618        // If this app is not running under the current user, then we
12619        // can't give it a report button because that would require
12620        // launching the report UI under a different user.
12621        app.errorReportReceiver = null;
12622
12623        for (int userId : mUserController.getCurrentProfileIdsLocked()) {
12624            if (app.userId == userId) {
12625                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12626                        mContext, app.info.packageName, app.info.flags);
12627            }
12628        }
12629        skipCurrentReceiverLocked(app);
12630    }
12631
12632    void skipCurrentReceiverLocked(ProcessRecord app) {
12633        for (BroadcastQueue queue : mBroadcastQueues) {
12634            queue.skipCurrentReceiverLocked(app);
12635        }
12636    }
12637
12638    /**
12639     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12640     * The application process will exit immediately after this call returns.
12641     * @param app object of the crashing app, null for the system server
12642     * @param crashInfo describing the exception
12643     */
12644    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12645        ProcessRecord r = findAppProcess(app, "Crash");
12646        final String processName = app == null ? "system_server"
12647                : (r == null ? "unknown" : r.processName);
12648
12649        handleApplicationCrashInner("crash", r, processName, crashInfo);
12650    }
12651
12652    /* Native crash reporting uses this inner version because it needs to be somewhat
12653     * decoupled from the AM-managed cleanup lifecycle
12654     */
12655    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12656            ApplicationErrorReport.CrashInfo crashInfo) {
12657        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12658                UserHandle.getUserId(Binder.getCallingUid()), processName,
12659                r == null ? -1 : r.info.flags,
12660                crashInfo.exceptionClassName,
12661                crashInfo.exceptionMessage,
12662                crashInfo.throwFileName,
12663                crashInfo.throwLineNumber);
12664
12665        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12666
12667        crashApplication(r, crashInfo);
12668    }
12669
12670    public void handleApplicationStrictModeViolation(
12671            IBinder app,
12672            int violationMask,
12673            StrictMode.ViolationInfo info) {
12674        ProcessRecord r = findAppProcess(app, "StrictMode");
12675        if (r == null) {
12676            return;
12677        }
12678
12679        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12680            Integer stackFingerprint = info.hashCode();
12681            boolean logIt = true;
12682            synchronized (mAlreadyLoggedViolatedStacks) {
12683                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12684                    logIt = false;
12685                    // TODO: sub-sample into EventLog for these, with
12686                    // the info.durationMillis?  Then we'd get
12687                    // the relative pain numbers, without logging all
12688                    // the stack traces repeatedly.  We'd want to do
12689                    // likewise in the client code, which also does
12690                    // dup suppression, before the Binder call.
12691                } else {
12692                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12693                        mAlreadyLoggedViolatedStacks.clear();
12694                    }
12695                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12696                }
12697            }
12698            if (logIt) {
12699                logStrictModeViolationToDropBox(r, info);
12700            }
12701        }
12702
12703        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12704            AppErrorResult result = new AppErrorResult();
12705            synchronized (this) {
12706                final long origId = Binder.clearCallingIdentity();
12707
12708                Message msg = Message.obtain();
12709                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12710                HashMap<String, Object> data = new HashMap<String, Object>();
12711                data.put("result", result);
12712                data.put("app", r);
12713                data.put("violationMask", violationMask);
12714                data.put("info", info);
12715                msg.obj = data;
12716                mUiHandler.sendMessage(msg);
12717
12718                Binder.restoreCallingIdentity(origId);
12719            }
12720            int res = result.get();
12721            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12722        }
12723    }
12724
12725    // Depending on the policy in effect, there could be a bunch of
12726    // these in quick succession so we try to batch these together to
12727    // minimize disk writes, number of dropbox entries, and maximize
12728    // compression, by having more fewer, larger records.
12729    private void logStrictModeViolationToDropBox(
12730            ProcessRecord process,
12731            StrictMode.ViolationInfo info) {
12732        if (info == null) {
12733            return;
12734        }
12735        final boolean isSystemApp = process == null ||
12736                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12737                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12738        final String processName = process == null ? "unknown" : process.processName;
12739        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12740        final DropBoxManager dbox = (DropBoxManager)
12741                mContext.getSystemService(Context.DROPBOX_SERVICE);
12742
12743        // Exit early if the dropbox isn't configured to accept this report type.
12744        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12745
12746        boolean bufferWasEmpty;
12747        boolean needsFlush;
12748        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12749        synchronized (sb) {
12750            bufferWasEmpty = sb.length() == 0;
12751            appendDropBoxProcessHeaders(process, processName, sb);
12752            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12753            sb.append("System-App: ").append(isSystemApp).append("\n");
12754            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12755            if (info.violationNumThisLoop != 0) {
12756                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12757            }
12758            if (info.numAnimationsRunning != 0) {
12759                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12760            }
12761            if (info.broadcastIntentAction != null) {
12762                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12763            }
12764            if (info.durationMillis != -1) {
12765                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12766            }
12767            if (info.numInstances != -1) {
12768                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12769            }
12770            if (info.tags != null) {
12771                for (String tag : info.tags) {
12772                    sb.append("Span-Tag: ").append(tag).append("\n");
12773                }
12774            }
12775            sb.append("\n");
12776            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12777                sb.append(info.crashInfo.stackTrace);
12778                sb.append("\n");
12779            }
12780            if (info.message != null) {
12781                sb.append(info.message);
12782                sb.append("\n");
12783            }
12784
12785            // Only buffer up to ~64k.  Various logging bits truncate
12786            // things at 128k.
12787            needsFlush = (sb.length() > 64 * 1024);
12788        }
12789
12790        // Flush immediately if the buffer's grown too large, or this
12791        // is a non-system app.  Non-system apps are isolated with a
12792        // different tag & policy and not batched.
12793        //
12794        // Batching is useful during internal testing with
12795        // StrictMode settings turned up high.  Without batching,
12796        // thousands of separate files could be created on boot.
12797        if (!isSystemApp || needsFlush) {
12798            new Thread("Error dump: " + dropboxTag) {
12799                @Override
12800                public void run() {
12801                    String report;
12802                    synchronized (sb) {
12803                        report = sb.toString();
12804                        sb.delete(0, sb.length());
12805                        sb.trimToSize();
12806                    }
12807                    if (report.length() != 0) {
12808                        dbox.addText(dropboxTag, report);
12809                    }
12810                }
12811            }.start();
12812            return;
12813        }
12814
12815        // System app batching:
12816        if (!bufferWasEmpty) {
12817            // An existing dropbox-writing thread is outstanding, so
12818            // we don't need to start it up.  The existing thread will
12819            // catch the buffer appends we just did.
12820            return;
12821        }
12822
12823        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12824        // (After this point, we shouldn't access AMS internal data structures.)
12825        new Thread("Error dump: " + dropboxTag) {
12826            @Override
12827            public void run() {
12828                // 5 second sleep to let stacks arrive and be batched together
12829                try {
12830                    Thread.sleep(5000);  // 5 seconds
12831                } catch (InterruptedException e) {}
12832
12833                String errorReport;
12834                synchronized (mStrictModeBuffer) {
12835                    errorReport = mStrictModeBuffer.toString();
12836                    if (errorReport.length() == 0) {
12837                        return;
12838                    }
12839                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12840                    mStrictModeBuffer.trimToSize();
12841                }
12842                dbox.addText(dropboxTag, errorReport);
12843            }
12844        }.start();
12845    }
12846
12847    /**
12848     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12849     * @param app object of the crashing app, null for the system server
12850     * @param tag reported by the caller
12851     * @param system whether this wtf is coming from the system
12852     * @param crashInfo describing the context of the error
12853     * @return true if the process should exit immediately (WTF is fatal)
12854     */
12855    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12856            final ApplicationErrorReport.CrashInfo crashInfo) {
12857        final int callingUid = Binder.getCallingUid();
12858        final int callingPid = Binder.getCallingPid();
12859
12860        if (system) {
12861            // If this is coming from the system, we could very well have low-level
12862            // system locks held, so we want to do this all asynchronously.  And we
12863            // never want this to become fatal, so there is that too.
12864            mHandler.post(new Runnable() {
12865                @Override public void run() {
12866                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12867                }
12868            });
12869            return false;
12870        }
12871
12872        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12873                crashInfo);
12874
12875        if (r != null && r.pid != Process.myPid() &&
12876                Settings.Global.getInt(mContext.getContentResolver(),
12877                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
12878            crashApplication(r, crashInfo);
12879            return true;
12880        } else {
12881            return false;
12882        }
12883    }
12884
12885    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12886            final ApplicationErrorReport.CrashInfo crashInfo) {
12887        final ProcessRecord r = findAppProcess(app, "WTF");
12888        final String processName = app == null ? "system_server"
12889                : (r == null ? "unknown" : r.processName);
12890
12891        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12892                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12893
12894        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12895
12896        return r;
12897    }
12898
12899    /**
12900     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12901     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12902     */
12903    private ProcessRecord findAppProcess(IBinder app, String reason) {
12904        if (app == null) {
12905            return null;
12906        }
12907
12908        synchronized (this) {
12909            final int NP = mProcessNames.getMap().size();
12910            for (int ip=0; ip<NP; ip++) {
12911                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12912                final int NA = apps.size();
12913                for (int ia=0; ia<NA; ia++) {
12914                    ProcessRecord p = apps.valueAt(ia);
12915                    if (p.thread != null && p.thread.asBinder() == app) {
12916                        return p;
12917                    }
12918                }
12919            }
12920
12921            Slog.w(TAG, "Can't find mystery application for " + reason
12922                    + " from pid=" + Binder.getCallingPid()
12923                    + " uid=" + Binder.getCallingUid() + ": " + app);
12924            return null;
12925        }
12926    }
12927
12928    /**
12929     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12930     * to append various headers to the dropbox log text.
12931     */
12932    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12933            StringBuilder sb) {
12934        // Watchdog thread ends up invoking this function (with
12935        // a null ProcessRecord) to add the stack file to dropbox.
12936        // Do not acquire a lock on this (am) in such cases, as it
12937        // could cause a potential deadlock, if and when watchdog
12938        // is invoked due to unavailability of lock on am and it
12939        // would prevent watchdog from killing system_server.
12940        if (process == null) {
12941            sb.append("Process: ").append(processName).append("\n");
12942            return;
12943        }
12944        // Note: ProcessRecord 'process' is guarded by the service
12945        // instance.  (notably process.pkgList, which could otherwise change
12946        // concurrently during execution of this method)
12947        synchronized (this) {
12948            sb.append("Process: ").append(processName).append("\n");
12949            int flags = process.info.flags;
12950            IPackageManager pm = AppGlobals.getPackageManager();
12951            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12952            for (int ip=0; ip<process.pkgList.size(); ip++) {
12953                String pkg = process.pkgList.keyAt(ip);
12954                sb.append("Package: ").append(pkg);
12955                try {
12956                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12957                    if (pi != null) {
12958                        sb.append(" v").append(pi.versionCode);
12959                        if (pi.versionName != null) {
12960                            sb.append(" (").append(pi.versionName).append(")");
12961                        }
12962                    }
12963                } catch (RemoteException e) {
12964                    Slog.e(TAG, "Error getting package info: " + pkg, e);
12965                }
12966                sb.append("\n");
12967            }
12968        }
12969    }
12970
12971    private static String processClass(ProcessRecord process) {
12972        if (process == null || process.pid == MY_PID) {
12973            return "system_server";
12974        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12975            return "system_app";
12976        } else {
12977            return "data_app";
12978        }
12979    }
12980
12981    /**
12982     * Write a description of an error (crash, WTF, ANR) to the drop box.
12983     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12984     * @param process which caused the error, null means the system server
12985     * @param activity which triggered the error, null if unknown
12986     * @param parent activity related to the error, null if unknown
12987     * @param subject line related to the error, null if absent
12988     * @param report in long form describing the error, null if absent
12989     * @param logFile to include in the report, null if none
12990     * @param crashInfo giving an application stack trace, null if absent
12991     */
12992    public void addErrorToDropBox(String eventType,
12993            ProcessRecord process, String processName, ActivityRecord activity,
12994            ActivityRecord parent, String subject,
12995            final String report, final File logFile,
12996            final ApplicationErrorReport.CrashInfo crashInfo) {
12997        // NOTE -- this must never acquire the ActivityManagerService lock,
12998        // otherwise the watchdog may be prevented from resetting the system.
12999
13000        final String dropboxTag = processClass(process) + "_" + eventType;
13001        final DropBoxManager dbox = (DropBoxManager)
13002                mContext.getSystemService(Context.DROPBOX_SERVICE);
13003
13004        // Exit early if the dropbox isn't configured to accept this report type.
13005        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13006
13007        final StringBuilder sb = new StringBuilder(1024);
13008        appendDropBoxProcessHeaders(process, processName, sb);
13009        if (activity != null) {
13010            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13011        }
13012        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13013            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13014        }
13015        if (parent != null && parent != activity) {
13016            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13017        }
13018        if (subject != null) {
13019            sb.append("Subject: ").append(subject).append("\n");
13020        }
13021        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13022        if (Debug.isDebuggerConnected()) {
13023            sb.append("Debugger: Connected\n");
13024        }
13025        sb.append("\n");
13026
13027        // Do the rest in a worker thread to avoid blocking the caller on I/O
13028        // (After this point, we shouldn't access AMS internal data structures.)
13029        Thread worker = new Thread("Error dump: " + dropboxTag) {
13030            @Override
13031            public void run() {
13032                if (report != null) {
13033                    sb.append(report);
13034                }
13035                if (logFile != null) {
13036                    try {
13037                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13038                                    "\n\n[[TRUNCATED]]"));
13039                    } catch (IOException e) {
13040                        Slog.e(TAG, "Error reading " + logFile, e);
13041                    }
13042                }
13043                if (crashInfo != null && crashInfo.stackTrace != null) {
13044                    sb.append(crashInfo.stackTrace);
13045                }
13046
13047                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13048                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13049                if (lines > 0) {
13050                    sb.append("\n");
13051
13052                    // Merge several logcat streams, and take the last N lines
13053                    InputStreamReader input = null;
13054                    try {
13055                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
13056                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
13057                                "-b", "crash",
13058                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
13059
13060                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13061                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13062                        input = new InputStreamReader(logcat.getInputStream());
13063
13064                        int num;
13065                        char[] buf = new char[8192];
13066                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13067                    } catch (IOException e) {
13068                        Slog.e(TAG, "Error running logcat", e);
13069                    } finally {
13070                        if (input != null) try { input.close(); } catch (IOException e) {}
13071                    }
13072                }
13073
13074                dbox.addText(dropboxTag, sb.toString());
13075            }
13076        };
13077
13078        if (process == null) {
13079            // If process is null, we are being called from some internal code
13080            // and may be about to die -- run this synchronously.
13081            worker.run();
13082        } else {
13083            worker.start();
13084        }
13085    }
13086
13087    /**
13088     * Bring up the "unexpected error" dialog box for a crashing app.
13089     * Deal with edge cases (intercepts from instrumented applications,
13090     * ActivityController, error intent receivers, that sort of thing).
13091     * @param r the application crashing
13092     * @param crashInfo describing the failure
13093     */
13094    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
13095        long timeMillis = System.currentTimeMillis();
13096        String shortMsg = crashInfo.exceptionClassName;
13097        String longMsg = crashInfo.exceptionMessage;
13098        String stackTrace = crashInfo.stackTrace;
13099        if (shortMsg != null && longMsg != null) {
13100            longMsg = shortMsg + ": " + longMsg;
13101        } else if (shortMsg != null) {
13102            longMsg = shortMsg;
13103        }
13104
13105        AppErrorResult result = new AppErrorResult();
13106        synchronized (this) {
13107            if (mController != null) {
13108                try {
13109                    String name = r != null ? r.processName : null;
13110                    int pid = r != null ? r.pid : Binder.getCallingPid();
13111                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
13112                    if (!mController.appCrashed(name, pid,
13113                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
13114                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
13115                                && "Native crash".equals(crashInfo.exceptionClassName)) {
13116                            Slog.w(TAG, "Skip killing native crashed app " + name
13117                                    + "(" + pid + ") during testing");
13118                        } else {
13119                            Slog.w(TAG, "Force-killing crashed app " + name
13120                                    + " at watcher's request");
13121                            if (r != null) {
13122                                r.kill("crash", true);
13123                            } else {
13124                                // Huh.
13125                                Process.killProcess(pid);
13126                                killProcessGroup(uid, pid);
13127                            }
13128                        }
13129                        return;
13130                    }
13131                } catch (RemoteException e) {
13132                    mController = null;
13133                    Watchdog.getInstance().setActivityController(null);
13134                }
13135            }
13136
13137            final long origId = Binder.clearCallingIdentity();
13138
13139            // If this process is running instrumentation, finish it.
13140            if (r != null && r.instrumentationClass != null) {
13141                Slog.w(TAG, "Error in app " + r.processName
13142                      + " running instrumentation " + r.instrumentationClass + ":");
13143                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
13144                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
13145                Bundle info = new Bundle();
13146                info.putString("shortMsg", shortMsg);
13147                info.putString("longMsg", longMsg);
13148                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
13149                Binder.restoreCallingIdentity(origId);
13150                return;
13151            }
13152
13153            // Log crash in battery stats.
13154            if (r != null) {
13155                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
13156            }
13157
13158            // If we can't identify the process or it's already exceeded its crash quota,
13159            // quit right away without showing a crash dialog.
13160            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
13161                Binder.restoreCallingIdentity(origId);
13162                return;
13163            }
13164
13165            Message msg = Message.obtain();
13166            msg.what = SHOW_ERROR_UI_MSG;
13167            HashMap data = new HashMap();
13168            data.put("result", result);
13169            data.put("app", r);
13170            msg.obj = data;
13171            mUiHandler.sendMessage(msg);
13172
13173            Binder.restoreCallingIdentity(origId);
13174        }
13175
13176        int res = result.get();
13177
13178        Intent appErrorIntent = null;
13179        synchronized (this) {
13180            if (r != null && !r.isolated) {
13181                // XXX Can't keep track of crash time for isolated processes,
13182                // since they don't have a persistent identity.
13183                mProcessCrashTimes.put(r.info.processName, r.uid,
13184                        SystemClock.uptimeMillis());
13185            }
13186            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
13187                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
13188            }
13189        }
13190
13191        if (appErrorIntent != null) {
13192            try {
13193                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
13194            } catch (ActivityNotFoundException e) {
13195                Slog.w(TAG, "bug report receiver dissappeared", e);
13196            }
13197        }
13198    }
13199
13200    Intent createAppErrorIntentLocked(ProcessRecord r,
13201            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
13202        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
13203        if (report == null) {
13204            return null;
13205        }
13206        Intent result = new Intent(Intent.ACTION_APP_ERROR);
13207        result.setComponent(r.errorReportReceiver);
13208        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
13209        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
13210        return result;
13211    }
13212
13213    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
13214            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
13215        if (r.errorReportReceiver == null) {
13216            return null;
13217        }
13218
13219        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
13220            return null;
13221        }
13222
13223        ApplicationErrorReport report = new ApplicationErrorReport();
13224        report.packageName = r.info.packageName;
13225        report.installerPackageName = r.errorReportReceiver.getPackageName();
13226        report.processName = r.processName;
13227        report.time = timeMillis;
13228        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
13229
13230        if (r.crashing || r.forceCrashReport) {
13231            report.type = ApplicationErrorReport.TYPE_CRASH;
13232            report.crashInfo = crashInfo;
13233        } else if (r.notResponding) {
13234            report.type = ApplicationErrorReport.TYPE_ANR;
13235            report.anrInfo = new ApplicationErrorReport.AnrInfo();
13236
13237            report.anrInfo.activity = r.notRespondingReport.tag;
13238            report.anrInfo.cause = r.notRespondingReport.shortMsg;
13239            report.anrInfo.info = r.notRespondingReport.longMsg;
13240        }
13241
13242        return report;
13243    }
13244
13245    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13246        enforceNotIsolatedCaller("getProcessesInErrorState");
13247        // assume our apps are happy - lazy create the list
13248        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13249
13250        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13251                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13252        int userId = UserHandle.getUserId(Binder.getCallingUid());
13253
13254        synchronized (this) {
13255
13256            // iterate across all processes
13257            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13258                ProcessRecord app = mLruProcesses.get(i);
13259                if (!allUsers && app.userId != userId) {
13260                    continue;
13261                }
13262                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13263                    // This one's in trouble, so we'll generate a report for it
13264                    // crashes are higher priority (in case there's a crash *and* an anr)
13265                    ActivityManager.ProcessErrorStateInfo report = null;
13266                    if (app.crashing) {
13267                        report = app.crashingReport;
13268                    } else if (app.notResponding) {
13269                        report = app.notRespondingReport;
13270                    }
13271
13272                    if (report != null) {
13273                        if (errList == null) {
13274                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13275                        }
13276                        errList.add(report);
13277                    } else {
13278                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13279                                " crashing = " + app.crashing +
13280                                " notResponding = " + app.notResponding);
13281                    }
13282                }
13283            }
13284        }
13285
13286        return errList;
13287    }
13288
13289    static int procStateToImportance(int procState, int memAdj,
13290            ActivityManager.RunningAppProcessInfo currApp) {
13291        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13292        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13293            currApp.lru = memAdj;
13294        } else {
13295            currApp.lru = 0;
13296        }
13297        return imp;
13298    }
13299
13300    private void fillInProcMemInfo(ProcessRecord app,
13301            ActivityManager.RunningAppProcessInfo outInfo) {
13302        outInfo.pid = app.pid;
13303        outInfo.uid = app.info.uid;
13304        if (mHeavyWeightProcess == app) {
13305            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13306        }
13307        if (app.persistent) {
13308            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13309        }
13310        if (app.activities.size() > 0) {
13311            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13312        }
13313        outInfo.lastTrimLevel = app.trimMemoryLevel;
13314        int adj = app.curAdj;
13315        int procState = app.curProcState;
13316        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13317        outInfo.importanceReasonCode = app.adjTypeCode;
13318        outInfo.processState = app.curProcState;
13319    }
13320
13321    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13322        enforceNotIsolatedCaller("getRunningAppProcesses");
13323
13324        final int callingUid = Binder.getCallingUid();
13325
13326        // Lazy instantiation of list
13327        List<ActivityManager.RunningAppProcessInfo> runList = null;
13328        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13329                callingUid) == PackageManager.PERMISSION_GRANTED;
13330        final int userId = UserHandle.getUserId(callingUid);
13331        final boolean allUids = isGetTasksAllowed(
13332                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13333
13334        synchronized (this) {
13335            // Iterate across all processes
13336            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13337                ProcessRecord app = mLruProcesses.get(i);
13338                if ((!allUsers && app.userId != userId)
13339                        || (!allUids && app.uid != callingUid)) {
13340                    continue;
13341                }
13342                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13343                    // Generate process state info for running application
13344                    ActivityManager.RunningAppProcessInfo currApp =
13345                        new ActivityManager.RunningAppProcessInfo(app.processName,
13346                                app.pid, app.getPackageList());
13347                    fillInProcMemInfo(app, currApp);
13348                    if (app.adjSource instanceof ProcessRecord) {
13349                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13350                        currApp.importanceReasonImportance =
13351                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13352                                        app.adjSourceProcState);
13353                    } else if (app.adjSource instanceof ActivityRecord) {
13354                        ActivityRecord r = (ActivityRecord)app.adjSource;
13355                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13356                    }
13357                    if (app.adjTarget instanceof ComponentName) {
13358                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13359                    }
13360                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13361                    //        + " lru=" + currApp.lru);
13362                    if (runList == null) {
13363                        runList = new ArrayList<>();
13364                    }
13365                    runList.add(currApp);
13366                }
13367            }
13368        }
13369        return runList;
13370    }
13371
13372    public List<ApplicationInfo> getRunningExternalApplications() {
13373        enforceNotIsolatedCaller("getRunningExternalApplications");
13374        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13375        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13376        if (runningApps != null && runningApps.size() > 0) {
13377            Set<String> extList = new HashSet<String>();
13378            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13379                if (app.pkgList != null) {
13380                    for (String pkg : app.pkgList) {
13381                        extList.add(pkg);
13382                    }
13383                }
13384            }
13385            IPackageManager pm = AppGlobals.getPackageManager();
13386            for (String pkg : extList) {
13387                try {
13388                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13389                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13390                        retList.add(info);
13391                    }
13392                } catch (RemoteException e) {
13393                }
13394            }
13395        }
13396        return retList;
13397    }
13398
13399    @Override
13400    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13401        enforceNotIsolatedCaller("getMyMemoryState");
13402        synchronized (this) {
13403            ProcessRecord proc;
13404            synchronized (mPidsSelfLocked) {
13405                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13406            }
13407            fillInProcMemInfo(proc, outInfo);
13408        }
13409    }
13410
13411    @Override
13412    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13413            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13414        (new ActivityManagerShellCommand(this, false)).exec(
13415                this, in, out, err, args, resultReceiver);
13416    }
13417
13418    @Override
13419    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13420        if (checkCallingPermission(android.Manifest.permission.DUMP)
13421                != PackageManager.PERMISSION_GRANTED) {
13422            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13423                    + Binder.getCallingPid()
13424                    + ", uid=" + Binder.getCallingUid()
13425                    + " without permission "
13426                    + android.Manifest.permission.DUMP);
13427            return;
13428        }
13429
13430        boolean dumpAll = false;
13431        boolean dumpClient = false;
13432        String dumpPackage = null;
13433
13434        int opti = 0;
13435        while (opti < args.length) {
13436            String opt = args[opti];
13437            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13438                break;
13439            }
13440            opti++;
13441            if ("-a".equals(opt)) {
13442                dumpAll = true;
13443            } else if ("-c".equals(opt)) {
13444                dumpClient = true;
13445            } else if ("-p".equals(opt)) {
13446                if (opti < args.length) {
13447                    dumpPackage = args[opti];
13448                    opti++;
13449                } else {
13450                    pw.println("Error: -p option requires package argument");
13451                    return;
13452                }
13453                dumpClient = true;
13454            } else if ("-h".equals(opt)) {
13455                ActivityManagerShellCommand.dumpHelp(pw, true);
13456                return;
13457            } else {
13458                pw.println("Unknown argument: " + opt + "; use -h for help");
13459            }
13460        }
13461
13462        long origId = Binder.clearCallingIdentity();
13463        boolean more = false;
13464        // Is the caller requesting to dump a particular piece of data?
13465        if (opti < args.length) {
13466            String cmd = args[opti];
13467            opti++;
13468            if ("activities".equals(cmd) || "a".equals(cmd)) {
13469                synchronized (this) {
13470                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13471                }
13472            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13473                synchronized (this) {
13474                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13475                }
13476            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13477                String[] newArgs;
13478                String name;
13479                if (opti >= args.length) {
13480                    name = null;
13481                    newArgs = EMPTY_STRING_ARRAY;
13482                } else {
13483                    dumpPackage = args[opti];
13484                    opti++;
13485                    newArgs = new String[args.length - opti];
13486                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13487                            args.length - opti);
13488                }
13489                synchronized (this) {
13490                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13491                }
13492            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13493                String[] newArgs;
13494                String name;
13495                if (opti >= args.length) {
13496                    name = null;
13497                    newArgs = EMPTY_STRING_ARRAY;
13498                } else {
13499                    dumpPackage = args[opti];
13500                    opti++;
13501                    newArgs = new String[args.length - opti];
13502                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13503                            args.length - opti);
13504                }
13505                synchronized (this) {
13506                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13507                }
13508            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13509                String[] newArgs;
13510                String name;
13511                if (opti >= args.length) {
13512                    name = null;
13513                    newArgs = EMPTY_STRING_ARRAY;
13514                } else {
13515                    dumpPackage = args[opti];
13516                    opti++;
13517                    newArgs = new String[args.length - opti];
13518                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13519                            args.length - opti);
13520                }
13521                synchronized (this) {
13522                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13523                }
13524            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13525                synchronized (this) {
13526                    dumpOomLocked(fd, pw, args, opti, true);
13527                }
13528            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13529                synchronized (this) {
13530                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13531                }
13532            } else if ("provider".equals(cmd)) {
13533                String[] newArgs;
13534                String name;
13535                if (opti >= args.length) {
13536                    name = null;
13537                    newArgs = EMPTY_STRING_ARRAY;
13538                } else {
13539                    name = args[opti];
13540                    opti++;
13541                    newArgs = new String[args.length - opti];
13542                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13543                }
13544                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13545                    pw.println("No providers match: " + name);
13546                    pw.println("Use -h for help.");
13547                }
13548            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13549                synchronized (this) {
13550                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13551                }
13552            } else if ("service".equals(cmd)) {
13553                String[] newArgs;
13554                String name;
13555                if (opti >= args.length) {
13556                    name = null;
13557                    newArgs = EMPTY_STRING_ARRAY;
13558                } else {
13559                    name = args[opti];
13560                    opti++;
13561                    newArgs = new String[args.length - opti];
13562                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13563                            args.length - opti);
13564                }
13565                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13566                    pw.println("No services match: " + name);
13567                    pw.println("Use -h for help.");
13568                }
13569            } else if ("package".equals(cmd)) {
13570                String[] newArgs;
13571                if (opti >= args.length) {
13572                    pw.println("package: no package name specified");
13573                    pw.println("Use -h for help.");
13574                } else {
13575                    dumpPackage = args[opti];
13576                    opti++;
13577                    newArgs = new String[args.length - opti];
13578                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13579                            args.length - opti);
13580                    args = newArgs;
13581                    opti = 0;
13582                    more = true;
13583                }
13584            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13585                synchronized (this) {
13586                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13587                }
13588            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13589                synchronized (this) {
13590                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13591                }
13592            } else {
13593                // Dumping a single activity?
13594                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13595                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13596                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13597                    if (res < 0) {
13598                        pw.println("Bad activity command, or no activities match: " + cmd);
13599                        pw.println("Use -h for help.");
13600                    }
13601                }
13602            }
13603            if (!more) {
13604                Binder.restoreCallingIdentity(origId);
13605                return;
13606            }
13607        }
13608
13609        // No piece of data specified, dump everything.
13610        synchronized (this) {
13611            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13612            pw.println();
13613            if (dumpAll) {
13614                pw.println("-------------------------------------------------------------------------------");
13615            }
13616            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13617            pw.println();
13618            if (dumpAll) {
13619                pw.println("-------------------------------------------------------------------------------");
13620            }
13621            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13622            pw.println();
13623            if (dumpAll) {
13624                pw.println("-------------------------------------------------------------------------------");
13625            }
13626            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13627            pw.println();
13628            if (dumpAll) {
13629                pw.println("-------------------------------------------------------------------------------");
13630            }
13631            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13632            pw.println();
13633            if (dumpAll) {
13634                pw.println("-------------------------------------------------------------------------------");
13635            }
13636            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13637            pw.println();
13638            if (dumpAll) {
13639                pw.println("-------------------------------------------------------------------------------");
13640            }
13641            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13642            if (mAssociations.size() > 0) {
13643                pw.println();
13644                if (dumpAll) {
13645                    pw.println("-------------------------------------------------------------------------------");
13646                }
13647                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13648            }
13649            pw.println();
13650            if (dumpAll) {
13651                pw.println("-------------------------------------------------------------------------------");
13652            }
13653            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13654        }
13655        Binder.restoreCallingIdentity(origId);
13656    }
13657
13658    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13659            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13660        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13661
13662        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13663                dumpPackage);
13664        boolean needSep = printedAnything;
13665
13666        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13667                dumpPackage, needSep, "  mFocusedActivity: ");
13668        if (printed) {
13669            printedAnything = true;
13670            needSep = false;
13671        }
13672
13673        if (dumpPackage == null) {
13674            if (needSep) {
13675                pw.println();
13676            }
13677            needSep = true;
13678            printedAnything = true;
13679            mStackSupervisor.dump(pw, "  ");
13680        }
13681
13682        if (!printedAnything) {
13683            pw.println("  (nothing)");
13684        }
13685    }
13686
13687    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13688            int opti, boolean dumpAll, String dumpPackage) {
13689        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13690
13691        boolean printedAnything = false;
13692
13693        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13694            boolean printedHeader = false;
13695
13696            final int N = mRecentTasks.size();
13697            for (int i=0; i<N; i++) {
13698                TaskRecord tr = mRecentTasks.get(i);
13699                if (dumpPackage != null) {
13700                    if (tr.realActivity == null ||
13701                            !dumpPackage.equals(tr.realActivity)) {
13702                        continue;
13703                    }
13704                }
13705                if (!printedHeader) {
13706                    pw.println("  Recent tasks:");
13707                    printedHeader = true;
13708                    printedAnything = true;
13709                }
13710                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13711                        pw.println(tr);
13712                if (dumpAll) {
13713                    mRecentTasks.get(i).dump(pw, "    ");
13714                }
13715            }
13716        }
13717
13718        if (!printedAnything) {
13719            pw.println("  (nothing)");
13720        }
13721    }
13722
13723    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13724            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13725        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13726
13727        int dumpUid = 0;
13728        if (dumpPackage != null) {
13729            IPackageManager pm = AppGlobals.getPackageManager();
13730            try {
13731                dumpUid = pm.getPackageUid(dumpPackage, 0);
13732            } catch (RemoteException e) {
13733            }
13734        }
13735
13736        boolean printedAnything = false;
13737
13738        final long now = SystemClock.uptimeMillis();
13739
13740        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13741            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13742                    = mAssociations.valueAt(i1);
13743            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13744                SparseArray<ArrayMap<String, Association>> sourceUids
13745                        = targetComponents.valueAt(i2);
13746                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13747                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13748                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13749                        Association ass = sourceProcesses.valueAt(i4);
13750                        if (dumpPackage != null) {
13751                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13752                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13753                                continue;
13754                            }
13755                        }
13756                        printedAnything = true;
13757                        pw.print("  ");
13758                        pw.print(ass.mTargetProcess);
13759                        pw.print("/");
13760                        UserHandle.formatUid(pw, ass.mTargetUid);
13761                        pw.print(" <- ");
13762                        pw.print(ass.mSourceProcess);
13763                        pw.print("/");
13764                        UserHandle.formatUid(pw, ass.mSourceUid);
13765                        pw.println();
13766                        pw.print("    via ");
13767                        pw.print(ass.mTargetComponent.flattenToShortString());
13768                        pw.println();
13769                        pw.print("    ");
13770                        long dur = ass.mTime;
13771                        if (ass.mNesting > 0) {
13772                            dur += now - ass.mStartTime;
13773                        }
13774                        TimeUtils.formatDuration(dur, pw);
13775                        pw.print(" (");
13776                        pw.print(ass.mCount);
13777                        pw.println(" times)");
13778                        if (ass.mNesting > 0) {
13779                            pw.print("    ");
13780                            pw.print(" Currently active: ");
13781                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13782                            pw.println();
13783                        }
13784                    }
13785                }
13786            }
13787
13788        }
13789
13790        if (!printedAnything) {
13791            pw.println("  (nothing)");
13792        }
13793    }
13794
13795    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13796            String header, boolean needSep) {
13797        boolean printed = false;
13798        int whichAppId = -1;
13799        if (dumpPackage != null) {
13800            try {
13801                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13802                        dumpPackage, 0);
13803                whichAppId = UserHandle.getAppId(info.uid);
13804            } catch (NameNotFoundException e) {
13805                e.printStackTrace();
13806            }
13807        }
13808        for (int i=0; i<uids.size(); i++) {
13809            UidRecord uidRec = uids.valueAt(i);
13810            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13811                continue;
13812            }
13813            if (!printed) {
13814                printed = true;
13815                if (needSep) {
13816                    pw.println();
13817                }
13818                pw.print("  ");
13819                pw.println(header);
13820                needSep = true;
13821            }
13822            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13823            pw.print(": "); pw.println(uidRec);
13824        }
13825        return printed;
13826    }
13827
13828    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13829            int opti, boolean dumpAll, String dumpPackage) {
13830        boolean needSep = false;
13831        boolean printedAnything = false;
13832        int numPers = 0;
13833
13834        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13835
13836        if (dumpAll) {
13837            final int NP = mProcessNames.getMap().size();
13838            for (int ip=0; ip<NP; ip++) {
13839                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13840                final int NA = procs.size();
13841                for (int ia=0; ia<NA; ia++) {
13842                    ProcessRecord r = procs.valueAt(ia);
13843                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13844                        continue;
13845                    }
13846                    if (!needSep) {
13847                        pw.println("  All known processes:");
13848                        needSep = true;
13849                        printedAnything = true;
13850                    }
13851                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13852                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13853                        pw.print(" "); pw.println(r);
13854                    r.dump(pw, "    ");
13855                    if (r.persistent) {
13856                        numPers++;
13857                    }
13858                }
13859            }
13860        }
13861
13862        if (mIsolatedProcesses.size() > 0) {
13863            boolean printed = false;
13864            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13865                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13866                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13867                    continue;
13868                }
13869                if (!printed) {
13870                    if (needSep) {
13871                        pw.println();
13872                    }
13873                    pw.println("  Isolated process list (sorted by uid):");
13874                    printedAnything = true;
13875                    printed = true;
13876                    needSep = true;
13877                }
13878                pw.println(String.format("%sIsolated #%2d: %s",
13879                        "    ", i, r.toString()));
13880            }
13881        }
13882
13883        if (mActiveUids.size() > 0) {
13884            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
13885                printedAnything = needSep = true;
13886            }
13887        }
13888        if (mValidateUids.size() > 0) {
13889            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
13890                printedAnything = needSep = true;
13891            }
13892        }
13893
13894        if (mLruProcesses.size() > 0) {
13895            if (needSep) {
13896                pw.println();
13897            }
13898            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13899                    pw.print(" total, non-act at ");
13900                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13901                    pw.print(", non-svc at ");
13902                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13903                    pw.println("):");
13904            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13905            needSep = true;
13906            printedAnything = true;
13907        }
13908
13909        if (dumpAll || dumpPackage != null) {
13910            synchronized (mPidsSelfLocked) {
13911                boolean printed = false;
13912                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13913                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13914                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13915                        continue;
13916                    }
13917                    if (!printed) {
13918                        if (needSep) pw.println();
13919                        needSep = true;
13920                        pw.println("  PID mappings:");
13921                        printed = true;
13922                        printedAnything = true;
13923                    }
13924                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13925                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13926                }
13927            }
13928        }
13929
13930        if (mForegroundProcesses.size() > 0) {
13931            synchronized (mPidsSelfLocked) {
13932                boolean printed = false;
13933                for (int i=0; i<mForegroundProcesses.size(); i++) {
13934                    ProcessRecord r = mPidsSelfLocked.get(
13935                            mForegroundProcesses.valueAt(i).pid);
13936                    if (dumpPackage != null && (r == null
13937                            || !r.pkgList.containsKey(dumpPackage))) {
13938                        continue;
13939                    }
13940                    if (!printed) {
13941                        if (needSep) pw.println();
13942                        needSep = true;
13943                        pw.println("  Foreground Processes:");
13944                        printed = true;
13945                        printedAnything = true;
13946                    }
13947                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13948                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13949                }
13950            }
13951        }
13952
13953        if (mPersistentStartingProcesses.size() > 0) {
13954            if (needSep) pw.println();
13955            needSep = true;
13956            printedAnything = true;
13957            pw.println("  Persisent processes that are starting:");
13958            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13959                    "Starting Norm", "Restarting PERS", dumpPackage);
13960        }
13961
13962        if (mRemovedProcesses.size() > 0) {
13963            if (needSep) pw.println();
13964            needSep = true;
13965            printedAnything = true;
13966            pw.println("  Processes that are being removed:");
13967            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13968                    "Removed Norm", "Removed PERS", dumpPackage);
13969        }
13970
13971        if (mProcessesOnHold.size() > 0) {
13972            if (needSep) pw.println();
13973            needSep = true;
13974            printedAnything = true;
13975            pw.println("  Processes that are on old until the system is ready:");
13976            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13977                    "OnHold Norm", "OnHold PERS", dumpPackage);
13978        }
13979
13980        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13981
13982        if (mProcessCrashTimes.getMap().size() > 0) {
13983            boolean printed = false;
13984            long now = SystemClock.uptimeMillis();
13985            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13986            final int NP = pmap.size();
13987            for (int ip=0; ip<NP; ip++) {
13988                String pname = pmap.keyAt(ip);
13989                SparseArray<Long> uids = pmap.valueAt(ip);
13990                final int N = uids.size();
13991                for (int i=0; i<N; i++) {
13992                    int puid = uids.keyAt(i);
13993                    ProcessRecord r = mProcessNames.get(pname, puid);
13994                    if (dumpPackage != null && (r == null
13995                            || !r.pkgList.containsKey(dumpPackage))) {
13996                        continue;
13997                    }
13998                    if (!printed) {
13999                        if (needSep) pw.println();
14000                        needSep = true;
14001                        pw.println("  Time since processes crashed:");
14002                        printed = true;
14003                        printedAnything = true;
14004                    }
14005                    pw.print("    Process "); pw.print(pname);
14006                            pw.print(" uid "); pw.print(puid);
14007                            pw.print(": last crashed ");
14008                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
14009                            pw.println(" ago");
14010                }
14011            }
14012        }
14013
14014        if (mBadProcesses.getMap().size() > 0) {
14015            boolean printed = false;
14016            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
14017            final int NP = pmap.size();
14018            for (int ip=0; ip<NP; ip++) {
14019                String pname = pmap.keyAt(ip);
14020                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
14021                final int N = uids.size();
14022                for (int i=0; i<N; i++) {
14023                    int puid = uids.keyAt(i);
14024                    ProcessRecord r = mProcessNames.get(pname, puid);
14025                    if (dumpPackage != null && (r == null
14026                            || !r.pkgList.containsKey(dumpPackage))) {
14027                        continue;
14028                    }
14029                    if (!printed) {
14030                        if (needSep) pw.println();
14031                        needSep = true;
14032                        pw.println("  Bad processes:");
14033                        printedAnything = true;
14034                    }
14035                    BadProcessInfo info = uids.valueAt(i);
14036                    pw.print("    Bad process "); pw.print(pname);
14037                            pw.print(" uid "); pw.print(puid);
14038                            pw.print(": crashed at time "); pw.println(info.time);
14039                    if (info.shortMsg != null) {
14040                        pw.print("      Short msg: "); pw.println(info.shortMsg);
14041                    }
14042                    if (info.longMsg != null) {
14043                        pw.print("      Long msg: "); pw.println(info.longMsg);
14044                    }
14045                    if (info.stack != null) {
14046                        pw.println("      Stack:");
14047                        int lastPos = 0;
14048                        for (int pos=0; pos<info.stack.length(); pos++) {
14049                            if (info.stack.charAt(pos) == '\n') {
14050                                pw.print("        ");
14051                                pw.write(info.stack, lastPos, pos-lastPos);
14052                                pw.println();
14053                                lastPos = pos+1;
14054                            }
14055                        }
14056                        if (lastPos < info.stack.length()) {
14057                            pw.print("        ");
14058                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
14059                            pw.println();
14060                        }
14061                    }
14062                }
14063            }
14064        }
14065
14066        if (dumpPackage == null) {
14067            pw.println();
14068            needSep = false;
14069            mUserController.dump(pw, dumpAll);
14070        }
14071        if (mHomeProcess != null && (dumpPackage == null
14072                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14073            if (needSep) {
14074                pw.println();
14075                needSep = false;
14076            }
14077            pw.println("  mHomeProcess: " + mHomeProcess);
14078        }
14079        if (mPreviousProcess != null && (dumpPackage == null
14080                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14081            if (needSep) {
14082                pw.println();
14083                needSep = false;
14084            }
14085            pw.println("  mPreviousProcess: " + mPreviousProcess);
14086        }
14087        if (dumpAll) {
14088            StringBuilder sb = new StringBuilder(128);
14089            sb.append("  mPreviousProcessVisibleTime: ");
14090            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14091            pw.println(sb);
14092        }
14093        if (mHeavyWeightProcess != null && (dumpPackage == null
14094                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14095            if (needSep) {
14096                pw.println();
14097                needSep = false;
14098            }
14099            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14100        }
14101        if (dumpPackage == null) {
14102            pw.println("  mConfiguration: " + mConfiguration);
14103        }
14104        if (dumpAll) {
14105            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14106            if (mCompatModePackages.getPackages().size() > 0) {
14107                boolean printed = false;
14108                for (Map.Entry<String, Integer> entry
14109                        : mCompatModePackages.getPackages().entrySet()) {
14110                    String pkg = entry.getKey();
14111                    int mode = entry.getValue();
14112                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14113                        continue;
14114                    }
14115                    if (!printed) {
14116                        pw.println("  mScreenCompatPackages:");
14117                        printed = true;
14118                    }
14119                    pw.print("    "); pw.print(pkg); pw.print(": ");
14120                            pw.print(mode); pw.println();
14121                }
14122            }
14123        }
14124        if (dumpPackage == null) {
14125            pw.println("  mWakefulness="
14126                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14127            pw.println("  mSleepTokens=" + mSleepTokens);
14128            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14129                    + lockScreenShownToString());
14130            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14131            if (mRunningVoice != null) {
14132                pw.println("  mRunningVoice=" + mRunningVoice);
14133                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14134            }
14135        }
14136        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14137                || mOrigWaitForDebugger) {
14138            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14139                    || dumpPackage.equals(mOrigDebugApp)) {
14140                if (needSep) {
14141                    pw.println();
14142                    needSep = false;
14143                }
14144                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14145                        + " mDebugTransient=" + mDebugTransient
14146                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14147            }
14148        }
14149        if (mCurAppTimeTracker != null) {
14150            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14151        }
14152        if (mMemWatchProcesses.getMap().size() > 0) {
14153            pw.println("  Mem watch processes:");
14154            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14155                    = mMemWatchProcesses.getMap();
14156            for (int i=0; i<procs.size(); i++) {
14157                final String proc = procs.keyAt(i);
14158                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14159                for (int j=0; j<uids.size(); j++) {
14160                    if (needSep) {
14161                        pw.println();
14162                        needSep = false;
14163                    }
14164                    StringBuilder sb = new StringBuilder();
14165                    sb.append("    ").append(proc).append('/');
14166                    UserHandle.formatUid(sb, uids.keyAt(j));
14167                    Pair<Long, String> val = uids.valueAt(j);
14168                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14169                    if (val.second != null) {
14170                        sb.append(", report to ").append(val.second);
14171                    }
14172                    pw.println(sb.toString());
14173                }
14174            }
14175            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14176            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14177            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14178                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14179        }
14180        if (mTrackAllocationApp != null) {
14181            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14182                if (needSep) {
14183                    pw.println();
14184                    needSep = false;
14185                }
14186                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14187            }
14188        }
14189        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14190                || mProfileFd != null) {
14191            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14192                if (needSep) {
14193                    pw.println();
14194                    needSep = false;
14195                }
14196                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14197                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14198                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14199                        + mAutoStopProfiler);
14200                pw.println("  mProfileType=" + mProfileType);
14201            }
14202        }
14203        if (dumpPackage == null) {
14204            if (mAlwaysFinishActivities || mController != null) {
14205                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14206                        + " mController=" + mController);
14207            }
14208            if (dumpAll) {
14209                pw.println("  Total persistent processes: " + numPers);
14210                pw.println("  mProcessesReady=" + mProcessesReady
14211                        + " mSystemReady=" + mSystemReady
14212                        + " mBooted=" + mBooted
14213                        + " mFactoryTest=" + mFactoryTest);
14214                pw.println("  mBooting=" + mBooting
14215                        + " mCallFinishBooting=" + mCallFinishBooting
14216                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14217                pw.print("  mLastPowerCheckRealtime=");
14218                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14219                        pw.println("");
14220                pw.print("  mLastPowerCheckUptime=");
14221                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14222                        pw.println("");
14223                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14224                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14225                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14226                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14227                        + " (" + mLruProcesses.size() + " total)"
14228                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14229                        + " mNumServiceProcs=" + mNumServiceProcs
14230                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14231                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14232                        + " mLastMemoryLevel" + mLastMemoryLevel
14233                        + " mLastNumProcesses" + mLastNumProcesses);
14234                long now = SystemClock.uptimeMillis();
14235                pw.print("  mLastIdleTime=");
14236                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14237                        pw.print(" mLowRamSinceLastIdle=");
14238                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14239                        pw.println();
14240            }
14241        }
14242
14243        if (!printedAnything) {
14244            pw.println("  (nothing)");
14245        }
14246    }
14247
14248    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14249            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14250        if (mProcessesToGc.size() > 0) {
14251            boolean printed = false;
14252            long now = SystemClock.uptimeMillis();
14253            for (int i=0; i<mProcessesToGc.size(); i++) {
14254                ProcessRecord proc = mProcessesToGc.get(i);
14255                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14256                    continue;
14257                }
14258                if (!printed) {
14259                    if (needSep) pw.println();
14260                    needSep = true;
14261                    pw.println("  Processes that are waiting to GC:");
14262                    printed = true;
14263                }
14264                pw.print("    Process "); pw.println(proc);
14265                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14266                        pw.print(", last gced=");
14267                        pw.print(now-proc.lastRequestedGc);
14268                        pw.print(" ms ago, last lowMem=");
14269                        pw.print(now-proc.lastLowMemory);
14270                        pw.println(" ms ago");
14271
14272            }
14273        }
14274        return needSep;
14275    }
14276
14277    void printOomLevel(PrintWriter pw, String name, int adj) {
14278        pw.print("    ");
14279        if (adj >= 0) {
14280            pw.print(' ');
14281            if (adj < 10) pw.print(' ');
14282        } else {
14283            if (adj > -10) pw.print(' ');
14284        }
14285        pw.print(adj);
14286        pw.print(": ");
14287        pw.print(name);
14288        pw.print(" (");
14289        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14290        pw.println(")");
14291    }
14292
14293    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14294            int opti, boolean dumpAll) {
14295        boolean needSep = false;
14296
14297        if (mLruProcesses.size() > 0) {
14298            if (needSep) pw.println();
14299            needSep = true;
14300            pw.println("  OOM levels:");
14301            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14302            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14303            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14304            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14305            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14306            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14307            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14308            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14309            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14310            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14311            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14312            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14313            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14314            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14315
14316            if (needSep) pw.println();
14317            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14318                    pw.print(" total, non-act at ");
14319                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14320                    pw.print(", non-svc at ");
14321                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14322                    pw.println("):");
14323            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14324            needSep = true;
14325        }
14326
14327        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14328
14329        pw.println();
14330        pw.println("  mHomeProcess: " + mHomeProcess);
14331        pw.println("  mPreviousProcess: " + mPreviousProcess);
14332        if (mHeavyWeightProcess != null) {
14333            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14334        }
14335
14336        return true;
14337    }
14338
14339    /**
14340     * There are three ways to call this:
14341     *  - no provider specified: dump all the providers
14342     *  - a flattened component name that matched an existing provider was specified as the
14343     *    first arg: dump that one provider
14344     *  - the first arg isn't the flattened component name of an existing provider:
14345     *    dump all providers whose component contains the first arg as a substring
14346     */
14347    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14348            int opti, boolean dumpAll) {
14349        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14350    }
14351
14352    static class ItemMatcher {
14353        ArrayList<ComponentName> components;
14354        ArrayList<String> strings;
14355        ArrayList<Integer> objects;
14356        boolean all;
14357
14358        ItemMatcher() {
14359            all = true;
14360        }
14361
14362        void build(String name) {
14363            ComponentName componentName = ComponentName.unflattenFromString(name);
14364            if (componentName != null) {
14365                if (components == null) {
14366                    components = new ArrayList<ComponentName>();
14367                }
14368                components.add(componentName);
14369                all = false;
14370            } else {
14371                int objectId = 0;
14372                // Not a '/' separated full component name; maybe an object ID?
14373                try {
14374                    objectId = Integer.parseInt(name, 16);
14375                    if (objects == null) {
14376                        objects = new ArrayList<Integer>();
14377                    }
14378                    objects.add(objectId);
14379                    all = false;
14380                } catch (RuntimeException e) {
14381                    // Not an integer; just do string match.
14382                    if (strings == null) {
14383                        strings = new ArrayList<String>();
14384                    }
14385                    strings.add(name);
14386                    all = false;
14387                }
14388            }
14389        }
14390
14391        int build(String[] args, int opti) {
14392            for (; opti<args.length; opti++) {
14393                String name = args[opti];
14394                if ("--".equals(name)) {
14395                    return opti+1;
14396                }
14397                build(name);
14398            }
14399            return opti;
14400        }
14401
14402        boolean match(Object object, ComponentName comp) {
14403            if (all) {
14404                return true;
14405            }
14406            if (components != null) {
14407                for (int i=0; i<components.size(); i++) {
14408                    if (components.get(i).equals(comp)) {
14409                        return true;
14410                    }
14411                }
14412            }
14413            if (objects != null) {
14414                for (int i=0; i<objects.size(); i++) {
14415                    if (System.identityHashCode(object) == objects.get(i)) {
14416                        return true;
14417                    }
14418                }
14419            }
14420            if (strings != null) {
14421                String flat = comp.flattenToString();
14422                for (int i=0; i<strings.size(); i++) {
14423                    if (flat.contains(strings.get(i))) {
14424                        return true;
14425                    }
14426                }
14427            }
14428            return false;
14429        }
14430    }
14431
14432    /**
14433     * There are three things that cmd can be:
14434     *  - a flattened component name that matches an existing activity
14435     *  - the cmd arg isn't the flattened component name of an existing activity:
14436     *    dump all activity whose component contains the cmd as a substring
14437     *  - A hex number of the ActivityRecord object instance.
14438     */
14439    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14440            int opti, boolean dumpAll) {
14441        ArrayList<ActivityRecord> activities;
14442
14443        synchronized (this) {
14444            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14445        }
14446
14447        if (activities.size() <= 0) {
14448            return false;
14449        }
14450
14451        String[] newArgs = new String[args.length - opti];
14452        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14453
14454        TaskRecord lastTask = null;
14455        boolean needSep = false;
14456        for (int i=activities.size()-1; i>=0; i--) {
14457            ActivityRecord r = activities.get(i);
14458            if (needSep) {
14459                pw.println();
14460            }
14461            needSep = true;
14462            synchronized (this) {
14463                if (lastTask != r.task) {
14464                    lastTask = r.task;
14465                    pw.print("TASK "); pw.print(lastTask.affinity);
14466                            pw.print(" id="); pw.println(lastTask.taskId);
14467                    if (dumpAll) {
14468                        lastTask.dump(pw, "  ");
14469                    }
14470                }
14471            }
14472            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14473        }
14474        return true;
14475    }
14476
14477    /**
14478     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14479     * there is a thread associated with the activity.
14480     */
14481    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14482            final ActivityRecord r, String[] args, boolean dumpAll) {
14483        String innerPrefix = prefix + "  ";
14484        synchronized (this) {
14485            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14486                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14487                    pw.print(" pid=");
14488                    if (r.app != null) pw.println(r.app.pid);
14489                    else pw.println("(not running)");
14490            if (dumpAll) {
14491                r.dump(pw, innerPrefix);
14492            }
14493        }
14494        if (r.app != null && r.app.thread != null) {
14495            // flush anything that is already in the PrintWriter since the thread is going
14496            // to write to the file descriptor directly
14497            pw.flush();
14498            try {
14499                TransferPipe tp = new TransferPipe();
14500                try {
14501                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14502                            r.appToken, innerPrefix, args);
14503                    tp.go(fd);
14504                } finally {
14505                    tp.kill();
14506                }
14507            } catch (IOException e) {
14508                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14509            } catch (RemoteException e) {
14510                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14511            }
14512        }
14513    }
14514
14515    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14516            int opti, boolean dumpAll, String dumpPackage) {
14517        boolean needSep = false;
14518        boolean onlyHistory = false;
14519        boolean printedAnything = false;
14520
14521        if ("history".equals(dumpPackage)) {
14522            if (opti < args.length && "-s".equals(args[opti])) {
14523                dumpAll = false;
14524            }
14525            onlyHistory = true;
14526            dumpPackage = null;
14527        }
14528
14529        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14530        if (!onlyHistory && dumpAll) {
14531            if (mRegisteredReceivers.size() > 0) {
14532                boolean printed = false;
14533                Iterator it = mRegisteredReceivers.values().iterator();
14534                while (it.hasNext()) {
14535                    ReceiverList r = (ReceiverList)it.next();
14536                    if (dumpPackage != null && (r.app == null ||
14537                            !dumpPackage.equals(r.app.info.packageName))) {
14538                        continue;
14539                    }
14540                    if (!printed) {
14541                        pw.println("  Registered Receivers:");
14542                        needSep = true;
14543                        printed = true;
14544                        printedAnything = true;
14545                    }
14546                    pw.print("  * "); pw.println(r);
14547                    r.dump(pw, "    ");
14548                }
14549            }
14550
14551            if (mReceiverResolver.dump(pw, needSep ?
14552                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14553                    "    ", dumpPackage, false, false)) {
14554                needSep = true;
14555                printedAnything = true;
14556            }
14557        }
14558
14559        for (BroadcastQueue q : mBroadcastQueues) {
14560            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14561            printedAnything |= needSep;
14562        }
14563
14564        needSep = true;
14565
14566        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14567            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14568                if (needSep) {
14569                    pw.println();
14570                }
14571                needSep = true;
14572                printedAnything = true;
14573                pw.print("  Sticky broadcasts for user ");
14574                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14575                StringBuilder sb = new StringBuilder(128);
14576                for (Map.Entry<String, ArrayList<Intent>> ent
14577                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14578                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14579                    if (dumpAll) {
14580                        pw.println(":");
14581                        ArrayList<Intent> intents = ent.getValue();
14582                        final int N = intents.size();
14583                        for (int i=0; i<N; i++) {
14584                            sb.setLength(0);
14585                            sb.append("    Intent: ");
14586                            intents.get(i).toShortString(sb, false, true, false, false);
14587                            pw.println(sb.toString());
14588                            Bundle bundle = intents.get(i).getExtras();
14589                            if (bundle != null) {
14590                                pw.print("      ");
14591                                pw.println(bundle.toString());
14592                            }
14593                        }
14594                    } else {
14595                        pw.println("");
14596                    }
14597                }
14598            }
14599        }
14600
14601        if (!onlyHistory && dumpAll) {
14602            pw.println();
14603            for (BroadcastQueue queue : mBroadcastQueues) {
14604                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14605                        + queue.mBroadcastsScheduled);
14606            }
14607            pw.println("  mHandler:");
14608            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14609            needSep = true;
14610            printedAnything = true;
14611        }
14612
14613        if (!printedAnything) {
14614            pw.println("  (nothing)");
14615        }
14616    }
14617
14618    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14619            int opti, boolean dumpAll, String dumpPackage) {
14620        boolean needSep;
14621        boolean printedAnything = false;
14622
14623        ItemMatcher matcher = new ItemMatcher();
14624        matcher.build(args, opti);
14625
14626        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14627
14628        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14629        printedAnything |= needSep;
14630
14631        if (mLaunchingProviders.size() > 0) {
14632            boolean printed = false;
14633            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14634                ContentProviderRecord r = mLaunchingProviders.get(i);
14635                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14636                    continue;
14637                }
14638                if (!printed) {
14639                    if (needSep) pw.println();
14640                    needSep = true;
14641                    pw.println("  Launching content providers:");
14642                    printed = true;
14643                    printedAnything = true;
14644                }
14645                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14646                        pw.println(r);
14647            }
14648        }
14649
14650        if (!printedAnything) {
14651            pw.println("  (nothing)");
14652        }
14653    }
14654
14655    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14656            int opti, boolean dumpAll, String dumpPackage) {
14657        boolean needSep = false;
14658        boolean printedAnything = false;
14659
14660        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14661
14662        if (mGrantedUriPermissions.size() > 0) {
14663            boolean printed = false;
14664            int dumpUid = -2;
14665            if (dumpPackage != null) {
14666                try {
14667                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14668                } catch (NameNotFoundException e) {
14669                    dumpUid = -1;
14670                }
14671            }
14672            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14673                int uid = mGrantedUriPermissions.keyAt(i);
14674                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14675                    continue;
14676                }
14677                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14678                if (!printed) {
14679                    if (needSep) pw.println();
14680                    needSep = true;
14681                    pw.println("  Granted Uri Permissions:");
14682                    printed = true;
14683                    printedAnything = true;
14684                }
14685                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14686                for (UriPermission perm : perms.values()) {
14687                    pw.print("    "); pw.println(perm);
14688                    if (dumpAll) {
14689                        perm.dump(pw, "      ");
14690                    }
14691                }
14692            }
14693        }
14694
14695        if (!printedAnything) {
14696            pw.println("  (nothing)");
14697        }
14698    }
14699
14700    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14701            int opti, boolean dumpAll, String dumpPackage) {
14702        boolean printed = false;
14703
14704        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14705
14706        if (mIntentSenderRecords.size() > 0) {
14707            Iterator<WeakReference<PendingIntentRecord>> it
14708                    = mIntentSenderRecords.values().iterator();
14709            while (it.hasNext()) {
14710                WeakReference<PendingIntentRecord> ref = it.next();
14711                PendingIntentRecord rec = ref != null ? ref.get(): null;
14712                if (dumpPackage != null && (rec == null
14713                        || !dumpPackage.equals(rec.key.packageName))) {
14714                    continue;
14715                }
14716                printed = true;
14717                if (rec != null) {
14718                    pw.print("  * "); pw.println(rec);
14719                    if (dumpAll) {
14720                        rec.dump(pw, "    ");
14721                    }
14722                } else {
14723                    pw.print("  * "); pw.println(ref);
14724                }
14725            }
14726        }
14727
14728        if (!printed) {
14729            pw.println("  (nothing)");
14730        }
14731    }
14732
14733    private static final int dumpProcessList(PrintWriter pw,
14734            ActivityManagerService service, List list,
14735            String prefix, String normalLabel, String persistentLabel,
14736            String dumpPackage) {
14737        int numPers = 0;
14738        final int N = list.size()-1;
14739        for (int i=N; i>=0; i--) {
14740            ProcessRecord r = (ProcessRecord)list.get(i);
14741            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14742                continue;
14743            }
14744            pw.println(String.format("%s%s #%2d: %s",
14745                    prefix, (r.persistent ? persistentLabel : normalLabel),
14746                    i, r.toString()));
14747            if (r.persistent) {
14748                numPers++;
14749            }
14750        }
14751        return numPers;
14752    }
14753
14754    private static final boolean dumpProcessOomList(PrintWriter pw,
14755            ActivityManagerService service, List<ProcessRecord> origList,
14756            String prefix, String normalLabel, String persistentLabel,
14757            boolean inclDetails, String dumpPackage) {
14758
14759        ArrayList<Pair<ProcessRecord, Integer>> list
14760                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14761        for (int i=0; i<origList.size(); i++) {
14762            ProcessRecord r = origList.get(i);
14763            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14764                continue;
14765            }
14766            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14767        }
14768
14769        if (list.size() <= 0) {
14770            return false;
14771        }
14772
14773        Comparator<Pair<ProcessRecord, Integer>> comparator
14774                = new Comparator<Pair<ProcessRecord, Integer>>() {
14775            @Override
14776            public int compare(Pair<ProcessRecord, Integer> object1,
14777                    Pair<ProcessRecord, Integer> object2) {
14778                if (object1.first.setAdj != object2.first.setAdj) {
14779                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14780                }
14781                if (object1.first.setProcState != object2.first.setProcState) {
14782                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14783                }
14784                if (object1.second.intValue() != object2.second.intValue()) {
14785                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14786                }
14787                return 0;
14788            }
14789        };
14790
14791        Collections.sort(list, comparator);
14792
14793        final long curRealtime = SystemClock.elapsedRealtime();
14794        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14795        final long curUptime = SystemClock.uptimeMillis();
14796        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14797
14798        for (int i=list.size()-1; i>=0; i--) {
14799            ProcessRecord r = list.get(i).first;
14800            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14801            char schedGroup;
14802            switch (r.setSchedGroup) {
14803                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14804                    schedGroup = 'B';
14805                    break;
14806                case Process.THREAD_GROUP_DEFAULT:
14807                    schedGroup = 'F';
14808                    break;
14809                default:
14810                    schedGroup = '?';
14811                    break;
14812            }
14813            char foreground;
14814            if (r.foregroundActivities) {
14815                foreground = 'A';
14816            } else if (r.foregroundServices) {
14817                foreground = 'S';
14818            } else {
14819                foreground = ' ';
14820            }
14821            String procState = ProcessList.makeProcStateString(r.curProcState);
14822            pw.print(prefix);
14823            pw.print(r.persistent ? persistentLabel : normalLabel);
14824            pw.print(" #");
14825            int num = (origList.size()-1)-list.get(i).second;
14826            if (num < 10) pw.print(' ');
14827            pw.print(num);
14828            pw.print(": ");
14829            pw.print(oomAdj);
14830            pw.print(' ');
14831            pw.print(schedGroup);
14832            pw.print('/');
14833            pw.print(foreground);
14834            pw.print('/');
14835            pw.print(procState);
14836            pw.print(" trm:");
14837            if (r.trimMemoryLevel < 10) pw.print(' ');
14838            pw.print(r.trimMemoryLevel);
14839            pw.print(' ');
14840            pw.print(r.toShortString());
14841            pw.print(" (");
14842            pw.print(r.adjType);
14843            pw.println(')');
14844            if (r.adjSource != null || r.adjTarget != null) {
14845                pw.print(prefix);
14846                pw.print("    ");
14847                if (r.adjTarget instanceof ComponentName) {
14848                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14849                } else if (r.adjTarget != null) {
14850                    pw.print(r.adjTarget.toString());
14851                } else {
14852                    pw.print("{null}");
14853                }
14854                pw.print("<=");
14855                if (r.adjSource instanceof ProcessRecord) {
14856                    pw.print("Proc{");
14857                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14858                    pw.println("}");
14859                } else if (r.adjSource != null) {
14860                    pw.println(r.adjSource.toString());
14861                } else {
14862                    pw.println("{null}");
14863                }
14864            }
14865            if (inclDetails) {
14866                pw.print(prefix);
14867                pw.print("    ");
14868                pw.print("oom: max="); pw.print(r.maxAdj);
14869                pw.print(" curRaw="); pw.print(r.curRawAdj);
14870                pw.print(" setRaw="); pw.print(r.setRawAdj);
14871                pw.print(" cur="); pw.print(r.curAdj);
14872                pw.print(" set="); pw.println(r.setAdj);
14873                pw.print(prefix);
14874                pw.print("    ");
14875                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14876                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14877                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14878                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14879                pw.println();
14880                pw.print(prefix);
14881                pw.print("    ");
14882                pw.print("cached="); pw.print(r.cached);
14883                pw.print(" empty="); pw.print(r.empty);
14884                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14885
14886                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14887                    if (r.lastWakeTime != 0) {
14888                        long wtime;
14889                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14890                        synchronized (stats) {
14891                            wtime = stats.getProcessWakeTime(r.info.uid,
14892                                    r.pid, curRealtime);
14893                        }
14894                        long timeUsed = wtime - r.lastWakeTime;
14895                        pw.print(prefix);
14896                        pw.print("    ");
14897                        pw.print("keep awake over ");
14898                        TimeUtils.formatDuration(realtimeSince, pw);
14899                        pw.print(" used ");
14900                        TimeUtils.formatDuration(timeUsed, pw);
14901                        pw.print(" (");
14902                        pw.print((timeUsed*100)/realtimeSince);
14903                        pw.println("%)");
14904                    }
14905                    if (r.lastCpuTime != 0) {
14906                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14907                        pw.print(prefix);
14908                        pw.print("    ");
14909                        pw.print("run cpu over ");
14910                        TimeUtils.formatDuration(uptimeSince, pw);
14911                        pw.print(" used ");
14912                        TimeUtils.formatDuration(timeUsed, pw);
14913                        pw.print(" (");
14914                        pw.print((timeUsed*100)/uptimeSince);
14915                        pw.println("%)");
14916                    }
14917                }
14918            }
14919        }
14920        return true;
14921    }
14922
14923    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14924            String[] args) {
14925        ArrayList<ProcessRecord> procs;
14926        synchronized (this) {
14927            if (args != null && args.length > start
14928                    && args[start].charAt(0) != '-') {
14929                procs = new ArrayList<ProcessRecord>();
14930                int pid = -1;
14931                try {
14932                    pid = Integer.parseInt(args[start]);
14933                } catch (NumberFormatException e) {
14934                }
14935                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14936                    ProcessRecord proc = mLruProcesses.get(i);
14937                    if (proc.pid == pid) {
14938                        procs.add(proc);
14939                    } else if (allPkgs && proc.pkgList != null
14940                            && proc.pkgList.containsKey(args[start])) {
14941                        procs.add(proc);
14942                    } else if (proc.processName.equals(args[start])) {
14943                        procs.add(proc);
14944                    }
14945                }
14946                if (procs.size() <= 0) {
14947                    return null;
14948                }
14949            } else {
14950                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14951            }
14952        }
14953        return procs;
14954    }
14955
14956    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14957            PrintWriter pw, String[] args) {
14958        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14959        if (procs == null) {
14960            pw.println("No process found for: " + args[0]);
14961            return;
14962        }
14963
14964        long uptime = SystemClock.uptimeMillis();
14965        long realtime = SystemClock.elapsedRealtime();
14966        pw.println("Applications Graphics Acceleration Info:");
14967        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14968
14969        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14970            ProcessRecord r = procs.get(i);
14971            if (r.thread != null) {
14972                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14973                pw.flush();
14974                try {
14975                    TransferPipe tp = new TransferPipe();
14976                    try {
14977                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14978                        tp.go(fd);
14979                    } finally {
14980                        tp.kill();
14981                    }
14982                } catch (IOException e) {
14983                    pw.println("Failure while dumping the app: " + r);
14984                    pw.flush();
14985                } catch (RemoteException e) {
14986                    pw.println("Got a RemoteException while dumping the app " + r);
14987                    pw.flush();
14988                }
14989            }
14990        }
14991    }
14992
14993    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14994        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14995        if (procs == null) {
14996            pw.println("No process found for: " + args[0]);
14997            return;
14998        }
14999
15000        pw.println("Applications Database Info:");
15001
15002        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15003            ProcessRecord r = procs.get(i);
15004            if (r.thread != null) {
15005                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15006                pw.flush();
15007                try {
15008                    TransferPipe tp = new TransferPipe();
15009                    try {
15010                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15011                        tp.go(fd);
15012                    } finally {
15013                        tp.kill();
15014                    }
15015                } catch (IOException e) {
15016                    pw.println("Failure while dumping the app: " + r);
15017                    pw.flush();
15018                } catch (RemoteException e) {
15019                    pw.println("Got a RemoteException while dumping the app " + r);
15020                    pw.flush();
15021                }
15022            }
15023        }
15024    }
15025
15026    final static class MemItem {
15027        final boolean isProc;
15028        final String label;
15029        final String shortLabel;
15030        final long pss;
15031        final int id;
15032        final boolean hasActivities;
15033        ArrayList<MemItem> subitems;
15034
15035        public MemItem(String _label, String _shortLabel, long _pss, int _id,
15036                boolean _hasActivities) {
15037            isProc = true;
15038            label = _label;
15039            shortLabel = _shortLabel;
15040            pss = _pss;
15041            id = _id;
15042            hasActivities = _hasActivities;
15043        }
15044
15045        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
15046            isProc = false;
15047            label = _label;
15048            shortLabel = _shortLabel;
15049            pss = _pss;
15050            id = _id;
15051            hasActivities = false;
15052        }
15053    }
15054
15055    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15056            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
15057        if (sort && !isCompact) {
15058            Collections.sort(items, new Comparator<MemItem>() {
15059                @Override
15060                public int compare(MemItem lhs, MemItem rhs) {
15061                    if (lhs.pss < rhs.pss) {
15062                        return 1;
15063                    } else if (lhs.pss > rhs.pss) {
15064                        return -1;
15065                    }
15066                    return 0;
15067                }
15068            });
15069        }
15070
15071        for (int i=0; i<items.size(); i++) {
15072            MemItem mi = items.get(i);
15073            if (!isCompact) {
15074                pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15075            } else if (mi.isProc) {
15076                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15077                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
15078                pw.println(mi.hasActivities ? ",a" : ",e");
15079            } else {
15080                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15081                pw.println(mi.pss);
15082            }
15083            if (mi.subitems != null) {
15084                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
15085                        true, isCompact);
15086            }
15087        }
15088    }
15089
15090    // These are in KB.
15091    static final long[] DUMP_MEM_BUCKETS = new long[] {
15092        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15093        120*1024, 160*1024, 200*1024,
15094        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15095        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15096    };
15097
15098    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15099            boolean stackLike) {
15100        int start = label.lastIndexOf('.');
15101        if (start >= 0) start++;
15102        else start = 0;
15103        int end = label.length();
15104        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15105            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15106                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15107                out.append(bucket);
15108                out.append(stackLike ? "MB." : "MB ");
15109                out.append(label, start, end);
15110                return;
15111            }
15112        }
15113        out.append(memKB/1024);
15114        out.append(stackLike ? "MB." : "MB ");
15115        out.append(label, start, end);
15116    }
15117
15118    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15119            ProcessList.NATIVE_ADJ,
15120            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15121            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15122            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15123            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15124            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15125            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15126    };
15127    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15128            "Native",
15129            "System", "Persistent", "Persistent Service", "Foreground",
15130            "Visible", "Perceptible",
15131            "Heavy Weight", "Backup",
15132            "A Services", "Home",
15133            "Previous", "B Services", "Cached"
15134    };
15135    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15136            "native",
15137            "sys", "pers", "persvc", "fore",
15138            "vis", "percept",
15139            "heavy", "backup",
15140            "servicea", "home",
15141            "prev", "serviceb", "cached"
15142    };
15143
15144    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15145            long realtime, boolean isCheckinRequest, boolean isCompact) {
15146        if (isCheckinRequest || isCompact) {
15147            // short checkin version
15148            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15149        } else {
15150            pw.println("Applications Memory Usage (in Kilobytes):");
15151            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15152        }
15153    }
15154
15155    private static final int KSM_SHARED = 0;
15156    private static final int KSM_SHARING = 1;
15157    private static final int KSM_UNSHARED = 2;
15158    private static final int KSM_VOLATILE = 3;
15159
15160    private final long[] getKsmInfo() {
15161        long[] longOut = new long[4];
15162        final int[] SINGLE_LONG_FORMAT = new int[] {
15163            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15164        };
15165        long[] longTmp = new long[1];
15166        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15167                SINGLE_LONG_FORMAT, null, longTmp, null);
15168        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15169        longTmp[0] = 0;
15170        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15171                SINGLE_LONG_FORMAT, null, longTmp, null);
15172        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15173        longTmp[0] = 0;
15174        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15175                SINGLE_LONG_FORMAT, null, longTmp, null);
15176        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15177        longTmp[0] = 0;
15178        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15179                SINGLE_LONG_FORMAT, null, longTmp, null);
15180        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15181        return longOut;
15182    }
15183
15184    private static String stringifySize(long size, int order) {
15185        Locale locale = Locale.US;
15186        switch (order) {
15187            case 1:
15188                return String.format(locale, "%,13d", size);
15189            case 1024:
15190                return String.format(locale, "%,9dK", size / 1024);
15191            case 1024 * 1024:
15192                return String.format(locale, "%,5dM", size / 1024 / 1024);
15193            case 1024 * 1024 * 1024:
15194                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15195            default:
15196                throw new IllegalArgumentException("Invalid size order");
15197        }
15198    }
15199
15200    private static String stringifyKBSize(long size) {
15201        return stringifySize(size * 1024, 1024);
15202    }
15203
15204    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15205            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15206        boolean dumpDetails = false;
15207        boolean dumpFullDetails = false;
15208        boolean dumpDalvik = false;
15209        boolean dumpSummaryOnly = false;
15210        boolean oomOnly = false;
15211        boolean isCompact = false;
15212        boolean localOnly = false;
15213        boolean packages = false;
15214
15215        int opti = 0;
15216        while (opti < args.length) {
15217            String opt = args[opti];
15218            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15219                break;
15220            }
15221            opti++;
15222            if ("-a".equals(opt)) {
15223                dumpDetails = true;
15224                dumpFullDetails = true;
15225                dumpDalvik = true;
15226            } else if ("-d".equals(opt)) {
15227                dumpDalvik = true;
15228            } else if ("-c".equals(opt)) {
15229                isCompact = true;
15230            } else if ("-s".equals(opt)) {
15231                dumpDetails = true;
15232                dumpSummaryOnly = true;
15233            } else if ("--oom".equals(opt)) {
15234                oomOnly = true;
15235            } else if ("--local".equals(opt)) {
15236                localOnly = true;
15237            } else if ("--package".equals(opt)) {
15238                packages = true;
15239            } else if ("-h".equals(opt)) {
15240                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15241                pw.println("  -a: include all available information for each process.");
15242                pw.println("  -d: include dalvik details.");
15243                pw.println("  -c: dump in a compact machine-parseable representation.");
15244                pw.println("  -s: dump only summary of application memory usage.");
15245                pw.println("  --oom: only show processes organized by oom adj.");
15246                pw.println("  --local: only collect details locally, don't call process.");
15247                pw.println("  --package: interpret process arg as package, dumping all");
15248                pw.println("             processes that have loaded that package.");
15249                pw.println("If [process] is specified it can be the name or ");
15250                pw.println("pid of a specific process to dump.");
15251                return;
15252            } else {
15253                pw.println("Unknown argument: " + opt + "; use -h for help");
15254            }
15255        }
15256
15257        final boolean isCheckinRequest = scanArgs(args, "--checkin");
15258        long uptime = SystemClock.uptimeMillis();
15259        long realtime = SystemClock.elapsedRealtime();
15260        final long[] tmpLong = new long[1];
15261
15262        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15263        if (procs == null) {
15264            // No Java processes.  Maybe they want to print a native process.
15265            if (args != null && args.length > opti
15266                    && args[opti].charAt(0) != '-') {
15267                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15268                        = new ArrayList<ProcessCpuTracker.Stats>();
15269                updateCpuStatsNow();
15270                int findPid = -1;
15271                try {
15272                    findPid = Integer.parseInt(args[opti]);
15273                } catch (NumberFormatException e) {
15274                }
15275                synchronized (mProcessCpuTracker) {
15276                    final int N = mProcessCpuTracker.countStats();
15277                    for (int i=0; i<N; i++) {
15278                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15279                        if (st.pid == findPid || (st.baseName != null
15280                                && st.baseName.equals(args[opti]))) {
15281                            nativeProcs.add(st);
15282                        }
15283                    }
15284                }
15285                if (nativeProcs.size() > 0) {
15286                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15287                            isCompact);
15288                    Debug.MemoryInfo mi = null;
15289                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15290                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15291                        final int pid = r.pid;
15292                        if (!isCheckinRequest && dumpDetails) {
15293                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15294                        }
15295                        if (mi == null) {
15296                            mi = new Debug.MemoryInfo();
15297                        }
15298                        if (dumpDetails || (!brief && !oomOnly)) {
15299                            Debug.getMemoryInfo(pid, mi);
15300                        } else {
15301                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15302                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15303                        }
15304                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15305                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15306                        if (isCheckinRequest) {
15307                            pw.println();
15308                        }
15309                    }
15310                    return;
15311                }
15312            }
15313            pw.println("No process found for: " + args[opti]);
15314            return;
15315        }
15316
15317        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15318            dumpDetails = true;
15319        }
15320
15321        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15322
15323        String[] innerArgs = new String[args.length-opti];
15324        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15325
15326        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15327        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15328        long nativePss = 0;
15329        long dalvikPss = 0;
15330        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15331                EmptyArray.LONG;
15332        long otherPss = 0;
15333        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15334
15335        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15336        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15337                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15338
15339        long totalPss = 0;
15340        long cachedPss = 0;
15341
15342        Debug.MemoryInfo mi = null;
15343        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15344            final ProcessRecord r = procs.get(i);
15345            final IApplicationThread thread;
15346            final int pid;
15347            final int oomAdj;
15348            final boolean hasActivities;
15349            synchronized (this) {
15350                thread = r.thread;
15351                pid = r.pid;
15352                oomAdj = r.getSetAdjWithServices();
15353                hasActivities = r.activities.size() > 0;
15354            }
15355            if (thread != null) {
15356                if (!isCheckinRequest && dumpDetails) {
15357                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15358                }
15359                if (mi == null) {
15360                    mi = new Debug.MemoryInfo();
15361                }
15362                if (dumpDetails || (!brief && !oomOnly)) {
15363                    Debug.getMemoryInfo(pid, mi);
15364                } else {
15365                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15366                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15367                }
15368                if (dumpDetails) {
15369                    if (localOnly) {
15370                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15371                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15372                        if (isCheckinRequest) {
15373                            pw.println();
15374                        }
15375                    } else {
15376                        try {
15377                            pw.flush();
15378                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15379                                    dumpDalvik, dumpSummaryOnly, innerArgs);
15380                        } catch (RemoteException e) {
15381                            if (!isCheckinRequest) {
15382                                pw.println("Got RemoteException!");
15383                                pw.flush();
15384                            }
15385                        }
15386                    }
15387                }
15388
15389                final long myTotalPss = mi.getTotalPss();
15390                final long myTotalUss = mi.getTotalUss();
15391
15392                synchronized (this) {
15393                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15394                        // Record this for posterity if the process has been stable.
15395                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15396                    }
15397                }
15398
15399                if (!isCheckinRequest && mi != null) {
15400                    totalPss += myTotalPss;
15401                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15402                            (hasActivities ? " / activities)" : ")"),
15403                            r.processName, myTotalPss, pid, hasActivities);
15404                    procMems.add(pssItem);
15405                    procMemsMap.put(pid, pssItem);
15406
15407                    nativePss += mi.nativePss;
15408                    dalvikPss += mi.dalvikPss;
15409                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15410                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15411                    }
15412                    otherPss += mi.otherPss;
15413                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15414                        long mem = mi.getOtherPss(j);
15415                        miscPss[j] += mem;
15416                        otherPss -= mem;
15417                    }
15418
15419                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15420                        cachedPss += myTotalPss;
15421                    }
15422
15423                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15424                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
15425                                || oomIndex == (oomPss.length-1)) {
15426                            oomPss[oomIndex] += myTotalPss;
15427                            if (oomProcs[oomIndex] == null) {
15428                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15429                            }
15430                            oomProcs[oomIndex].add(pssItem);
15431                            break;
15432                        }
15433                    }
15434                }
15435            }
15436        }
15437
15438        long nativeProcTotalPss = 0;
15439
15440        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15441            // If we are showing aggregations, also look for native processes to
15442            // include so that our aggregations are more accurate.
15443            updateCpuStatsNow();
15444            mi = null;
15445            synchronized (mProcessCpuTracker) {
15446                final int N = mProcessCpuTracker.countStats();
15447                for (int i=0; i<N; i++) {
15448                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15449                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15450                        if (mi == null) {
15451                            mi = new Debug.MemoryInfo();
15452                        }
15453                        if (!brief && !oomOnly) {
15454                            Debug.getMemoryInfo(st.pid, mi);
15455                        } else {
15456                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15457                            mi.nativePrivateDirty = (int)tmpLong[0];
15458                        }
15459
15460                        final long myTotalPss = mi.getTotalPss();
15461                        totalPss += myTotalPss;
15462                        nativeProcTotalPss += myTotalPss;
15463
15464                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15465                                st.name, myTotalPss, st.pid, false);
15466                        procMems.add(pssItem);
15467
15468                        nativePss += mi.nativePss;
15469                        dalvikPss += mi.dalvikPss;
15470                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15471                            dalvikSubitemPss[j] += mi.getOtherPss(
15472                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
15473                        }
15474                        otherPss += mi.otherPss;
15475                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15476                            long mem = mi.getOtherPss(j);
15477                            miscPss[j] += mem;
15478                            otherPss -= mem;
15479                        }
15480                        oomPss[0] += myTotalPss;
15481                        if (oomProcs[0] == null) {
15482                            oomProcs[0] = new ArrayList<MemItem>();
15483                        }
15484                        oomProcs[0].add(pssItem);
15485                    }
15486                }
15487            }
15488
15489            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15490
15491            catMems.add(new MemItem("Native", "Native", nativePss, -1));
15492            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
15493            if (dalvikSubitemPss.length > 0) {
15494                dalvikItem.subitems = new ArrayList<MemItem>();
15495                for (int j=0; j<dalvikSubitemPss.length; j++) {
15496                    final String name = Debug.MemoryInfo.getOtherLabel(
15497                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15498                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
15499                }
15500            }
15501            catMems.add(dalvikItem);
15502            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
15503            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15504                String label = Debug.MemoryInfo.getOtherLabel(j);
15505                catMems.add(new MemItem(label, label, miscPss[j], j));
15506            }
15507
15508            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15509            for (int j=0; j<oomPss.length; j++) {
15510                if (oomPss[j] != 0) {
15511                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15512                            : DUMP_MEM_OOM_LABEL[j];
15513                    MemItem item = new MemItem(label, label, oomPss[j],
15514                            DUMP_MEM_OOM_ADJ[j]);
15515                    item.subitems = oomProcs[j];
15516                    oomMems.add(item);
15517                }
15518            }
15519
15520            if (!brief && !oomOnly && !isCompact) {
15521                pw.println();
15522                pw.println("Total PSS by process:");
15523                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
15524                pw.println();
15525            }
15526            if (!isCompact) {
15527                pw.println("Total PSS by OOM adjustment:");
15528            }
15529            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
15530            if (!brief && !oomOnly) {
15531                PrintWriter out = categoryPw != null ? categoryPw : pw;
15532                if (!isCompact) {
15533                    out.println();
15534                    out.println("Total PSS by category:");
15535                }
15536                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
15537            }
15538            if (!isCompact) {
15539                pw.println();
15540            }
15541            MemInfoReader memInfo = new MemInfoReader();
15542            memInfo.readMemInfo();
15543            if (nativeProcTotalPss > 0) {
15544                synchronized (this) {
15545                    final long cachedKb = memInfo.getCachedSizeKb();
15546                    final long freeKb = memInfo.getFreeSizeKb();
15547                    final long zramKb = memInfo.getZramTotalSizeKb();
15548                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15549                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15550                            kernelKb*1024, nativeProcTotalPss*1024);
15551                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15552                            nativeProcTotalPss);
15553                }
15554            }
15555            if (!brief) {
15556                if (!isCompact) {
15557                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15558                    pw.print(" (status ");
15559                    switch (mLastMemoryLevel) {
15560                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15561                            pw.println("normal)");
15562                            break;
15563                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15564                            pw.println("moderate)");
15565                            break;
15566                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15567                            pw.println("low)");
15568                            break;
15569                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15570                            pw.println("critical)");
15571                            break;
15572                        default:
15573                            pw.print(mLastMemoryLevel);
15574                            pw.println(")");
15575                            break;
15576                    }
15577                    pw.print(" Free RAM: ");
15578                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15579                            + memInfo.getFreeSizeKb()));
15580                    pw.print(" (");
15581                    pw.print(stringifyKBSize(cachedPss));
15582                    pw.print(" cached pss + ");
15583                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15584                    pw.print(" cached kernel + ");
15585                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15586                    pw.println(" free)");
15587                } else {
15588                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15589                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15590                            + memInfo.getFreeSizeKb()); pw.print(",");
15591                    pw.println(totalPss - cachedPss);
15592                }
15593            }
15594            if (!isCompact) {
15595                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15596                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15597                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15598                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15599                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(memInfo.getTotalSizeKb()
15600                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15601                        - memInfo.getKernelUsedSizeKb()));
15602            } else {
15603                pw.print("lostram,"); pw.println(memInfo.getTotalSizeKb()
15604                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15605                        - memInfo.getKernelUsedSizeKb());
15606            }
15607            if (!brief) {
15608                if (memInfo.getZramTotalSizeKb() != 0) {
15609                    if (!isCompact) {
15610                        pw.print("     ZRAM: ");
15611                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15612                                pw.print(" physical used for ");
15613                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15614                                        - memInfo.getSwapFreeSizeKb()));
15615                                pw.print(" in swap (");
15616                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15617                                pw.println(" total swap)");
15618                    } else {
15619                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15620                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15621                                pw.println(memInfo.getSwapFreeSizeKb());
15622                    }
15623                }
15624                final long[] ksm = getKsmInfo();
15625                if (!isCompact) {
15626                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15627                            || ksm[KSM_VOLATILE] != 0) {
15628                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15629                                pw.print(" saved from shared ");
15630                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15631                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15632                                pw.print(" unshared; ");
15633                                pw.print(stringifyKBSize(
15634                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15635                    }
15636                    pw.print("   Tuning: ");
15637                    pw.print(ActivityManager.staticGetMemoryClass());
15638                    pw.print(" (large ");
15639                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15640                    pw.print("), oom ");
15641                    pw.print(stringifySize(
15642                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15643                    pw.print(", restore limit ");
15644                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15645                    if (ActivityManager.isLowRamDeviceStatic()) {
15646                        pw.print(" (low-ram)");
15647                    }
15648                    if (ActivityManager.isHighEndGfx()) {
15649                        pw.print(" (high-end-gfx)");
15650                    }
15651                    pw.println();
15652                } else {
15653                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15654                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15655                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15656                    pw.print("tuning,");
15657                    pw.print(ActivityManager.staticGetMemoryClass());
15658                    pw.print(',');
15659                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15660                    pw.print(',');
15661                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15662                    if (ActivityManager.isLowRamDeviceStatic()) {
15663                        pw.print(",low-ram");
15664                    }
15665                    if (ActivityManager.isHighEndGfx()) {
15666                        pw.print(",high-end-gfx");
15667                    }
15668                    pw.println();
15669                }
15670            }
15671        }
15672    }
15673
15674    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15675            long memtrack, String name) {
15676        sb.append("  ");
15677        sb.append(ProcessList.makeOomAdjString(oomAdj));
15678        sb.append(' ');
15679        sb.append(ProcessList.makeProcStateString(procState));
15680        sb.append(' ');
15681        ProcessList.appendRamKb(sb, pss);
15682        sb.append(": ");
15683        sb.append(name);
15684        if (memtrack > 0) {
15685            sb.append(" (");
15686            sb.append(stringifyKBSize(memtrack));
15687            sb.append(" memtrack)");
15688        }
15689    }
15690
15691    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15692        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15693        sb.append(" (pid ");
15694        sb.append(mi.pid);
15695        sb.append(") ");
15696        sb.append(mi.adjType);
15697        sb.append('\n');
15698        if (mi.adjReason != null) {
15699            sb.append("                      ");
15700            sb.append(mi.adjReason);
15701            sb.append('\n');
15702        }
15703    }
15704
15705    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15706        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15707        for (int i=0, N=memInfos.size(); i<N; i++) {
15708            ProcessMemInfo mi = memInfos.get(i);
15709            infoMap.put(mi.pid, mi);
15710        }
15711        updateCpuStatsNow();
15712        long[] memtrackTmp = new long[1];
15713        synchronized (mProcessCpuTracker) {
15714            final int N = mProcessCpuTracker.countStats();
15715            for (int i=0; i<N; i++) {
15716                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15717                if (st.vsize > 0) {
15718                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15719                    if (pss > 0) {
15720                        if (infoMap.indexOfKey(st.pid) < 0) {
15721                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15722                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15723                            mi.pss = pss;
15724                            mi.memtrack = memtrackTmp[0];
15725                            memInfos.add(mi);
15726                        }
15727                    }
15728                }
15729            }
15730        }
15731
15732        long totalPss = 0;
15733        long totalMemtrack = 0;
15734        for (int i=0, N=memInfos.size(); i<N; i++) {
15735            ProcessMemInfo mi = memInfos.get(i);
15736            if (mi.pss == 0) {
15737                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15738                mi.memtrack = memtrackTmp[0];
15739            }
15740            totalPss += mi.pss;
15741            totalMemtrack += mi.memtrack;
15742        }
15743        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15744            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15745                if (lhs.oomAdj != rhs.oomAdj) {
15746                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15747                }
15748                if (lhs.pss != rhs.pss) {
15749                    return lhs.pss < rhs.pss ? 1 : -1;
15750                }
15751                return 0;
15752            }
15753        });
15754
15755        StringBuilder tag = new StringBuilder(128);
15756        StringBuilder stack = new StringBuilder(128);
15757        tag.append("Low on memory -- ");
15758        appendMemBucket(tag, totalPss, "total", false);
15759        appendMemBucket(stack, totalPss, "total", true);
15760
15761        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15762        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15763        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15764
15765        boolean firstLine = true;
15766        int lastOomAdj = Integer.MIN_VALUE;
15767        long extraNativeRam = 0;
15768        long extraNativeMemtrack = 0;
15769        long cachedPss = 0;
15770        for (int i=0, N=memInfos.size(); i<N; i++) {
15771            ProcessMemInfo mi = memInfos.get(i);
15772
15773            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15774                cachedPss += mi.pss;
15775            }
15776
15777            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15778                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15779                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15780                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15781                if (lastOomAdj != mi.oomAdj) {
15782                    lastOomAdj = mi.oomAdj;
15783                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15784                        tag.append(" / ");
15785                    }
15786                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15787                        if (firstLine) {
15788                            stack.append(":");
15789                            firstLine = false;
15790                        }
15791                        stack.append("\n\t at ");
15792                    } else {
15793                        stack.append("$");
15794                    }
15795                } else {
15796                    tag.append(" ");
15797                    stack.append("$");
15798                }
15799                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15800                    appendMemBucket(tag, mi.pss, mi.name, false);
15801                }
15802                appendMemBucket(stack, mi.pss, mi.name, true);
15803                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15804                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15805                    stack.append("(");
15806                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15807                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15808                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15809                            stack.append(":");
15810                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15811                        }
15812                    }
15813                    stack.append(")");
15814                }
15815            }
15816
15817            appendMemInfo(fullNativeBuilder, mi);
15818            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15819                // The short form only has native processes that are >= 512K.
15820                if (mi.pss >= 512) {
15821                    appendMemInfo(shortNativeBuilder, mi);
15822                } else {
15823                    extraNativeRam += mi.pss;
15824                    extraNativeMemtrack += mi.memtrack;
15825                }
15826            } else {
15827                // Short form has all other details, but if we have collected RAM
15828                // from smaller native processes let's dump a summary of that.
15829                if (extraNativeRam > 0) {
15830                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15831                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15832                    shortNativeBuilder.append('\n');
15833                    extraNativeRam = 0;
15834                }
15835                appendMemInfo(fullJavaBuilder, mi);
15836            }
15837        }
15838
15839        fullJavaBuilder.append("           ");
15840        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15841        fullJavaBuilder.append(": TOTAL");
15842        if (totalMemtrack > 0) {
15843            fullJavaBuilder.append(" (");
15844            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15845            fullJavaBuilder.append(" memtrack)");
15846        } else {
15847        }
15848        fullJavaBuilder.append("\n");
15849
15850        MemInfoReader memInfo = new MemInfoReader();
15851        memInfo.readMemInfo();
15852        final long[] infos = memInfo.getRawInfo();
15853
15854        StringBuilder memInfoBuilder = new StringBuilder(1024);
15855        Debug.getMemInfo(infos);
15856        memInfoBuilder.append("  MemInfo: ");
15857        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15858        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15859        memInfoBuilder.append(stringifyKBSize(
15860                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15861        memInfoBuilder.append(stringifyKBSize(
15862                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15863        memInfoBuilder.append(stringifyKBSize(
15864                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
15865        memInfoBuilder.append("           ");
15866        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
15867        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
15868        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
15869        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
15870        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15871            memInfoBuilder.append("  ZRAM: ");
15872            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
15873            memInfoBuilder.append(" RAM, ");
15874            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
15875            memInfoBuilder.append(" swap total, ");
15876            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
15877            memInfoBuilder.append(" swap free\n");
15878        }
15879        final long[] ksm = getKsmInfo();
15880        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15881                || ksm[KSM_VOLATILE] != 0) {
15882            memInfoBuilder.append("  KSM: ");
15883            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
15884            memInfoBuilder.append(" saved from shared ");
15885            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
15886            memInfoBuilder.append("\n       ");
15887            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
15888            memInfoBuilder.append(" unshared; ");
15889            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
15890            memInfoBuilder.append(" volatile\n");
15891        }
15892        memInfoBuilder.append("  Free RAM: ");
15893        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15894                + memInfo.getFreeSizeKb()));
15895        memInfoBuilder.append("\n");
15896        memInfoBuilder.append("  Used RAM: ");
15897        memInfoBuilder.append(stringifyKBSize(
15898                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
15899        memInfoBuilder.append("\n");
15900        memInfoBuilder.append("  Lost RAM: ");
15901        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
15902                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15903                - memInfo.getKernelUsedSizeKb()));
15904        memInfoBuilder.append("\n");
15905        Slog.i(TAG, "Low on memory:");
15906        Slog.i(TAG, shortNativeBuilder.toString());
15907        Slog.i(TAG, fullJavaBuilder.toString());
15908        Slog.i(TAG, memInfoBuilder.toString());
15909
15910        StringBuilder dropBuilder = new StringBuilder(1024);
15911        /*
15912        StringWriter oomSw = new StringWriter();
15913        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15914        StringWriter catSw = new StringWriter();
15915        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15916        String[] emptyArgs = new String[] { };
15917        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15918        oomPw.flush();
15919        String oomString = oomSw.toString();
15920        */
15921        dropBuilder.append("Low on memory:");
15922        dropBuilder.append(stack);
15923        dropBuilder.append('\n');
15924        dropBuilder.append(fullNativeBuilder);
15925        dropBuilder.append(fullJavaBuilder);
15926        dropBuilder.append('\n');
15927        dropBuilder.append(memInfoBuilder);
15928        dropBuilder.append('\n');
15929        /*
15930        dropBuilder.append(oomString);
15931        dropBuilder.append('\n');
15932        */
15933        StringWriter catSw = new StringWriter();
15934        synchronized (ActivityManagerService.this) {
15935            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15936            String[] emptyArgs = new String[] { };
15937            catPw.println();
15938            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15939            catPw.println();
15940            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15941                    false, false, null);
15942            catPw.println();
15943            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15944            catPw.flush();
15945        }
15946        dropBuilder.append(catSw.toString());
15947        addErrorToDropBox("lowmem", null, "system_server", null,
15948                null, tag.toString(), dropBuilder.toString(), null, null);
15949        //Slog.i(TAG, "Sent to dropbox:");
15950        //Slog.i(TAG, dropBuilder.toString());
15951        synchronized (ActivityManagerService.this) {
15952            long now = SystemClock.uptimeMillis();
15953            if (mLastMemUsageReportTime < now) {
15954                mLastMemUsageReportTime = now;
15955            }
15956        }
15957    }
15958
15959    /**
15960     * Searches array of arguments for the specified string
15961     * @param args array of argument strings
15962     * @param value value to search for
15963     * @return true if the value is contained in the array
15964     */
15965    private static boolean scanArgs(String[] args, String value) {
15966        if (args != null) {
15967            for (String arg : args) {
15968                if (value.equals(arg)) {
15969                    return true;
15970                }
15971            }
15972        }
15973        return false;
15974    }
15975
15976    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15977            ContentProviderRecord cpr, boolean always) {
15978        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15979
15980        if (!inLaunching || always) {
15981            synchronized (cpr) {
15982                cpr.launchingApp = null;
15983                cpr.notifyAll();
15984            }
15985            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15986            String names[] = cpr.info.authority.split(";");
15987            for (int j = 0; j < names.length; j++) {
15988                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15989            }
15990        }
15991
15992        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15993            ContentProviderConnection conn = cpr.connections.get(i);
15994            if (conn.waiting) {
15995                // If this connection is waiting for the provider, then we don't
15996                // need to mess with its process unless we are always removing
15997                // or for some reason the provider is not currently launching.
15998                if (inLaunching && !always) {
15999                    continue;
16000                }
16001            }
16002            ProcessRecord capp = conn.client;
16003            conn.dead = true;
16004            if (conn.stableCount > 0) {
16005                if (!capp.persistent && capp.thread != null
16006                        && capp.pid != 0
16007                        && capp.pid != MY_PID) {
16008                    capp.kill("depends on provider "
16009                            + cpr.name.flattenToShortString()
16010                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16011                }
16012            } else if (capp.thread != null && conn.provider.provider != null) {
16013                try {
16014                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16015                } catch (RemoteException e) {
16016                }
16017                // In the protocol here, we don't expect the client to correctly
16018                // clean up this connection, we'll just remove it.
16019                cpr.connections.remove(i);
16020                if (conn.client.conProviders.remove(conn)) {
16021                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16022                }
16023            }
16024        }
16025
16026        if (inLaunching && always) {
16027            mLaunchingProviders.remove(cpr);
16028        }
16029        return inLaunching;
16030    }
16031
16032    /**
16033     * Main code for cleaning up a process when it has gone away.  This is
16034     * called both as a result of the process dying, or directly when stopping
16035     * a process when running in single process mode.
16036     *
16037     * @return Returns true if the given process has been restarted, so the
16038     * app that was passed in must remain on the process lists.
16039     */
16040    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16041            boolean restarting, boolean allowRestart, int index) {
16042        if (index >= 0) {
16043            removeLruProcessLocked(app);
16044            ProcessList.remove(app.pid);
16045        }
16046
16047        mProcessesToGc.remove(app);
16048        mPendingPssProcesses.remove(app);
16049
16050        // Dismiss any open dialogs.
16051        if (app.crashDialog != null && !app.forceCrashReport) {
16052            app.crashDialog.dismiss();
16053            app.crashDialog = null;
16054        }
16055        if (app.anrDialog != null) {
16056            app.anrDialog.dismiss();
16057            app.anrDialog = null;
16058        }
16059        if (app.waitDialog != null) {
16060            app.waitDialog.dismiss();
16061            app.waitDialog = null;
16062        }
16063
16064        app.crashing = false;
16065        app.notResponding = false;
16066
16067        app.resetPackageList(mProcessStats);
16068        app.unlinkDeathRecipient();
16069        app.makeInactive(mProcessStats);
16070        app.waitingToKill = null;
16071        app.forcingToForeground = null;
16072        updateProcessForegroundLocked(app, false, false);
16073        app.foregroundActivities = false;
16074        app.hasShownUi = false;
16075        app.treatLikeActivity = false;
16076        app.hasAboveClient = false;
16077        app.hasClientActivities = false;
16078
16079        mServices.killServicesLocked(app, allowRestart);
16080
16081        boolean restart = false;
16082
16083        // Remove published content providers.
16084        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16085            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16086            final boolean always = app.bad || !allowRestart;
16087            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16088            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16089                // We left the provider in the launching list, need to
16090                // restart it.
16091                restart = true;
16092            }
16093
16094            cpr.provider = null;
16095            cpr.proc = null;
16096        }
16097        app.pubProviders.clear();
16098
16099        // Take care of any launching providers waiting for this process.
16100        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16101            restart = true;
16102        }
16103
16104        // Unregister from connected content providers.
16105        if (!app.conProviders.isEmpty()) {
16106            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16107                ContentProviderConnection conn = app.conProviders.get(i);
16108                conn.provider.connections.remove(conn);
16109                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16110                        conn.provider.name);
16111            }
16112            app.conProviders.clear();
16113        }
16114
16115        // At this point there may be remaining entries in mLaunchingProviders
16116        // where we were the only one waiting, so they are no longer of use.
16117        // Look for these and clean up if found.
16118        // XXX Commented out for now.  Trying to figure out a way to reproduce
16119        // the actual situation to identify what is actually going on.
16120        if (false) {
16121            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16122                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16123                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16124                    synchronized (cpr) {
16125                        cpr.launchingApp = null;
16126                        cpr.notifyAll();
16127                    }
16128                }
16129            }
16130        }
16131
16132        skipCurrentReceiverLocked(app);
16133
16134        // Unregister any receivers.
16135        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16136            removeReceiverLocked(app.receivers.valueAt(i));
16137        }
16138        app.receivers.clear();
16139
16140        // If the app is undergoing backup, tell the backup manager about it
16141        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16142            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16143                    + mBackupTarget.appInfo + " died during backup");
16144            try {
16145                IBackupManager bm = IBackupManager.Stub.asInterface(
16146                        ServiceManager.getService(Context.BACKUP_SERVICE));
16147                bm.agentDisconnected(app.info.packageName);
16148            } catch (RemoteException e) {
16149                // can't happen; backup manager is local
16150            }
16151        }
16152
16153        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16154            ProcessChangeItem item = mPendingProcessChanges.get(i);
16155            if (item.pid == app.pid) {
16156                mPendingProcessChanges.remove(i);
16157                mAvailProcessChanges.add(item);
16158            }
16159        }
16160        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16161                null).sendToTarget();
16162
16163        // If the caller is restarting this app, then leave it in its
16164        // current lists and let the caller take care of it.
16165        if (restarting) {
16166            return false;
16167        }
16168
16169        if (!app.persistent || app.isolated) {
16170            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16171                    "Removing non-persistent process during cleanup: " + app);
16172            removeProcessNameLocked(app.processName, app.uid);
16173            if (mHeavyWeightProcess == app) {
16174                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16175                        mHeavyWeightProcess.userId, 0));
16176                mHeavyWeightProcess = null;
16177            }
16178        } else if (!app.removed) {
16179            // This app is persistent, so we need to keep its record around.
16180            // If it is not already on the pending app list, add it there
16181            // and start a new process for it.
16182            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16183                mPersistentStartingProcesses.add(app);
16184                restart = true;
16185            }
16186        }
16187        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16188                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16189        mProcessesOnHold.remove(app);
16190
16191        if (app == mHomeProcess) {
16192            mHomeProcess = null;
16193        }
16194        if (app == mPreviousProcess) {
16195            mPreviousProcess = null;
16196        }
16197
16198        if (restart && !app.isolated) {
16199            // We have components that still need to be running in the
16200            // process, so re-launch it.
16201            if (index < 0) {
16202                ProcessList.remove(app.pid);
16203            }
16204            addProcessNameLocked(app);
16205            startProcessLocked(app, "restart", app.processName);
16206            return true;
16207        } else if (app.pid > 0 && app.pid != MY_PID) {
16208            // Goodbye!
16209            boolean removed;
16210            synchronized (mPidsSelfLocked) {
16211                mPidsSelfLocked.remove(app.pid);
16212                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16213            }
16214            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16215            if (app.isolated) {
16216                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16217            }
16218            app.setPid(0);
16219        }
16220        return false;
16221    }
16222
16223    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16224        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16225            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16226            if (cpr.launchingApp == app) {
16227                return true;
16228            }
16229        }
16230        return false;
16231    }
16232
16233    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16234        // Look through the content providers we are waiting to have launched,
16235        // and if any run in this process then either schedule a restart of
16236        // the process or kill the client waiting for it if this process has
16237        // gone bad.
16238        boolean restart = false;
16239        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16240            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16241            if (cpr.launchingApp == app) {
16242                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16243                    restart = true;
16244                } else {
16245                    removeDyingProviderLocked(app, cpr, true);
16246                }
16247            }
16248        }
16249        return restart;
16250    }
16251
16252    // =========================================================
16253    // SERVICES
16254    // =========================================================
16255
16256    @Override
16257    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16258            int flags) {
16259        enforceNotIsolatedCaller("getServices");
16260        synchronized (this) {
16261            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16262        }
16263    }
16264
16265    @Override
16266    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16267        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16268        synchronized (this) {
16269            return mServices.getRunningServiceControlPanelLocked(name);
16270        }
16271    }
16272
16273    @Override
16274    public ComponentName startService(IApplicationThread caller, Intent service,
16275            String resolvedType, String callingPackage, int userId)
16276            throws TransactionTooLargeException {
16277        enforceNotIsolatedCaller("startService");
16278        // Refuse possible leaked file descriptors
16279        if (service != null && service.hasFileDescriptors() == true) {
16280            throw new IllegalArgumentException("File descriptors passed in Intent");
16281        }
16282
16283        if (callingPackage == null) {
16284            throw new IllegalArgumentException("callingPackage cannot be null");
16285        }
16286
16287        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16288                "startService: " + service + " type=" + resolvedType);
16289        synchronized(this) {
16290            final int callingPid = Binder.getCallingPid();
16291            final int callingUid = Binder.getCallingUid();
16292            final long origId = Binder.clearCallingIdentity();
16293            ComponentName res = mServices.startServiceLocked(caller, service,
16294                    resolvedType, callingPid, callingUid, callingPackage, userId);
16295            Binder.restoreCallingIdentity(origId);
16296            return res;
16297        }
16298    }
16299
16300    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16301            String callingPackage, int userId)
16302            throws TransactionTooLargeException {
16303        synchronized(this) {
16304            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16305                    "startServiceInPackage: " + service + " type=" + resolvedType);
16306            final long origId = Binder.clearCallingIdentity();
16307            ComponentName res = mServices.startServiceLocked(null, service,
16308                    resolvedType, -1, uid, callingPackage, userId);
16309            Binder.restoreCallingIdentity(origId);
16310            return res;
16311        }
16312    }
16313
16314    @Override
16315    public int stopService(IApplicationThread caller, Intent service,
16316            String resolvedType, int userId) {
16317        enforceNotIsolatedCaller("stopService");
16318        // Refuse possible leaked file descriptors
16319        if (service != null && service.hasFileDescriptors() == true) {
16320            throw new IllegalArgumentException("File descriptors passed in Intent");
16321        }
16322
16323        synchronized(this) {
16324            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16325        }
16326    }
16327
16328    @Override
16329    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16330        enforceNotIsolatedCaller("peekService");
16331        // Refuse possible leaked file descriptors
16332        if (service != null && service.hasFileDescriptors() == true) {
16333            throw new IllegalArgumentException("File descriptors passed in Intent");
16334        }
16335
16336        if (callingPackage == null) {
16337            throw new IllegalArgumentException("callingPackage cannot be null");
16338        }
16339
16340        synchronized(this) {
16341            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16342        }
16343    }
16344
16345    @Override
16346    public boolean stopServiceToken(ComponentName className, IBinder token,
16347            int startId) {
16348        synchronized(this) {
16349            return mServices.stopServiceTokenLocked(className, token, startId);
16350        }
16351    }
16352
16353    @Override
16354    public void setServiceForeground(ComponentName className, IBinder token,
16355            int id, Notification notification, boolean removeNotification) {
16356        synchronized(this) {
16357            mServices.setServiceForegroundLocked(className, token, id, notification,
16358                    removeNotification);
16359        }
16360    }
16361
16362    @Override
16363    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16364            boolean requireFull, String name, String callerPackage) {
16365        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16366                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16367    }
16368
16369    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16370            String className, int flags) {
16371        boolean result = false;
16372        // For apps that don't have pre-defined UIDs, check for permission
16373        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16374            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16375                if (ActivityManager.checkUidPermission(
16376                        INTERACT_ACROSS_USERS,
16377                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16378                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16379                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16380                            + " requests FLAG_SINGLE_USER, but app does not hold "
16381                            + INTERACT_ACROSS_USERS;
16382                    Slog.w(TAG, msg);
16383                    throw new SecurityException(msg);
16384                }
16385                // Permission passed
16386                result = true;
16387            }
16388        } else if ("system".equals(componentProcessName)) {
16389            result = true;
16390        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16391            // Phone app and persistent apps are allowed to export singleuser providers.
16392            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16393                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16394        }
16395        if (DEBUG_MU) Slog.v(TAG_MU,
16396                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16397                + Integer.toHexString(flags) + ") = " + result);
16398        return result;
16399    }
16400
16401    /**
16402     * Checks to see if the caller is in the same app as the singleton
16403     * component, or the component is in a special app. It allows special apps
16404     * to export singleton components but prevents exporting singleton
16405     * components for regular apps.
16406     */
16407    boolean isValidSingletonCall(int callingUid, int componentUid) {
16408        int componentAppId = UserHandle.getAppId(componentUid);
16409        return UserHandle.isSameApp(callingUid, componentUid)
16410                || componentAppId == Process.SYSTEM_UID
16411                || componentAppId == Process.PHONE_UID
16412                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16413                        == PackageManager.PERMISSION_GRANTED;
16414    }
16415
16416    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16417            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16418            int userId) throws TransactionTooLargeException {
16419        enforceNotIsolatedCaller("bindService");
16420
16421        // Refuse possible leaked file descriptors
16422        if (service != null && service.hasFileDescriptors() == true) {
16423            throw new IllegalArgumentException("File descriptors passed in Intent");
16424        }
16425
16426        if (callingPackage == null) {
16427            throw new IllegalArgumentException("callingPackage cannot be null");
16428        }
16429
16430        synchronized(this) {
16431            return mServices.bindServiceLocked(caller, token, service,
16432                    resolvedType, connection, flags, callingPackage, userId);
16433        }
16434    }
16435
16436    public boolean unbindService(IServiceConnection connection) {
16437        synchronized (this) {
16438            return mServices.unbindServiceLocked(connection);
16439        }
16440    }
16441
16442    public void publishService(IBinder token, Intent intent, IBinder service) {
16443        // Refuse possible leaked file descriptors
16444        if (intent != null && intent.hasFileDescriptors() == true) {
16445            throw new IllegalArgumentException("File descriptors passed in Intent");
16446        }
16447
16448        synchronized(this) {
16449            if (!(token instanceof ServiceRecord)) {
16450                throw new IllegalArgumentException("Invalid service token");
16451            }
16452            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16453        }
16454    }
16455
16456    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16457        // Refuse possible leaked file descriptors
16458        if (intent != null && intent.hasFileDescriptors() == true) {
16459            throw new IllegalArgumentException("File descriptors passed in Intent");
16460        }
16461
16462        synchronized(this) {
16463            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16464        }
16465    }
16466
16467    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16468        synchronized(this) {
16469            if (!(token instanceof ServiceRecord)) {
16470                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16471                throw new IllegalArgumentException("Invalid service token");
16472            }
16473            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16474        }
16475    }
16476
16477    // =========================================================
16478    // BACKUP AND RESTORE
16479    // =========================================================
16480
16481    // Cause the target app to be launched if necessary and its backup agent
16482    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16483    // activity manager to announce its creation.
16484    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16485        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16486                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16487        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16488
16489        synchronized(this) {
16490            // !!! TODO: currently no check here that we're already bound
16491            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16492            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16493            synchronized (stats) {
16494                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16495            }
16496
16497            // Backup agent is now in use, its package can't be stopped.
16498            try {
16499                AppGlobals.getPackageManager().setPackageStoppedState(
16500                        app.packageName, false, UserHandle.getUserId(app.uid));
16501            } catch (RemoteException e) {
16502            } catch (IllegalArgumentException e) {
16503                Slog.w(TAG, "Failed trying to unstop package "
16504                        + app.packageName + ": " + e);
16505            }
16506
16507            BackupRecord r = new BackupRecord(ss, app, backupMode);
16508            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16509                    ? new ComponentName(app.packageName, app.backupAgentName)
16510                    : new ComponentName("android", "FullBackupAgent");
16511            // startProcessLocked() returns existing proc's record if it's already running
16512            ProcessRecord proc = startProcessLocked(app.processName, app,
16513                    false, 0, "backup", hostingName, false, false, false);
16514            if (proc == null) {
16515                Slog.e(TAG, "Unable to start backup agent process " + r);
16516                return false;
16517            }
16518
16519            r.app = proc;
16520            mBackupTarget = r;
16521            mBackupAppName = app.packageName;
16522
16523            // Try not to kill the process during backup
16524            updateOomAdjLocked(proc);
16525
16526            // If the process is already attached, schedule the creation of the backup agent now.
16527            // If it is not yet live, this will be done when it attaches to the framework.
16528            if (proc.thread != null) {
16529                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16530                try {
16531                    proc.thread.scheduleCreateBackupAgent(app,
16532                            compatibilityInfoForPackageLocked(app), backupMode);
16533                } catch (RemoteException e) {
16534                    // Will time out on the backup manager side
16535                }
16536            } else {
16537                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16538            }
16539            // Invariants: at this point, the target app process exists and the application
16540            // is either already running or in the process of coming up.  mBackupTarget and
16541            // mBackupAppName describe the app, so that when it binds back to the AM we
16542            // know that it's scheduled for a backup-agent operation.
16543        }
16544
16545        return true;
16546    }
16547
16548    @Override
16549    public void clearPendingBackup() {
16550        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16551        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16552
16553        synchronized (this) {
16554            mBackupTarget = null;
16555            mBackupAppName = null;
16556        }
16557    }
16558
16559    // A backup agent has just come up
16560    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16561        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16562                + " = " + agent);
16563
16564        synchronized(this) {
16565            if (!agentPackageName.equals(mBackupAppName)) {
16566                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16567                return;
16568            }
16569        }
16570
16571        long oldIdent = Binder.clearCallingIdentity();
16572        try {
16573            IBackupManager bm = IBackupManager.Stub.asInterface(
16574                    ServiceManager.getService(Context.BACKUP_SERVICE));
16575            bm.agentConnected(agentPackageName, agent);
16576        } catch (RemoteException e) {
16577            // can't happen; the backup manager service is local
16578        } catch (Exception e) {
16579            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16580            e.printStackTrace();
16581        } finally {
16582            Binder.restoreCallingIdentity(oldIdent);
16583        }
16584    }
16585
16586    // done with this agent
16587    public void unbindBackupAgent(ApplicationInfo appInfo) {
16588        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16589        if (appInfo == null) {
16590            Slog.w(TAG, "unbind backup agent for null app");
16591            return;
16592        }
16593
16594        synchronized(this) {
16595            try {
16596                if (mBackupAppName == null) {
16597                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16598                    return;
16599                }
16600
16601                if (!mBackupAppName.equals(appInfo.packageName)) {
16602                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16603                    return;
16604                }
16605
16606                // Not backing this app up any more; reset its OOM adjustment
16607                final ProcessRecord proc = mBackupTarget.app;
16608                updateOomAdjLocked(proc);
16609
16610                // If the app crashed during backup, 'thread' will be null here
16611                if (proc.thread != null) {
16612                    try {
16613                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16614                                compatibilityInfoForPackageLocked(appInfo));
16615                    } catch (Exception e) {
16616                        Slog.e(TAG, "Exception when unbinding backup agent:");
16617                        e.printStackTrace();
16618                    }
16619                }
16620            } finally {
16621                mBackupTarget = null;
16622                mBackupAppName = null;
16623            }
16624        }
16625    }
16626    // =========================================================
16627    // BROADCASTS
16628    // =========================================================
16629
16630    boolean isPendingBroadcastProcessLocked(int pid) {
16631        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16632                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16633    }
16634
16635    void skipPendingBroadcastLocked(int pid) {
16636            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16637            for (BroadcastQueue queue : mBroadcastQueues) {
16638                queue.skipPendingBroadcastLocked(pid);
16639            }
16640    }
16641
16642    // The app just attached; send any pending broadcasts that it should receive
16643    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16644        boolean didSomething = false;
16645        for (BroadcastQueue queue : mBroadcastQueues) {
16646            didSomething |= queue.sendPendingBroadcastsLocked(app);
16647        }
16648        return didSomething;
16649    }
16650
16651    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16652            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16653        enforceNotIsolatedCaller("registerReceiver");
16654        ArrayList<Intent> stickyIntents = null;
16655        ProcessRecord callerApp = null;
16656        int callingUid;
16657        int callingPid;
16658        synchronized(this) {
16659            if (caller != null) {
16660                callerApp = getRecordForAppLocked(caller);
16661                if (callerApp == null) {
16662                    throw new SecurityException(
16663                            "Unable to find app for caller " + caller
16664                            + " (pid=" + Binder.getCallingPid()
16665                            + ") when registering receiver " + receiver);
16666                }
16667                if (callerApp.info.uid != Process.SYSTEM_UID &&
16668                        !callerApp.pkgList.containsKey(callerPackage) &&
16669                        !"android".equals(callerPackage)) {
16670                    throw new SecurityException("Given caller package " + callerPackage
16671                            + " is not running in process " + callerApp);
16672                }
16673                callingUid = callerApp.info.uid;
16674                callingPid = callerApp.pid;
16675            } else {
16676                callerPackage = null;
16677                callingUid = Binder.getCallingUid();
16678                callingPid = Binder.getCallingPid();
16679            }
16680
16681            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16682                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16683
16684            Iterator<String> actions = filter.actionsIterator();
16685            if (actions == null) {
16686                ArrayList<String> noAction = new ArrayList<String>(1);
16687                noAction.add(null);
16688                actions = noAction.iterator();
16689            }
16690
16691            // Collect stickies of users
16692            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16693            while (actions.hasNext()) {
16694                String action = actions.next();
16695                for (int id : userIds) {
16696                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16697                    if (stickies != null) {
16698                        ArrayList<Intent> intents = stickies.get(action);
16699                        if (intents != null) {
16700                            if (stickyIntents == null) {
16701                                stickyIntents = new ArrayList<Intent>();
16702                            }
16703                            stickyIntents.addAll(intents);
16704                        }
16705                    }
16706                }
16707            }
16708        }
16709
16710        ArrayList<Intent> allSticky = null;
16711        if (stickyIntents != null) {
16712            final ContentResolver resolver = mContext.getContentResolver();
16713            // Look for any matching sticky broadcasts...
16714            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16715                Intent intent = stickyIntents.get(i);
16716                // If intent has scheme "content", it will need to acccess
16717                // provider that needs to lock mProviderMap in ActivityThread
16718                // and also it may need to wait application response, so we
16719                // cannot lock ActivityManagerService here.
16720                if (filter.match(resolver, intent, true, TAG) >= 0) {
16721                    if (allSticky == null) {
16722                        allSticky = new ArrayList<Intent>();
16723                    }
16724                    allSticky.add(intent);
16725                }
16726            }
16727        }
16728
16729        // The first sticky in the list is returned directly back to the client.
16730        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16731        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16732        if (receiver == null) {
16733            return sticky;
16734        }
16735
16736        synchronized (this) {
16737            if (callerApp != null && (callerApp.thread == null
16738                    || callerApp.thread.asBinder() != caller.asBinder())) {
16739                // Original caller already died
16740                return null;
16741            }
16742            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16743            if (rl == null) {
16744                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16745                        userId, receiver);
16746                if (rl.app != null) {
16747                    rl.app.receivers.add(rl);
16748                } else {
16749                    try {
16750                        receiver.asBinder().linkToDeath(rl, 0);
16751                    } catch (RemoteException e) {
16752                        return sticky;
16753                    }
16754                    rl.linkedToDeath = true;
16755                }
16756                mRegisteredReceivers.put(receiver.asBinder(), rl);
16757            } else if (rl.uid != callingUid) {
16758                throw new IllegalArgumentException(
16759                        "Receiver requested to register for uid " + callingUid
16760                        + " was previously registered for uid " + rl.uid);
16761            } else if (rl.pid != callingPid) {
16762                throw new IllegalArgumentException(
16763                        "Receiver requested to register for pid " + callingPid
16764                        + " was previously registered for pid " + rl.pid);
16765            } else if (rl.userId != userId) {
16766                throw new IllegalArgumentException(
16767                        "Receiver requested to register for user " + userId
16768                        + " was previously registered for user " + rl.userId);
16769            }
16770            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16771                    permission, callingUid, userId);
16772            rl.add(bf);
16773            if (!bf.debugCheck()) {
16774                Slog.w(TAG, "==> For Dynamic broadcast");
16775            }
16776            mReceiverResolver.addFilter(bf);
16777
16778            // Enqueue broadcasts for all existing stickies that match
16779            // this filter.
16780            if (allSticky != null) {
16781                ArrayList receivers = new ArrayList();
16782                receivers.add(bf);
16783
16784                final int stickyCount = allSticky.size();
16785                for (int i = 0; i < stickyCount; i++) {
16786                    Intent intent = allSticky.get(i);
16787                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16788                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16789                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16790                            null, 0, null, null, false, true, true, -1);
16791                    queue.enqueueParallelBroadcastLocked(r);
16792                    queue.scheduleBroadcastsLocked();
16793                }
16794            }
16795
16796            return sticky;
16797        }
16798    }
16799
16800    public void unregisterReceiver(IIntentReceiver receiver) {
16801        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16802
16803        final long origId = Binder.clearCallingIdentity();
16804        try {
16805            boolean doTrim = false;
16806
16807            synchronized(this) {
16808                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16809                if (rl != null) {
16810                    final BroadcastRecord r = rl.curBroadcast;
16811                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16812                        final boolean doNext = r.queue.finishReceiverLocked(
16813                                r, r.resultCode, r.resultData, r.resultExtras,
16814                                r.resultAbort, false);
16815                        if (doNext) {
16816                            doTrim = true;
16817                            r.queue.processNextBroadcast(false);
16818                        }
16819                    }
16820
16821                    if (rl.app != null) {
16822                        rl.app.receivers.remove(rl);
16823                    }
16824                    removeReceiverLocked(rl);
16825                    if (rl.linkedToDeath) {
16826                        rl.linkedToDeath = false;
16827                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16828                    }
16829                }
16830            }
16831
16832            // If we actually concluded any broadcasts, we might now be able
16833            // to trim the recipients' apps from our working set
16834            if (doTrim) {
16835                trimApplications();
16836                return;
16837            }
16838
16839        } finally {
16840            Binder.restoreCallingIdentity(origId);
16841        }
16842    }
16843
16844    void removeReceiverLocked(ReceiverList rl) {
16845        mRegisteredReceivers.remove(rl.receiver.asBinder());
16846        for (int i = rl.size() - 1; i >= 0; i--) {
16847            mReceiverResolver.removeFilter(rl.get(i));
16848        }
16849    }
16850
16851    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16852        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16853            ProcessRecord r = mLruProcesses.get(i);
16854            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16855                try {
16856                    r.thread.dispatchPackageBroadcast(cmd, packages);
16857                } catch (RemoteException ex) {
16858                }
16859            }
16860        }
16861    }
16862
16863    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16864            int callingUid, int[] users) {
16865        List<ResolveInfo> receivers = null;
16866        try {
16867            HashSet<ComponentName> singleUserReceivers = null;
16868            boolean scannedFirstReceivers = false;
16869            for (int user : users) {
16870                // Skip users that have Shell restrictions
16871                if (callingUid == Process.SHELL_UID
16872                        && mUserController.hasUserRestriction(
16873                        UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16874                    continue;
16875                }
16876                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16877                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16878                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
16879                    // If this is not the system user, we need to check for
16880                    // any receivers that should be filtered out.
16881                    for (int i=0; i<newReceivers.size(); i++) {
16882                        ResolveInfo ri = newReceivers.get(i);
16883                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
16884                            newReceivers.remove(i);
16885                            i--;
16886                        }
16887                    }
16888                }
16889                if (newReceivers != null && newReceivers.size() == 0) {
16890                    newReceivers = null;
16891                }
16892                if (receivers == null) {
16893                    receivers = newReceivers;
16894                } else if (newReceivers != null) {
16895                    // We need to concatenate the additional receivers
16896                    // found with what we have do far.  This would be easy,
16897                    // but we also need to de-dup any receivers that are
16898                    // singleUser.
16899                    if (!scannedFirstReceivers) {
16900                        // Collect any single user receivers we had already retrieved.
16901                        scannedFirstReceivers = true;
16902                        for (int i=0; i<receivers.size(); i++) {
16903                            ResolveInfo ri = receivers.get(i);
16904                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16905                                ComponentName cn = new ComponentName(
16906                                        ri.activityInfo.packageName, ri.activityInfo.name);
16907                                if (singleUserReceivers == null) {
16908                                    singleUserReceivers = new HashSet<ComponentName>();
16909                                }
16910                                singleUserReceivers.add(cn);
16911                            }
16912                        }
16913                    }
16914                    // Add the new results to the existing results, tracking
16915                    // and de-dupping single user receivers.
16916                    for (int i=0; i<newReceivers.size(); i++) {
16917                        ResolveInfo ri = newReceivers.get(i);
16918                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16919                            ComponentName cn = new ComponentName(
16920                                    ri.activityInfo.packageName, ri.activityInfo.name);
16921                            if (singleUserReceivers == null) {
16922                                singleUserReceivers = new HashSet<ComponentName>();
16923                            }
16924                            if (!singleUserReceivers.contains(cn)) {
16925                                singleUserReceivers.add(cn);
16926                                receivers.add(ri);
16927                            }
16928                        } else {
16929                            receivers.add(ri);
16930                        }
16931                    }
16932                }
16933            }
16934        } catch (RemoteException ex) {
16935            // pm is in same process, this will never happen.
16936        }
16937        return receivers;
16938    }
16939
16940    final int broadcastIntentLocked(ProcessRecord callerApp,
16941            String callerPackage, Intent intent, String resolvedType,
16942            IIntentReceiver resultTo, int resultCode, String resultData,
16943            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
16944            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16945        intent = new Intent(intent);
16946
16947        // By default broadcasts do not go to stopped apps.
16948        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16949
16950        // If we have not finished booting, don't allow this to launch new processes.
16951        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16952            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16953        }
16954
16955        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16956                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16957                + " ordered=" + ordered + " userid=" + userId);
16958        if ((resultTo != null) && !ordered) {
16959            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16960        }
16961
16962        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16963                ALLOW_NON_FULL, "broadcast", callerPackage);
16964
16965        // Make sure that the user who is receiving this broadcast is running.
16966        // If not, we will just skip it. Make an exception for shutdown broadcasts
16967        // and upgrade steps.
16968
16969        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
16970            if ((callingUid != Process.SYSTEM_UID
16971                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16972                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16973                Slog.w(TAG, "Skipping broadcast of " + intent
16974                        + ": user " + userId + " is stopped");
16975                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16976            }
16977        }
16978
16979        BroadcastOptions brOptions = null;
16980        if (bOptions != null) {
16981            brOptions = new BroadcastOptions(bOptions);
16982            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16983                // See if the caller is allowed to do this.  Note we are checking against
16984                // the actual real caller (not whoever provided the operation as say a
16985                // PendingIntent), because that who is actually supplied the arguments.
16986                if (checkComponentPermission(
16987                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16988                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16989                        != PackageManager.PERMISSION_GRANTED) {
16990                    String msg = "Permission Denial: " + intent.getAction()
16991                            + " broadcast from " + callerPackage + " (pid=" + callingPid
16992                            + ", uid=" + callingUid + ")"
16993                            + " requires "
16994                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16995                    Slog.w(TAG, msg);
16996                    throw new SecurityException(msg);
16997                }
16998            }
16999        }
17000
17001        final String action = intent.getAction();
17002        final boolean isProtectedBroadcast;
17003        try {
17004            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17005        } catch (RemoteException e) {
17006            Slog.w(TAG, "Remote exception", e);
17007            return ActivityManager.BROADCAST_SUCCESS;
17008        }
17009
17010        /*
17011         * Prevent non-system code (defined here to be non-persistent
17012         * processes) from sending protected broadcasts.
17013         */
17014        int callingAppId = UserHandle.getAppId(callingUid);
17015        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
17016            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
17017            || callingAppId == Process.NFC_UID || callingUid == 0) {
17018            // Always okay.
17019
17020            // Yell if the system is trying to send a non-protected broadcast.
17021            // The vast majority of broadcasts sent from system callers should
17022            // be protected to avoid security holes, so exceptions here should
17023            // be incredibly rare.
17024            if (!isProtectedBroadcast
17025                    && !Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
17026                // TODO: eventually switch over to hard throw
17027                Log.wtf(TAG, "Sending non-protected broadcast " + action
17028                        + " from system", new Throwable());
17029            }
17030
17031        } else if (callerApp == null || !callerApp.persistent) {
17032            if (isProtectedBroadcast) {
17033                String msg = "Permission Denial: not allowed to send broadcast "
17034                        + action + " from pid="
17035                        + callingPid + ", uid=" + callingUid;
17036                Slog.w(TAG, msg);
17037                throw new SecurityException(msg);
17038            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)) {
17039                // Special case for compatibility: we don't want apps to send this,
17040                // but historically it has not been protected and apps may be using it
17041                // to poke their own app widget.  So, instead of making it protected,
17042                // just limit it to the caller.
17043                if (callerApp == null) {
17044                    String msg = "Permission Denial: not allowed to send broadcast "
17045                            + action + " from unknown caller.";
17046                    Slog.w(TAG, msg);
17047                    throw new SecurityException(msg);
17048                } else if (intent.getComponent() != null) {
17049                    // They are good enough to send to an explicit component...  verify
17050                    // it is being sent to the calling app.
17051                    if (!intent.getComponent().getPackageName().equals(
17052                            callerApp.info.packageName)) {
17053                        String msg = "Permission Denial: not allowed to send broadcast "
17054                                + action + " to "
17055                                + intent.getComponent().getPackageName() + " from "
17056                                + callerApp.info.packageName;
17057                        Slog.w(TAG, msg);
17058                        throw new SecurityException(msg);
17059                    }
17060                } else {
17061                    // Limit broadcast to their own package.
17062                    intent.setPackage(callerApp.info.packageName);
17063                }
17064            }
17065        }
17066
17067        if (action != null) {
17068            switch (action) {
17069                case Intent.ACTION_UID_REMOVED:
17070                case Intent.ACTION_PACKAGE_REMOVED:
17071                case Intent.ACTION_PACKAGE_CHANGED:
17072                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17073                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17074                    // Handle special intents: if this broadcast is from the package
17075                    // manager about a package being removed, we need to remove all of
17076                    // its activities from the history stack.
17077                    if (checkComponentPermission(
17078                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17079                            callingPid, callingUid, -1, true)
17080                            != PackageManager.PERMISSION_GRANTED) {
17081                        String msg = "Permission Denial: " + intent.getAction()
17082                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17083                                + ", uid=" + callingUid + ")"
17084                                + " requires "
17085                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17086                        Slog.w(TAG, msg);
17087                        throw new SecurityException(msg);
17088                    }
17089                    switch (action) {
17090                        case Intent.ACTION_UID_REMOVED:
17091                            final Bundle intentExtras = intent.getExtras();
17092                            final int uid = intentExtras != null
17093                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17094                            if (uid >= 0) {
17095                                mBatteryStatsService.removeUid(uid);
17096                                mAppOpsService.uidRemoved(uid);
17097                            }
17098                            break;
17099                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17100                            // If resources are unavailable just force stop all those packages
17101                            // and flush the attribute cache as well.
17102                            String list[] =
17103                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17104                            if (list != null && list.length > 0) {
17105                                for (int i = 0; i < list.length; i++) {
17106                                    forceStopPackageLocked(list[i], -1, false, true, true,
17107                                            false, false, userId, "storage unmount");
17108                                }
17109                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17110                                sendPackageBroadcastLocked(
17111                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17112                                        userId);
17113                            }
17114                            break;
17115                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17116                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17117                            break;
17118                        case Intent.ACTION_PACKAGE_REMOVED:
17119                        case Intent.ACTION_PACKAGE_CHANGED:
17120                            Uri data = intent.getData();
17121                            String ssp;
17122                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17123                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17124                                boolean fullUninstall = removed &&
17125                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17126                                final boolean killProcess =
17127                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17128                                if (killProcess) {
17129                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17130                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17131                                            false, true, true, false, fullUninstall, userId,
17132                                            removed ? "pkg removed" : "pkg changed");
17133                                }
17134                                if (removed) {
17135                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
17136                                            new String[] {ssp}, userId);
17137                                    if (fullUninstall) {
17138                                        mAppOpsService.packageRemoved(
17139                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17140
17141                                        // Remove all permissions granted from/to this package
17142                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17143
17144                                        removeTasksByPackageNameLocked(ssp, userId);
17145                                        mBatteryStatsService.notePackageUninstalled(ssp);
17146                                    }
17147                                } else {
17148                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17149                                            intent.getStringArrayExtra(
17150                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17151                                }
17152                            }
17153                            break;
17154                    }
17155                    break;
17156                case Intent.ACTION_PACKAGE_ADDED:
17157                    // Special case for adding a package: by default turn on compatibility mode.
17158                    Uri data = intent.getData();
17159                    String ssp;
17160                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17161                        final boolean replacing =
17162                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17163                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17164
17165                        try {
17166                            ApplicationInfo ai = AppGlobals.getPackageManager().
17167                                    getApplicationInfo(ssp, 0, 0);
17168                            mBatteryStatsService.notePackageInstalled(ssp,
17169                                    ai != null ? ai.versionCode : 0);
17170                        } catch (RemoteException e) {
17171                        }
17172                    }
17173                    break;
17174                case Intent.ACTION_TIMEZONE_CHANGED:
17175                    // If this is the time zone changed action, queue up a message that will reset
17176                    // the timezone of all currently running processes. This message will get
17177                    // queued up before the broadcast happens.
17178                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17179                    break;
17180                case Intent.ACTION_TIME_CHANGED:
17181                    // If the user set the time, let all running processes know.
17182                    final int is24Hour =
17183                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17184                                    : 0;
17185                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17186                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17187                    synchronized (stats) {
17188                        stats.noteCurrentTimeChangedLocked();
17189                    }
17190                    break;
17191                case Intent.ACTION_CLEAR_DNS_CACHE:
17192                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17193                    break;
17194                case Proxy.PROXY_CHANGE_ACTION:
17195                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17196                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17197                    break;
17198            }
17199        }
17200
17201        // Add to the sticky list if requested.
17202        if (sticky) {
17203            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17204                    callingPid, callingUid)
17205                    != PackageManager.PERMISSION_GRANTED) {
17206                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17207                        + callingPid + ", uid=" + callingUid
17208                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17209                Slog.w(TAG, msg);
17210                throw new SecurityException(msg);
17211            }
17212            if (requiredPermissions != null && requiredPermissions.length > 0) {
17213                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17214                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17215                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17216            }
17217            if (intent.getComponent() != null) {
17218                throw new SecurityException(
17219                        "Sticky broadcasts can't target a specific component");
17220            }
17221            // We use userId directly here, since the "all" target is maintained
17222            // as a separate set of sticky broadcasts.
17223            if (userId != UserHandle.USER_ALL) {
17224                // But first, if this is not a broadcast to all users, then
17225                // make sure it doesn't conflict with an existing broadcast to
17226                // all users.
17227                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17228                        UserHandle.USER_ALL);
17229                if (stickies != null) {
17230                    ArrayList<Intent> list = stickies.get(intent.getAction());
17231                    if (list != null) {
17232                        int N = list.size();
17233                        int i;
17234                        for (i=0; i<N; i++) {
17235                            if (intent.filterEquals(list.get(i))) {
17236                                throw new IllegalArgumentException(
17237                                        "Sticky broadcast " + intent + " for user "
17238                                        + userId + " conflicts with existing global broadcast");
17239                            }
17240                        }
17241                    }
17242                }
17243            }
17244            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17245            if (stickies == null) {
17246                stickies = new ArrayMap<>();
17247                mStickyBroadcasts.put(userId, stickies);
17248            }
17249            ArrayList<Intent> list = stickies.get(intent.getAction());
17250            if (list == null) {
17251                list = new ArrayList<>();
17252                stickies.put(intent.getAction(), list);
17253            }
17254            final int stickiesCount = list.size();
17255            int i;
17256            for (i = 0; i < stickiesCount; i++) {
17257                if (intent.filterEquals(list.get(i))) {
17258                    // This sticky already exists, replace it.
17259                    list.set(i, new Intent(intent));
17260                    break;
17261                }
17262            }
17263            if (i >= stickiesCount) {
17264                list.add(new Intent(intent));
17265            }
17266        }
17267
17268        int[] users;
17269        if (userId == UserHandle.USER_ALL) {
17270            // Caller wants broadcast to go to all started users.
17271            users = mUserController.getStartedUserArrayLocked();
17272        } else {
17273            // Caller wants broadcast to go to one specific user.
17274            users = new int[] {userId};
17275        }
17276
17277        // Figure out who all will receive this broadcast.
17278        List receivers = null;
17279        List<BroadcastFilter> registeredReceivers = null;
17280        // Need to resolve the intent to interested receivers...
17281        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17282                 == 0) {
17283            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17284        }
17285        if (intent.getComponent() == null) {
17286            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17287                // Query one target user at a time, excluding shell-restricted users
17288                for (int i = 0; i < users.length; i++) {
17289                    if (mUserController.hasUserRestriction(
17290                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17291                        continue;
17292                    }
17293                    List<BroadcastFilter> registeredReceiversForUser =
17294                            mReceiverResolver.queryIntent(intent,
17295                                    resolvedType, false, users[i]);
17296                    if (registeredReceivers == null) {
17297                        registeredReceivers = registeredReceiversForUser;
17298                    } else if (registeredReceiversForUser != null) {
17299                        registeredReceivers.addAll(registeredReceiversForUser);
17300                    }
17301                }
17302            } else {
17303                registeredReceivers = mReceiverResolver.queryIntent(intent,
17304                        resolvedType, false, userId);
17305            }
17306        }
17307
17308        final boolean replacePending =
17309                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17310
17311        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17312                + " replacePending=" + replacePending);
17313
17314        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17315        if (!ordered && NR > 0) {
17316            // If we are not serializing this broadcast, then send the
17317            // registered receivers separately so they don't wait for the
17318            // components to be launched.
17319            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17320            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17321                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17322                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17323                    resultExtras, ordered, sticky, false, userId);
17324            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17325            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17326            if (!replaced) {
17327                queue.enqueueParallelBroadcastLocked(r);
17328                queue.scheduleBroadcastsLocked();
17329            }
17330            registeredReceivers = null;
17331            NR = 0;
17332        }
17333
17334        // Merge into one list.
17335        int ir = 0;
17336        if (receivers != null) {
17337            // A special case for PACKAGE_ADDED: do not allow the package
17338            // being added to see this broadcast.  This prevents them from
17339            // using this as a back door to get run as soon as they are
17340            // installed.  Maybe in the future we want to have a special install
17341            // broadcast or such for apps, but we'd like to deliberately make
17342            // this decision.
17343            String skipPackages[] = null;
17344            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17345                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17346                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17347                Uri data = intent.getData();
17348                if (data != null) {
17349                    String pkgName = data.getSchemeSpecificPart();
17350                    if (pkgName != null) {
17351                        skipPackages = new String[] { pkgName };
17352                    }
17353                }
17354            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17355                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17356            }
17357            if (skipPackages != null && (skipPackages.length > 0)) {
17358                for (String skipPackage : skipPackages) {
17359                    if (skipPackage != null) {
17360                        int NT = receivers.size();
17361                        for (int it=0; it<NT; it++) {
17362                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17363                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17364                                receivers.remove(it);
17365                                it--;
17366                                NT--;
17367                            }
17368                        }
17369                    }
17370                }
17371            }
17372
17373            int NT = receivers != null ? receivers.size() : 0;
17374            int it = 0;
17375            ResolveInfo curt = null;
17376            BroadcastFilter curr = null;
17377            while (it < NT && ir < NR) {
17378                if (curt == null) {
17379                    curt = (ResolveInfo)receivers.get(it);
17380                }
17381                if (curr == null) {
17382                    curr = registeredReceivers.get(ir);
17383                }
17384                if (curr.getPriority() >= curt.priority) {
17385                    // Insert this broadcast record into the final list.
17386                    receivers.add(it, curr);
17387                    ir++;
17388                    curr = null;
17389                    it++;
17390                    NT++;
17391                } else {
17392                    // Skip to the next ResolveInfo in the final list.
17393                    it++;
17394                    curt = null;
17395                }
17396            }
17397        }
17398        while (ir < NR) {
17399            if (receivers == null) {
17400                receivers = new ArrayList();
17401            }
17402            receivers.add(registeredReceivers.get(ir));
17403            ir++;
17404        }
17405
17406        if ((receivers != null && receivers.size() > 0)
17407                || resultTo != null) {
17408            BroadcastQueue queue = broadcastQueueForIntent(intent);
17409            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17410                    callerPackage, callingPid, callingUid, resolvedType,
17411                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17412                    resultData, resultExtras, ordered, sticky, false, userId);
17413
17414            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17415                    + ": prev had " + queue.mOrderedBroadcasts.size());
17416            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17417                    "Enqueueing broadcast " + r.intent.getAction());
17418
17419            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17420            if (!replaced) {
17421                queue.enqueueOrderedBroadcastLocked(r);
17422                queue.scheduleBroadcastsLocked();
17423            }
17424        }
17425
17426        return ActivityManager.BROADCAST_SUCCESS;
17427    }
17428
17429    final Intent verifyBroadcastLocked(Intent intent) {
17430        // Refuse possible leaked file descriptors
17431        if (intent != null && intent.hasFileDescriptors() == true) {
17432            throw new IllegalArgumentException("File descriptors passed in Intent");
17433        }
17434
17435        int flags = intent.getFlags();
17436
17437        if (!mProcessesReady) {
17438            // if the caller really truly claims to know what they're doing, go
17439            // ahead and allow the broadcast without launching any receivers
17440            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17441                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17442            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17443                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17444                        + " before boot completion");
17445                throw new IllegalStateException("Cannot broadcast before boot completed");
17446            }
17447        }
17448
17449        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17450            throw new IllegalArgumentException(
17451                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17452        }
17453
17454        return intent;
17455    }
17456
17457    public final int broadcastIntent(IApplicationThread caller,
17458            Intent intent, String resolvedType, IIntentReceiver resultTo,
17459            int resultCode, String resultData, Bundle resultExtras,
17460            String[] requiredPermissions, int appOp, Bundle bOptions,
17461            boolean serialized, boolean sticky, int userId) {
17462        enforceNotIsolatedCaller("broadcastIntent");
17463        synchronized(this) {
17464            intent = verifyBroadcastLocked(intent);
17465
17466            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17467            final int callingPid = Binder.getCallingPid();
17468            final int callingUid = Binder.getCallingUid();
17469            final long origId = Binder.clearCallingIdentity();
17470            int res = broadcastIntentLocked(callerApp,
17471                    callerApp != null ? callerApp.info.packageName : null,
17472                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17473                    requiredPermissions, appOp, null, serialized, sticky,
17474                    callingPid, callingUid, userId);
17475            Binder.restoreCallingIdentity(origId);
17476            return res;
17477        }
17478    }
17479
17480
17481    int broadcastIntentInPackage(String packageName, int uid,
17482            Intent intent, String resolvedType, IIntentReceiver resultTo,
17483            int resultCode, String resultData, Bundle resultExtras,
17484            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17485            int userId) {
17486        synchronized(this) {
17487            intent = verifyBroadcastLocked(intent);
17488
17489            final long origId = Binder.clearCallingIdentity();
17490            String[] requiredPermissions = requiredPermission == null ? null
17491                    : new String[] {requiredPermission};
17492            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17493                    resultTo, resultCode, resultData, resultExtras,
17494                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17495                    sticky, -1, uid, userId);
17496            Binder.restoreCallingIdentity(origId);
17497            return res;
17498        }
17499    }
17500
17501    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17502        // Refuse possible leaked file descriptors
17503        if (intent != null && intent.hasFileDescriptors() == true) {
17504            throw new IllegalArgumentException("File descriptors passed in Intent");
17505        }
17506
17507        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17508                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17509
17510        synchronized(this) {
17511            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17512                    != PackageManager.PERMISSION_GRANTED) {
17513                String msg = "Permission Denial: unbroadcastIntent() from pid="
17514                        + Binder.getCallingPid()
17515                        + ", uid=" + Binder.getCallingUid()
17516                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17517                Slog.w(TAG, msg);
17518                throw new SecurityException(msg);
17519            }
17520            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17521            if (stickies != null) {
17522                ArrayList<Intent> list = stickies.get(intent.getAction());
17523                if (list != null) {
17524                    int N = list.size();
17525                    int i;
17526                    for (i=0; i<N; i++) {
17527                        if (intent.filterEquals(list.get(i))) {
17528                            list.remove(i);
17529                            break;
17530                        }
17531                    }
17532                    if (list.size() <= 0) {
17533                        stickies.remove(intent.getAction());
17534                    }
17535                }
17536                if (stickies.size() <= 0) {
17537                    mStickyBroadcasts.remove(userId);
17538                }
17539            }
17540        }
17541    }
17542
17543    void backgroundServicesFinishedLocked(int userId) {
17544        for (BroadcastQueue queue : mBroadcastQueues) {
17545            queue.backgroundServicesFinishedLocked(userId);
17546        }
17547    }
17548
17549    public void finishReceiver(IBinder who, int resultCode, String resultData,
17550            Bundle resultExtras, boolean resultAbort, int flags) {
17551        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17552
17553        // Refuse possible leaked file descriptors
17554        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17555            throw new IllegalArgumentException("File descriptors passed in Bundle");
17556        }
17557
17558        final long origId = Binder.clearCallingIdentity();
17559        try {
17560            boolean doNext = false;
17561            BroadcastRecord r;
17562
17563            synchronized(this) {
17564                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17565                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17566                r = queue.getMatchingOrderedReceiver(who);
17567                if (r != null) {
17568                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17569                        resultData, resultExtras, resultAbort, true);
17570                }
17571            }
17572
17573            if (doNext) {
17574                r.queue.processNextBroadcast(false);
17575            }
17576            trimApplications();
17577        } finally {
17578            Binder.restoreCallingIdentity(origId);
17579        }
17580    }
17581
17582    // =========================================================
17583    // INSTRUMENTATION
17584    // =========================================================
17585
17586    public boolean startInstrumentation(ComponentName className,
17587            String profileFile, int flags, Bundle arguments,
17588            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17589            int userId, String abiOverride) {
17590        enforceNotIsolatedCaller("startInstrumentation");
17591        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17592                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17593        // Refuse possible leaked file descriptors
17594        if (arguments != null && arguments.hasFileDescriptors()) {
17595            throw new IllegalArgumentException("File descriptors passed in Bundle");
17596        }
17597
17598        synchronized(this) {
17599            InstrumentationInfo ii = null;
17600            ApplicationInfo ai = null;
17601            try {
17602                ii = mContext.getPackageManager().getInstrumentationInfo(
17603                    className, STOCK_PM_FLAGS);
17604                ai = AppGlobals.getPackageManager().getApplicationInfo(
17605                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17606            } catch (PackageManager.NameNotFoundException e) {
17607            } catch (RemoteException e) {
17608            }
17609            if (ii == null) {
17610                reportStartInstrumentationFailure(watcher, className,
17611                        "Unable to find instrumentation info for: " + className);
17612                return false;
17613            }
17614            if (ai == null) {
17615                reportStartInstrumentationFailure(watcher, className,
17616                        "Unable to find instrumentation target package: " + ii.targetPackage);
17617                return false;
17618            }
17619
17620            int match = mContext.getPackageManager().checkSignatures(
17621                    ii.targetPackage, ii.packageName);
17622            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17623                String msg = "Permission Denial: starting instrumentation "
17624                        + className + " from pid="
17625                        + Binder.getCallingPid()
17626                        + ", uid=" + Binder.getCallingPid()
17627                        + " not allowed because package " + ii.packageName
17628                        + " does not have a signature matching the target "
17629                        + ii.targetPackage;
17630                reportStartInstrumentationFailure(watcher, className, msg);
17631                throw new SecurityException(msg);
17632            }
17633
17634            final long origId = Binder.clearCallingIdentity();
17635            // Instrumentation can kill and relaunch even persistent processes
17636            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17637                    "start instr");
17638            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17639            app.instrumentationClass = className;
17640            app.instrumentationInfo = ai;
17641            app.instrumentationProfileFile = profileFile;
17642            app.instrumentationArguments = arguments;
17643            app.instrumentationWatcher = watcher;
17644            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17645            app.instrumentationResultClass = className;
17646            Binder.restoreCallingIdentity(origId);
17647        }
17648
17649        return true;
17650    }
17651
17652    /**
17653     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17654     * error to the logs, but if somebody is watching, send the report there too.  This enables
17655     * the "am" command to report errors with more information.
17656     *
17657     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17658     * @param cn The component name of the instrumentation.
17659     * @param report The error report.
17660     */
17661    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17662            ComponentName cn, String report) {
17663        Slog.w(TAG, report);
17664        try {
17665            if (watcher != null) {
17666                Bundle results = new Bundle();
17667                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17668                results.putString("Error", report);
17669                watcher.instrumentationStatus(cn, -1, results);
17670            }
17671        } catch (RemoteException e) {
17672            Slog.w(TAG, e);
17673        }
17674    }
17675
17676    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17677        if (app.instrumentationWatcher != null) {
17678            try {
17679                // NOTE:  IInstrumentationWatcher *must* be oneway here
17680                app.instrumentationWatcher.instrumentationFinished(
17681                    app.instrumentationClass,
17682                    resultCode,
17683                    results);
17684            } catch (RemoteException e) {
17685            }
17686        }
17687
17688        // Can't call out of the system process with a lock held, so post a message.
17689        if (app.instrumentationUiAutomationConnection != null) {
17690            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17691                    app.instrumentationUiAutomationConnection).sendToTarget();
17692        }
17693
17694        app.instrumentationWatcher = null;
17695        app.instrumentationUiAutomationConnection = null;
17696        app.instrumentationClass = null;
17697        app.instrumentationInfo = null;
17698        app.instrumentationProfileFile = null;
17699        app.instrumentationArguments = null;
17700
17701        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17702                "finished inst");
17703    }
17704
17705    public void finishInstrumentation(IApplicationThread target,
17706            int resultCode, Bundle results) {
17707        int userId = UserHandle.getCallingUserId();
17708        // Refuse possible leaked file descriptors
17709        if (results != null && results.hasFileDescriptors()) {
17710            throw new IllegalArgumentException("File descriptors passed in Intent");
17711        }
17712
17713        synchronized(this) {
17714            ProcessRecord app = getRecordForAppLocked(target);
17715            if (app == null) {
17716                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17717                return;
17718            }
17719            final long origId = Binder.clearCallingIdentity();
17720            finishInstrumentationLocked(app, resultCode, results);
17721            Binder.restoreCallingIdentity(origId);
17722        }
17723    }
17724
17725    // =========================================================
17726    // CONFIGURATION
17727    // =========================================================
17728
17729    public ConfigurationInfo getDeviceConfigurationInfo() {
17730        ConfigurationInfo config = new ConfigurationInfo();
17731        synchronized (this) {
17732            config.reqTouchScreen = mConfiguration.touchscreen;
17733            config.reqKeyboardType = mConfiguration.keyboard;
17734            config.reqNavigation = mConfiguration.navigation;
17735            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17736                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17737                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17738            }
17739            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17740                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17741                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17742            }
17743            config.reqGlEsVersion = GL_ES_VERSION;
17744        }
17745        return config;
17746    }
17747
17748    ActivityStack getFocusedStack() {
17749        return mStackSupervisor.getFocusedStack();
17750    }
17751
17752    @Override
17753    public int getFocusedStackId() throws RemoteException {
17754        ActivityStack focusedStack = getFocusedStack();
17755        if (focusedStack != null) {
17756            return focusedStack.getStackId();
17757        }
17758        return -1;
17759    }
17760
17761    public Configuration getConfiguration() {
17762        Configuration ci;
17763        synchronized(this) {
17764            ci = new Configuration(mConfiguration);
17765            ci.userSetLocale = false;
17766        }
17767        return ci;
17768    }
17769
17770    @Override
17771    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17772        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
17773                "suppressResizeConfigChanges()");
17774        synchronized (this) {
17775            mSuppressResizeConfigChanges = suppress;
17776        }
17777    }
17778
17779    @Override
17780    public void removeStack(int stackId) {
17781        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
17782                "detahStack()");
17783        if (stackId == HOME_STACK_ID) {
17784            throw new IllegalArgumentException("Removing home stack is not allowed.");
17785        }
17786        synchronized (this) {
17787            long origId = Binder.clearCallingIdentity();
17788            ActivityStack stack = mStackSupervisor.getStack(stackId);
17789            if (stack != null) {
17790                ArrayList<TaskRecord> tasks = stack.getAllTasks();
17791                for (int i = tasks.size() - 1; i >= 0; i--) {
17792                    removeTaskByIdLocked(tasks.get(i).taskId, false /* killProcess */,
17793                            !REMOVE_FROM_RECENTS);
17794                }
17795            }
17796            Binder.restoreCallingIdentity(origId);
17797        }
17798    }
17799
17800    @Override
17801    public void updatePersistentConfiguration(Configuration values) {
17802        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17803                "updateConfiguration()");
17804        enforceWriteSettingsPermission("updateConfiguration()");
17805        if (values == null) {
17806            throw new NullPointerException("Configuration must not be null");
17807        }
17808
17809        int userId = UserHandle.getCallingUserId();
17810
17811        synchronized(this) {
17812            final long origId = Binder.clearCallingIdentity();
17813            updateConfigurationLocked(values, null, false, true, userId);
17814            Binder.restoreCallingIdentity(origId);
17815        }
17816    }
17817
17818    private void enforceWriteSettingsPermission(String func) {
17819        int uid = Binder.getCallingUid();
17820        if (uid == Process.ROOT_UID) {
17821            return;
17822        }
17823
17824        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17825                Settings.getPackageNameForUid(mContext, uid), false)) {
17826            return;
17827        }
17828
17829        String msg = "Permission Denial: " + func + " from pid="
17830                + Binder.getCallingPid()
17831                + ", uid=" + uid
17832                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17833        Slog.w(TAG, msg);
17834        throw new SecurityException(msg);
17835    }
17836
17837    public void updateConfiguration(Configuration values) {
17838        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17839                "updateConfiguration()");
17840
17841        synchronized(this) {
17842            if (values == null && mWindowManager != null) {
17843                // sentinel: fetch the current configuration from the window manager
17844                values = mWindowManager.computeNewConfiguration();
17845            }
17846
17847            if (mWindowManager != null) {
17848                mProcessList.applyDisplaySize(mWindowManager);
17849            }
17850
17851            final long origId = Binder.clearCallingIdentity();
17852            if (values != null) {
17853                Settings.System.clearConfiguration(values);
17854            }
17855            updateConfigurationLocked(values, null, false);
17856            Binder.restoreCallingIdentity(origId);
17857        }
17858    }
17859
17860    void updateUserConfigurationLocked() {
17861        Configuration configuration = new Configuration(mConfiguration);
17862        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
17863                mUserController.getCurrentUserIdLocked());
17864        updateConfigurationLocked(configuration, null, false);
17865    }
17866
17867    boolean updateConfigurationLocked(Configuration values,
17868            ActivityRecord starting, boolean initLocale) {
17869        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
17870        return updateConfigurationLocked(values, starting, initLocale, false,
17871                UserHandle.USER_NULL);
17872    }
17873
17874    // To cache the list of supported system locales
17875    private String[] mSupportedSystemLocales = null;
17876
17877    /**
17878     * Do either or both things: (1) change the current configuration, and (2)
17879     * make sure the given activity is running with the (now) current
17880     * configuration.  Returns true if the activity has been left running, or
17881     * false if <var>starting</var> is being destroyed to match the new
17882     * configuration.
17883     *
17884     * @param userId is only used when persistent parameter is set to true to persist configuration
17885     *               for that particular user
17886     */
17887    private boolean updateConfigurationLocked(Configuration values,
17888            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
17889        int changes = 0;
17890
17891        if (values != null) {
17892            Configuration newConfig = new Configuration(mConfiguration);
17893            changes = newConfig.updateFrom(values);
17894            if (changes != 0) {
17895                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17896                        "Updating configuration to: " + values);
17897
17898                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17899
17900                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
17901                    if (mSupportedSystemLocales == null) {
17902                        mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
17903                    }
17904                    final Locale locale = values.getLocales().getBestMatch(mSupportedSystemLocales);
17905                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
17906                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17907                            locale));
17908                }
17909
17910                mConfigurationSeq++;
17911                if (mConfigurationSeq <= 0) {
17912                    mConfigurationSeq = 1;
17913                }
17914                newConfig.seq = mConfigurationSeq;
17915                mConfiguration = newConfig;
17916                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17917                mUsageStatsService.reportConfigurationChange(newConfig,
17918                        mUserController.getCurrentUserIdLocked());
17919                //mUsageStatsService.noteStartConfig(newConfig);
17920
17921                final Configuration configCopy = new Configuration(mConfiguration);
17922
17923                // TODO: If our config changes, should we auto dismiss any currently
17924                // showing dialogs?
17925                mShowDialogs = shouldShowDialogs(newConfig);
17926
17927                AttributeCache ac = AttributeCache.instance();
17928                if (ac != null) {
17929                    ac.updateConfiguration(configCopy);
17930                }
17931
17932                // Make sure all resources in our process are updated
17933                // right now, so that anyone who is going to retrieve
17934                // resource values after we return will be sure to get
17935                // the new ones.  This is especially important during
17936                // boot, where the first config change needs to guarantee
17937                // all resources have that config before following boot
17938                // code is executed.
17939                mSystemThread.applyConfigurationToResources(configCopy);
17940
17941                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17942                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17943                    msg.obj = new Configuration(configCopy);
17944                    msg.arg1 = userId;
17945                    mHandler.sendMessage(msg);
17946                }
17947
17948                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17949                    ProcessRecord app = mLruProcesses.get(i);
17950                    try {
17951                        if (app.thread != null) {
17952                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17953                                    + app.processName + " new config " + mConfiguration);
17954                            app.thread.scheduleConfigurationChanged(configCopy);
17955                        }
17956                    } catch (Exception e) {
17957                    }
17958                }
17959                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17960                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17961                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
17962                        | Intent.FLAG_RECEIVER_FOREGROUND);
17963                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17964                        null, AppOpsManager.OP_NONE, null, false, false,
17965                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17966                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17967                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17968                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17969                    if (!mProcessesReady) {
17970                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17971                    }
17972                    broadcastIntentLocked(null, null, intent,
17973                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17974                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17975                }
17976            }
17977        }
17978
17979        boolean kept = true;
17980        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17981        // mainStack is null during startup.
17982        if (mainStack != null) {
17983            if (changes != 0 && starting == null) {
17984                // If the configuration changed, and the caller is not already
17985                // in the process of starting an activity, then find the top
17986                // activity to check if its configuration needs to change.
17987                starting = mainStack.topRunningActivityLocked();
17988            }
17989
17990            if (starting != null) {
17991                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
17992                // And we need to make sure at this point that all other activities
17993                // are made visible with the correct configuration.
17994                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
17995                        !PRESERVE_WINDOWS);
17996            }
17997        }
17998
17999        if (values != null && mWindowManager != null) {
18000            mWindowManager.setNewConfiguration(mConfiguration);
18001        }
18002
18003        return kept;
18004    }
18005
18006    /**
18007     * Decide based on the configuration whether we should shouw the ANR,
18008     * crash, etc dialogs.  The idea is that if there is no affordnace to
18009     * press the on-screen buttons, we shouldn't show the dialog.
18010     *
18011     * A thought: SystemUI might also want to get told about this, the Power
18012     * dialog / global actions also might want different behaviors.
18013     */
18014    private static final boolean shouldShowDialogs(Configuration config) {
18015        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18016                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18017                && config.navigation == Configuration.NAVIGATION_NONAV);
18018    }
18019
18020    @Override
18021    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18022        synchronized (this) {
18023            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18024            if (srec != null) {
18025                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18026            }
18027        }
18028        return false;
18029    }
18030
18031    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18032            Intent resultData) {
18033
18034        synchronized (this) {
18035            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18036            if (r != null) {
18037                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18038            }
18039            return false;
18040        }
18041    }
18042
18043    public int getLaunchedFromUid(IBinder activityToken) {
18044        ActivityRecord srec;
18045        synchronized (this) {
18046            srec = ActivityRecord.forTokenLocked(activityToken);
18047        }
18048        if (srec == null) {
18049            return -1;
18050        }
18051        return srec.launchedFromUid;
18052    }
18053
18054    public String getLaunchedFromPackage(IBinder activityToken) {
18055        ActivityRecord srec;
18056        synchronized (this) {
18057            srec = ActivityRecord.forTokenLocked(activityToken);
18058        }
18059        if (srec == null) {
18060            return null;
18061        }
18062        return srec.launchedFromPackage;
18063    }
18064
18065    // =========================================================
18066    // LIFETIME MANAGEMENT
18067    // =========================================================
18068
18069    // Returns which broadcast queue the app is the current [or imminent] receiver
18070    // on, or 'null' if the app is not an active broadcast recipient.
18071    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18072        BroadcastRecord r = app.curReceiver;
18073        if (r != null) {
18074            return r.queue;
18075        }
18076
18077        // It's not the current receiver, but it might be starting up to become one
18078        synchronized (this) {
18079            for (BroadcastQueue queue : mBroadcastQueues) {
18080                r = queue.mPendingBroadcast;
18081                if (r != null && r.curApp == app) {
18082                    // found it; report which queue it's in
18083                    return queue;
18084                }
18085            }
18086        }
18087
18088        return null;
18089    }
18090
18091    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18092            ComponentName targetComponent, String targetProcess) {
18093        if (!mTrackingAssociations) {
18094            return null;
18095        }
18096        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18097                = mAssociations.get(targetUid);
18098        if (components == null) {
18099            components = new ArrayMap<>();
18100            mAssociations.put(targetUid, components);
18101        }
18102        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18103        if (sourceUids == null) {
18104            sourceUids = new SparseArray<>();
18105            components.put(targetComponent, sourceUids);
18106        }
18107        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18108        if (sourceProcesses == null) {
18109            sourceProcesses = new ArrayMap<>();
18110            sourceUids.put(sourceUid, sourceProcesses);
18111        }
18112        Association ass = sourceProcesses.get(sourceProcess);
18113        if (ass == null) {
18114            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18115                    targetProcess);
18116            sourceProcesses.put(sourceProcess, ass);
18117        }
18118        ass.mCount++;
18119        ass.mNesting++;
18120        if (ass.mNesting == 1) {
18121            ass.mStartTime = SystemClock.uptimeMillis();
18122        }
18123        return ass;
18124    }
18125
18126    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18127            ComponentName targetComponent) {
18128        if (!mTrackingAssociations) {
18129            return;
18130        }
18131        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18132                = mAssociations.get(targetUid);
18133        if (components == null) {
18134            return;
18135        }
18136        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18137        if (sourceUids == null) {
18138            return;
18139        }
18140        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18141        if (sourceProcesses == null) {
18142            return;
18143        }
18144        Association ass = sourceProcesses.get(sourceProcess);
18145        if (ass == null || ass.mNesting <= 0) {
18146            return;
18147        }
18148        ass.mNesting--;
18149        if (ass.mNesting == 0) {
18150            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
18151        }
18152    }
18153
18154    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18155            boolean doingAll, long now) {
18156        if (mAdjSeq == app.adjSeq) {
18157            // This adjustment has already been computed.
18158            return app.curRawAdj;
18159        }
18160
18161        if (app.thread == null) {
18162            app.adjSeq = mAdjSeq;
18163            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18164            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18165            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18166        }
18167
18168        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18169        app.adjSource = null;
18170        app.adjTarget = null;
18171        app.empty = false;
18172        app.cached = false;
18173
18174        final int activitiesSize = app.activities.size();
18175
18176        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18177            // The max adjustment doesn't allow this app to be anything
18178            // below foreground, so it is not worth doing work for it.
18179            app.adjType = "fixed";
18180            app.adjSeq = mAdjSeq;
18181            app.curRawAdj = app.maxAdj;
18182            app.foregroundActivities = false;
18183            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
18184            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18185            // System processes can do UI, and when they do we want to have
18186            // them trim their memory after the user leaves the UI.  To
18187            // facilitate this, here we need to determine whether or not it
18188            // is currently showing UI.
18189            app.systemNoUi = true;
18190            if (app == TOP_APP) {
18191                app.systemNoUi = false;
18192            } else if (activitiesSize > 0) {
18193                for (int j = 0; j < activitiesSize; j++) {
18194                    final ActivityRecord r = app.activities.get(j);
18195                    if (r.visible) {
18196                        app.systemNoUi = false;
18197                    }
18198                }
18199            }
18200            if (!app.systemNoUi) {
18201                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18202            }
18203            return (app.curAdj=app.maxAdj);
18204        }
18205
18206        app.systemNoUi = false;
18207
18208        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18209
18210        // Determine the importance of the process, starting with most
18211        // important to least, and assign an appropriate OOM adjustment.
18212        int adj;
18213        int schedGroup;
18214        int procState;
18215        boolean foregroundActivities = false;
18216        BroadcastQueue queue;
18217        if (app == TOP_APP) {
18218            // The last app on the list is the foreground app.
18219            adj = ProcessList.FOREGROUND_APP_ADJ;
18220            schedGroup = Process.THREAD_GROUP_DEFAULT;
18221            app.adjType = "top-activity";
18222            foregroundActivities = true;
18223            procState = PROCESS_STATE_CUR_TOP;
18224        } else if (app.instrumentationClass != null) {
18225            // Don't want to kill running instrumentation.
18226            adj = ProcessList.FOREGROUND_APP_ADJ;
18227            schedGroup = Process.THREAD_GROUP_DEFAULT;
18228            app.adjType = "instrumentation";
18229            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18230        } else if ((queue = isReceivingBroadcast(app)) != null) {
18231            // An app that is currently receiving a broadcast also
18232            // counts as being in the foreground for OOM killer purposes.
18233            // It's placed in a sched group based on the nature of the
18234            // broadcast as reflected by which queue it's active in.
18235            adj = ProcessList.FOREGROUND_APP_ADJ;
18236            schedGroup = (queue == mFgBroadcastQueue)
18237                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18238            app.adjType = "broadcast";
18239            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18240        } else if (app.executingServices.size() > 0) {
18241            // An app that is currently executing a service callback also
18242            // counts as being in the foreground.
18243            adj = ProcessList.FOREGROUND_APP_ADJ;
18244            schedGroup = app.execServicesFg ?
18245                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18246            app.adjType = "exec-service";
18247            procState = ActivityManager.PROCESS_STATE_SERVICE;
18248            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18249        } else {
18250            // As far as we know the process is empty.  We may change our mind later.
18251            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18252            // At this point we don't actually know the adjustment.  Use the cached adj
18253            // value that the caller wants us to.
18254            adj = cachedAdj;
18255            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18256            app.cached = true;
18257            app.empty = true;
18258            app.adjType = "cch-empty";
18259        }
18260
18261        // Examine all activities if not already foreground.
18262        if (!foregroundActivities && activitiesSize > 0) {
18263            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18264            for (int j = 0; j < activitiesSize; j++) {
18265                final ActivityRecord r = app.activities.get(j);
18266                if (r.app != app) {
18267                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
18268                            + app + "?!? Using " + r.app + " instead.");
18269                    continue;
18270                }
18271                if (r.visible) {
18272                    // App has a visible activity; only upgrade adjustment.
18273                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18274                        adj = ProcessList.VISIBLE_APP_ADJ;
18275                        app.adjType = "visible";
18276                    }
18277                    if (procState > PROCESS_STATE_CUR_TOP) {
18278                        procState = PROCESS_STATE_CUR_TOP;
18279                    }
18280                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18281                    app.cached = false;
18282                    app.empty = false;
18283                    foregroundActivities = true;
18284                    if (r.task != null && minLayer > 0) {
18285                        final int layer = r.task.mLayerRank;
18286                        if (layer >= 0 && minLayer > layer) {
18287                            minLayer = layer;
18288                        }
18289                    }
18290                    break;
18291                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18292                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18293                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18294                        app.adjType = "pausing";
18295                    }
18296                    if (procState > PROCESS_STATE_CUR_TOP) {
18297                        procState = PROCESS_STATE_CUR_TOP;
18298                    }
18299                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18300                    app.cached = false;
18301                    app.empty = false;
18302                    foregroundActivities = true;
18303                } else if (r.state == ActivityState.STOPPING) {
18304                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18305                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18306                        app.adjType = "stopping";
18307                    }
18308                    // For the process state, we will at this point consider the
18309                    // process to be cached.  It will be cached either as an activity
18310                    // or empty depending on whether the activity is finishing.  We do
18311                    // this so that we can treat the process as cached for purposes of
18312                    // memory trimming (determing current memory level, trim command to
18313                    // send to process) since there can be an arbitrary number of stopping
18314                    // processes and they should soon all go into the cached state.
18315                    if (!r.finishing) {
18316                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18317                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18318                        }
18319                    }
18320                    app.cached = false;
18321                    app.empty = false;
18322                    foregroundActivities = true;
18323                } else {
18324                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18325                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18326                        app.adjType = "cch-act";
18327                    }
18328                }
18329            }
18330            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18331                adj += minLayer;
18332            }
18333        }
18334
18335        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18336                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18337            if (app.foregroundServices) {
18338                // The user is aware of this app, so make it visible.
18339                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18340                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18341                app.cached = false;
18342                app.adjType = "fg-service";
18343                schedGroup = Process.THREAD_GROUP_DEFAULT;
18344            } else if (app.forcingToForeground != null) {
18345                // The user is aware of this app, so make it visible.
18346                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18347                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18348                app.cached = false;
18349                app.adjType = "force-fg";
18350                app.adjSource = app.forcingToForeground;
18351                schedGroup = Process.THREAD_GROUP_DEFAULT;
18352            }
18353        }
18354
18355        if (app == mHeavyWeightProcess) {
18356            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18357                // We don't want to kill the current heavy-weight process.
18358                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18359                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18360                app.cached = false;
18361                app.adjType = "heavy";
18362            }
18363            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18364                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18365            }
18366        }
18367
18368        if (app == mHomeProcess) {
18369            if (adj > ProcessList.HOME_APP_ADJ) {
18370                // This process is hosting what we currently consider to be the
18371                // home app, so we don't want to let it go into the background.
18372                adj = ProcessList.HOME_APP_ADJ;
18373                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18374                app.cached = false;
18375                app.adjType = "home";
18376            }
18377            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18378                procState = ActivityManager.PROCESS_STATE_HOME;
18379            }
18380        }
18381
18382        if (app == mPreviousProcess && app.activities.size() > 0) {
18383            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18384                // This was the previous process that showed UI to the user.
18385                // We want to try to keep it around more aggressively, to give
18386                // a good experience around switching between two apps.
18387                adj = ProcessList.PREVIOUS_APP_ADJ;
18388                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18389                app.cached = false;
18390                app.adjType = "previous";
18391            }
18392            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18393                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18394            }
18395        }
18396
18397        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18398                + " reason=" + app.adjType);
18399
18400        // By default, we use the computed adjustment.  It may be changed if
18401        // there are applications dependent on our services or providers, but
18402        // this gives us a baseline and makes sure we don't get into an
18403        // infinite recursion.
18404        app.adjSeq = mAdjSeq;
18405        app.curRawAdj = adj;
18406        app.hasStartedServices = false;
18407
18408        if (mBackupTarget != null && app == mBackupTarget.app) {
18409            // If possible we want to avoid killing apps while they're being backed up
18410            if (adj > ProcessList.BACKUP_APP_ADJ) {
18411                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18412                adj = ProcessList.BACKUP_APP_ADJ;
18413                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18414                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18415                }
18416                app.adjType = "backup";
18417                app.cached = false;
18418            }
18419            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18420                procState = ActivityManager.PROCESS_STATE_BACKUP;
18421            }
18422        }
18423
18424        boolean mayBeTop = false;
18425
18426        for (int is = app.services.size()-1;
18427                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18428                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18429                        || procState > ActivityManager.PROCESS_STATE_TOP);
18430                is--) {
18431            ServiceRecord s = app.services.valueAt(is);
18432            if (s.startRequested) {
18433                app.hasStartedServices = true;
18434                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18435                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18436                }
18437                if (app.hasShownUi && app != mHomeProcess) {
18438                    // If this process has shown some UI, let it immediately
18439                    // go to the LRU list because it may be pretty heavy with
18440                    // UI stuff.  We'll tag it with a label just to help
18441                    // debug and understand what is going on.
18442                    if (adj > ProcessList.SERVICE_ADJ) {
18443                        app.adjType = "cch-started-ui-services";
18444                    }
18445                } else {
18446                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18447                        // This service has seen some activity within
18448                        // recent memory, so we will keep its process ahead
18449                        // of the background processes.
18450                        if (adj > ProcessList.SERVICE_ADJ) {
18451                            adj = ProcessList.SERVICE_ADJ;
18452                            app.adjType = "started-services";
18453                            app.cached = false;
18454                        }
18455                    }
18456                    // If we have let the service slide into the background
18457                    // state, still have some text describing what it is doing
18458                    // even though the service no longer has an impact.
18459                    if (adj > ProcessList.SERVICE_ADJ) {
18460                        app.adjType = "cch-started-services";
18461                    }
18462                }
18463            }
18464            for (int conni = s.connections.size()-1;
18465                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18466                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18467                            || procState > ActivityManager.PROCESS_STATE_TOP);
18468                    conni--) {
18469                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18470                for (int i = 0;
18471                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18472                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18473                                || procState > ActivityManager.PROCESS_STATE_TOP);
18474                        i++) {
18475                    // XXX should compute this based on the max of
18476                    // all connected clients.
18477                    ConnectionRecord cr = clist.get(i);
18478                    if (cr.binding.client == app) {
18479                        // Binding to ourself is not interesting.
18480                        continue;
18481                    }
18482                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18483                        ProcessRecord client = cr.binding.client;
18484                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18485                                TOP_APP, doingAll, now);
18486                        int clientProcState = client.curProcState;
18487                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18488                            // If the other app is cached for any reason, for purposes here
18489                            // we are going to consider it empty.  The specific cached state
18490                            // doesn't propagate except under certain conditions.
18491                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18492                        }
18493                        String adjType = null;
18494                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18495                            // Not doing bind OOM management, so treat
18496                            // this guy more like a started service.
18497                            if (app.hasShownUi && app != mHomeProcess) {
18498                                // If this process has shown some UI, let it immediately
18499                                // go to the LRU list because it may be pretty heavy with
18500                                // UI stuff.  We'll tag it with a label just to help
18501                                // debug and understand what is going on.
18502                                if (adj > clientAdj) {
18503                                    adjType = "cch-bound-ui-services";
18504                                }
18505                                app.cached = false;
18506                                clientAdj = adj;
18507                                clientProcState = procState;
18508                            } else {
18509                                if (now >= (s.lastActivity
18510                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18511                                    // This service has not seen activity within
18512                                    // recent memory, so allow it to drop to the
18513                                    // LRU list if there is no other reason to keep
18514                                    // it around.  We'll also tag it with a label just
18515                                    // to help debug and undertand what is going on.
18516                                    if (adj > clientAdj) {
18517                                        adjType = "cch-bound-services";
18518                                    }
18519                                    clientAdj = adj;
18520                                }
18521                            }
18522                        }
18523                        if (adj > clientAdj) {
18524                            // If this process has recently shown UI, and
18525                            // the process that is binding to it is less
18526                            // important than being visible, then we don't
18527                            // care about the binding as much as we care
18528                            // about letting this process get into the LRU
18529                            // list to be killed and restarted if needed for
18530                            // memory.
18531                            if (app.hasShownUi && app != mHomeProcess
18532                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18533                                adjType = "cch-bound-ui-services";
18534                            } else {
18535                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18536                                        |Context.BIND_IMPORTANT)) != 0) {
18537                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18538                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18539                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18540                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18541                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18542                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18543                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18544                                    adj = clientAdj;
18545                                } else {
18546                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18547                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18548                                    }
18549                                }
18550                                if (!client.cached) {
18551                                    app.cached = false;
18552                                }
18553                                adjType = "service";
18554                            }
18555                        }
18556                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18557                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18558                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18559                            }
18560                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18561                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18562                                    // Special handling of clients who are in the top state.
18563                                    // We *may* want to consider this process to be in the
18564                                    // top state as well, but only if there is not another
18565                                    // reason for it to be running.  Being on the top is a
18566                                    // special state, meaning you are specifically running
18567                                    // for the current top app.  If the process is already
18568                                    // running in the background for some other reason, it
18569                                    // is more important to continue considering it to be
18570                                    // in the background state.
18571                                    mayBeTop = true;
18572                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18573                                } else {
18574                                    // Special handling for above-top states (persistent
18575                                    // processes).  These should not bring the current process
18576                                    // into the top state, since they are not on top.  Instead
18577                                    // give them the best state after that.
18578                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18579                                        clientProcState =
18580                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18581                                    } else if (mWakefulness
18582                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18583                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18584                                                    != 0) {
18585                                        clientProcState =
18586                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18587                                    } else {
18588                                        clientProcState =
18589                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18590                                    }
18591                                }
18592                            }
18593                        } else {
18594                            if (clientProcState <
18595                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18596                                clientProcState =
18597                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18598                            }
18599                        }
18600                        if (procState > clientProcState) {
18601                            procState = clientProcState;
18602                        }
18603                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18604                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18605                            app.pendingUiClean = true;
18606                        }
18607                        if (adjType != null) {
18608                            app.adjType = adjType;
18609                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18610                                    .REASON_SERVICE_IN_USE;
18611                            app.adjSource = cr.binding.client;
18612                            app.adjSourceProcState = clientProcState;
18613                            app.adjTarget = s.name;
18614                        }
18615                    }
18616                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18617                        app.treatLikeActivity = true;
18618                    }
18619                    final ActivityRecord a = cr.activity;
18620                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18621                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18622                                (a.visible || a.state == ActivityState.RESUMED
18623                                 || a.state == ActivityState.PAUSING)) {
18624                            adj = ProcessList.FOREGROUND_APP_ADJ;
18625                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18626                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18627                            }
18628                            app.cached = false;
18629                            app.adjType = "service";
18630                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18631                                    .REASON_SERVICE_IN_USE;
18632                            app.adjSource = a;
18633                            app.adjSourceProcState = procState;
18634                            app.adjTarget = s.name;
18635                        }
18636                    }
18637                }
18638            }
18639        }
18640
18641        for (int provi = app.pubProviders.size()-1;
18642                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18643                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18644                        || procState > ActivityManager.PROCESS_STATE_TOP);
18645                provi--) {
18646            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18647            for (int i = cpr.connections.size()-1;
18648                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18649                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18650                            || procState > ActivityManager.PROCESS_STATE_TOP);
18651                    i--) {
18652                ContentProviderConnection conn = cpr.connections.get(i);
18653                ProcessRecord client = conn.client;
18654                if (client == app) {
18655                    // Being our own client is not interesting.
18656                    continue;
18657                }
18658                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18659                int clientProcState = client.curProcState;
18660                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18661                    // If the other app is cached for any reason, for purposes here
18662                    // we are going to consider it empty.
18663                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18664                }
18665                if (adj > clientAdj) {
18666                    if (app.hasShownUi && app != mHomeProcess
18667                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18668                        app.adjType = "cch-ui-provider";
18669                    } else {
18670                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18671                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18672                        app.adjType = "provider";
18673                    }
18674                    app.cached &= client.cached;
18675                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18676                            .REASON_PROVIDER_IN_USE;
18677                    app.adjSource = client;
18678                    app.adjSourceProcState = clientProcState;
18679                    app.adjTarget = cpr.name;
18680                }
18681                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18682                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18683                        // Special handling of clients who are in the top state.
18684                        // We *may* want to consider this process to be in the
18685                        // top state as well, but only if there is not another
18686                        // reason for it to be running.  Being on the top is a
18687                        // special state, meaning you are specifically running
18688                        // for the current top app.  If the process is already
18689                        // running in the background for some other reason, it
18690                        // is more important to continue considering it to be
18691                        // in the background state.
18692                        mayBeTop = true;
18693                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18694                    } else {
18695                        // Special handling for above-top states (persistent
18696                        // processes).  These should not bring the current process
18697                        // into the top state, since they are not on top.  Instead
18698                        // give them the best state after that.
18699                        clientProcState =
18700                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18701                    }
18702                }
18703                if (procState > clientProcState) {
18704                    procState = clientProcState;
18705                }
18706                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18707                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18708                }
18709            }
18710            // If the provider has external (non-framework) process
18711            // dependencies, ensure that its adjustment is at least
18712            // FOREGROUND_APP_ADJ.
18713            if (cpr.hasExternalProcessHandles()) {
18714                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18715                    adj = ProcessList.FOREGROUND_APP_ADJ;
18716                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18717                    app.cached = false;
18718                    app.adjType = "provider";
18719                    app.adjTarget = cpr.name;
18720                }
18721                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18722                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18723                }
18724            }
18725        }
18726
18727        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
18728            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18729                adj = ProcessList.PREVIOUS_APP_ADJ;
18730                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18731                app.cached = false;
18732                app.adjType = "provider";
18733            }
18734            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18735                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18736            }
18737        }
18738
18739        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18740            // A client of one of our services or providers is in the top state.  We
18741            // *may* want to be in the top state, but not if we are already running in
18742            // the background for some other reason.  For the decision here, we are going
18743            // to pick out a few specific states that we want to remain in when a client
18744            // is top (states that tend to be longer-term) and otherwise allow it to go
18745            // to the top state.
18746            switch (procState) {
18747                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18748                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18749                case ActivityManager.PROCESS_STATE_SERVICE:
18750                    // These all are longer-term states, so pull them up to the top
18751                    // of the background states, but not all the way to the top state.
18752                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18753                    break;
18754                default:
18755                    // Otherwise, top is a better choice, so take it.
18756                    procState = ActivityManager.PROCESS_STATE_TOP;
18757                    break;
18758            }
18759        }
18760
18761        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18762            if (app.hasClientActivities) {
18763                // This is a cached process, but with client activities.  Mark it so.
18764                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18765                app.adjType = "cch-client-act";
18766            } else if (app.treatLikeActivity) {
18767                // This is a cached process, but somebody wants us to treat it like it has
18768                // an activity, okay!
18769                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18770                app.adjType = "cch-as-act";
18771            }
18772        }
18773
18774        if (adj == ProcessList.SERVICE_ADJ) {
18775            if (doingAll) {
18776                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18777                mNewNumServiceProcs++;
18778                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18779                if (!app.serviceb) {
18780                    // This service isn't far enough down on the LRU list to
18781                    // normally be a B service, but if we are low on RAM and it
18782                    // is large we want to force it down since we would prefer to
18783                    // keep launcher over it.
18784                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18785                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18786                        app.serviceHighRam = true;
18787                        app.serviceb = true;
18788                        //Slog.i(TAG, "ADJ " + app + " high ram!");
18789                    } else {
18790                        mNewNumAServiceProcs++;
18791                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
18792                    }
18793                } else {
18794                    app.serviceHighRam = false;
18795                }
18796            }
18797            if (app.serviceb) {
18798                adj = ProcessList.SERVICE_B_ADJ;
18799            }
18800        }
18801
18802        app.curRawAdj = adj;
18803
18804        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18805        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18806        if (adj > app.maxAdj) {
18807            adj = app.maxAdj;
18808            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18809                schedGroup = Process.THREAD_GROUP_DEFAULT;
18810            }
18811        }
18812
18813        // Do final modification to adj.  Everything we do between here and applying
18814        // the final setAdj must be done in this function, because we will also use
18815        // it when computing the final cached adj later.  Note that we don't need to
18816        // worry about this for max adj above, since max adj will always be used to
18817        // keep it out of the cached vaues.
18818        app.curAdj = app.modifyRawOomAdj(adj);
18819        app.curSchedGroup = schedGroup;
18820        app.curProcState = procState;
18821        app.foregroundActivities = foregroundActivities;
18822
18823        return app.curRawAdj;
18824    }
18825
18826    /**
18827     * Record new PSS sample for a process.
18828     */
18829    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18830        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18831        proc.lastPssTime = now;
18832        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18833        if (DEBUG_PSS) Slog.d(TAG_PSS,
18834                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18835                + " state=" + ProcessList.makeProcStateString(procState));
18836        if (proc.initialIdlePss == 0) {
18837            proc.initialIdlePss = pss;
18838        }
18839        proc.lastPss = pss;
18840        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18841            proc.lastCachedPss = pss;
18842        }
18843
18844        final SparseArray<Pair<Long, String>> watchUids
18845                = mMemWatchProcesses.getMap().get(proc.processName);
18846        Long check = null;
18847        if (watchUids != null) {
18848            Pair<Long, String> val = watchUids.get(proc.uid);
18849            if (val == null) {
18850                val = watchUids.get(0);
18851            }
18852            if (val != null) {
18853                check = val.first;
18854            }
18855        }
18856        if (check != null) {
18857            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18858                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18859                if (!isDebuggable) {
18860                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18861                        isDebuggable = true;
18862                    }
18863                }
18864                if (isDebuggable) {
18865                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18866                    final ProcessRecord myProc = proc;
18867                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
18868                    mMemWatchDumpProcName = proc.processName;
18869                    mMemWatchDumpFile = heapdumpFile.toString();
18870                    mMemWatchDumpPid = proc.pid;
18871                    mMemWatchDumpUid = proc.uid;
18872                    BackgroundThread.getHandler().post(new Runnable() {
18873                        @Override
18874                        public void run() {
18875                            revokeUriPermission(ActivityThread.currentActivityThread()
18876                                            .getApplicationThread(),
18877                                    DumpHeapActivity.JAVA_URI,
18878                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18879                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18880                                    UserHandle.myUserId());
18881                            ParcelFileDescriptor fd = null;
18882                            try {
18883                                heapdumpFile.delete();
18884                                fd = ParcelFileDescriptor.open(heapdumpFile,
18885                                        ParcelFileDescriptor.MODE_CREATE |
18886                                                ParcelFileDescriptor.MODE_TRUNCATE |
18887                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
18888                                                ParcelFileDescriptor.MODE_APPEND);
18889                                IApplicationThread thread = myProc.thread;
18890                                if (thread != null) {
18891                                    try {
18892                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
18893                                                "Requesting dump heap from "
18894                                                + myProc + " to " + heapdumpFile);
18895                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
18896                                    } catch (RemoteException e) {
18897                                    }
18898                                }
18899                            } catch (FileNotFoundException e) {
18900                                e.printStackTrace();
18901                            } finally {
18902                                if (fd != null) {
18903                                    try {
18904                                        fd.close();
18905                                    } catch (IOException e) {
18906                                    }
18907                                }
18908                            }
18909                        }
18910                    });
18911                } else {
18912                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18913                            + ", but debugging not enabled");
18914                }
18915            }
18916        }
18917    }
18918
18919    /**
18920     * Schedule PSS collection of a process.
18921     */
18922    void requestPssLocked(ProcessRecord proc, int procState) {
18923        if (mPendingPssProcesses.contains(proc)) {
18924            return;
18925        }
18926        if (mPendingPssProcesses.size() == 0) {
18927            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18928        }
18929        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18930        proc.pssProcState = procState;
18931        mPendingPssProcesses.add(proc);
18932    }
18933
18934    /**
18935     * Schedule PSS collection of all processes.
18936     */
18937    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18938        if (!always) {
18939            if (now < (mLastFullPssTime +
18940                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18941                return;
18942            }
18943        }
18944        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18945        mLastFullPssTime = now;
18946        mFullPssPending = true;
18947        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18948        mPendingPssProcesses.clear();
18949        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18950            ProcessRecord app = mLruProcesses.get(i);
18951            if (app.thread == null
18952                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18953                continue;
18954            }
18955            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18956                app.pssProcState = app.setProcState;
18957                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18958                        mTestPssMode, isSleeping(), now);
18959                mPendingPssProcesses.add(app);
18960            }
18961        }
18962        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18963    }
18964
18965    public void setTestPssMode(boolean enabled) {
18966        synchronized (this) {
18967            mTestPssMode = enabled;
18968            if (enabled) {
18969                // Whenever we enable the mode, we want to take a snapshot all of current
18970                // process mem use.
18971                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18972            }
18973        }
18974    }
18975
18976    /**
18977     * Ask a given process to GC right now.
18978     */
18979    final void performAppGcLocked(ProcessRecord app) {
18980        try {
18981            app.lastRequestedGc = SystemClock.uptimeMillis();
18982            if (app.thread != null) {
18983                if (app.reportLowMemory) {
18984                    app.reportLowMemory = false;
18985                    app.thread.scheduleLowMemory();
18986                } else {
18987                    app.thread.processInBackground();
18988                }
18989            }
18990        } catch (Exception e) {
18991            // whatever.
18992        }
18993    }
18994
18995    /**
18996     * Returns true if things are idle enough to perform GCs.
18997     */
18998    private final boolean canGcNowLocked() {
18999        boolean processingBroadcasts = false;
19000        for (BroadcastQueue q : mBroadcastQueues) {
19001            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19002                processingBroadcasts = true;
19003            }
19004        }
19005        return !processingBroadcasts
19006                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19007    }
19008
19009    /**
19010     * Perform GCs on all processes that are waiting for it, but only
19011     * if things are idle.
19012     */
19013    final void performAppGcsLocked() {
19014        final int N = mProcessesToGc.size();
19015        if (N <= 0) {
19016            return;
19017        }
19018        if (canGcNowLocked()) {
19019            while (mProcessesToGc.size() > 0) {
19020                ProcessRecord proc = mProcessesToGc.remove(0);
19021                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19022                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19023                            <= SystemClock.uptimeMillis()) {
19024                        // To avoid spamming the system, we will GC processes one
19025                        // at a time, waiting a few seconds between each.
19026                        performAppGcLocked(proc);
19027                        scheduleAppGcsLocked();
19028                        return;
19029                    } else {
19030                        // It hasn't been long enough since we last GCed this
19031                        // process...  put it in the list to wait for its time.
19032                        addProcessToGcListLocked(proc);
19033                        break;
19034                    }
19035                }
19036            }
19037
19038            scheduleAppGcsLocked();
19039        }
19040    }
19041
19042    /**
19043     * If all looks good, perform GCs on all processes waiting for them.
19044     */
19045    final void performAppGcsIfAppropriateLocked() {
19046        if (canGcNowLocked()) {
19047            performAppGcsLocked();
19048            return;
19049        }
19050        // Still not idle, wait some more.
19051        scheduleAppGcsLocked();
19052    }
19053
19054    /**
19055     * Schedule the execution of all pending app GCs.
19056     */
19057    final void scheduleAppGcsLocked() {
19058        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19059
19060        if (mProcessesToGc.size() > 0) {
19061            // Schedule a GC for the time to the next process.
19062            ProcessRecord proc = mProcessesToGc.get(0);
19063            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19064
19065            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19066            long now = SystemClock.uptimeMillis();
19067            if (when < (now+GC_TIMEOUT)) {
19068                when = now + GC_TIMEOUT;
19069            }
19070            mHandler.sendMessageAtTime(msg, when);
19071        }
19072    }
19073
19074    /**
19075     * Add a process to the array of processes waiting to be GCed.  Keeps the
19076     * list in sorted order by the last GC time.  The process can't already be
19077     * on the list.
19078     */
19079    final void addProcessToGcListLocked(ProcessRecord proc) {
19080        boolean added = false;
19081        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19082            if (mProcessesToGc.get(i).lastRequestedGc <
19083                    proc.lastRequestedGc) {
19084                added = true;
19085                mProcessesToGc.add(i+1, proc);
19086                break;
19087            }
19088        }
19089        if (!added) {
19090            mProcessesToGc.add(0, proc);
19091        }
19092    }
19093
19094    /**
19095     * Set up to ask a process to GC itself.  This will either do it
19096     * immediately, or put it on the list of processes to gc the next
19097     * time things are idle.
19098     */
19099    final void scheduleAppGcLocked(ProcessRecord app) {
19100        long now = SystemClock.uptimeMillis();
19101        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19102            return;
19103        }
19104        if (!mProcessesToGc.contains(app)) {
19105            addProcessToGcListLocked(app);
19106            scheduleAppGcsLocked();
19107        }
19108    }
19109
19110    final void checkExcessivePowerUsageLocked(boolean doKills) {
19111        updateCpuStatsNow();
19112
19113        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19114        boolean doWakeKills = doKills;
19115        boolean doCpuKills = doKills;
19116        if (mLastPowerCheckRealtime == 0) {
19117            doWakeKills = false;
19118        }
19119        if (mLastPowerCheckUptime == 0) {
19120            doCpuKills = false;
19121        }
19122        if (stats.isScreenOn()) {
19123            doWakeKills = false;
19124        }
19125        final long curRealtime = SystemClock.elapsedRealtime();
19126        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19127        final long curUptime = SystemClock.uptimeMillis();
19128        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19129        mLastPowerCheckRealtime = curRealtime;
19130        mLastPowerCheckUptime = curUptime;
19131        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19132            doWakeKills = false;
19133        }
19134        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19135            doCpuKills = false;
19136        }
19137        int i = mLruProcesses.size();
19138        while (i > 0) {
19139            i--;
19140            ProcessRecord app = mLruProcesses.get(i);
19141            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19142                long wtime;
19143                synchronized (stats) {
19144                    wtime = stats.getProcessWakeTime(app.info.uid,
19145                            app.pid, curRealtime);
19146                }
19147                long wtimeUsed = wtime - app.lastWakeTime;
19148                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19149                if (DEBUG_POWER) {
19150                    StringBuilder sb = new StringBuilder(128);
19151                    sb.append("Wake for ");
19152                    app.toShortString(sb);
19153                    sb.append(": over ");
19154                    TimeUtils.formatDuration(realtimeSince, sb);
19155                    sb.append(" used ");
19156                    TimeUtils.formatDuration(wtimeUsed, sb);
19157                    sb.append(" (");
19158                    sb.append((wtimeUsed*100)/realtimeSince);
19159                    sb.append("%)");
19160                    Slog.i(TAG_POWER, sb.toString());
19161                    sb.setLength(0);
19162                    sb.append("CPU for ");
19163                    app.toShortString(sb);
19164                    sb.append(": over ");
19165                    TimeUtils.formatDuration(uptimeSince, sb);
19166                    sb.append(" used ");
19167                    TimeUtils.formatDuration(cputimeUsed, sb);
19168                    sb.append(" (");
19169                    sb.append((cputimeUsed*100)/uptimeSince);
19170                    sb.append("%)");
19171                    Slog.i(TAG_POWER, sb.toString());
19172                }
19173                // If a process has held a wake lock for more
19174                // than 50% of the time during this period,
19175                // that sounds bad.  Kill!
19176                if (doWakeKills && realtimeSince > 0
19177                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19178                    synchronized (stats) {
19179                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19180                                realtimeSince, wtimeUsed);
19181                    }
19182                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19183                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19184                } else if (doCpuKills && uptimeSince > 0
19185                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19186                    synchronized (stats) {
19187                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19188                                uptimeSince, cputimeUsed);
19189                    }
19190                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19191                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19192                } else {
19193                    app.lastWakeTime = wtime;
19194                    app.lastCpuTime = app.curCpuTime;
19195                }
19196            }
19197        }
19198    }
19199
19200    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19201            long nowElapsed) {
19202        boolean success = true;
19203
19204        if (app.curRawAdj != app.setRawAdj) {
19205            app.setRawAdj = app.curRawAdj;
19206        }
19207
19208        int changes = 0;
19209
19210        if (app.curAdj != app.setAdj) {
19211            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19212            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19213                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19214                    + app.adjType);
19215            app.setAdj = app.curAdj;
19216        }
19217
19218        if (app.setSchedGroup != app.curSchedGroup) {
19219            app.setSchedGroup = app.curSchedGroup;
19220            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19221                    "Setting process group of " + app.processName
19222                    + " to " + app.curSchedGroup);
19223            if (app.waitingToKill != null && app.curReceiver == null
19224                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
19225                app.kill(app.waitingToKill, true);
19226                success = false;
19227            } else {
19228                if (true) {
19229                    long oldId = Binder.clearCallingIdentity();
19230                    try {
19231                        Process.setProcessGroup(app.pid, app.curSchedGroup);
19232                    } catch (Exception e) {
19233                        Slog.w(TAG, "Failed setting process group of " + app.pid
19234                                + " to " + app.curSchedGroup);
19235                        e.printStackTrace();
19236                    } finally {
19237                        Binder.restoreCallingIdentity(oldId);
19238                    }
19239                } else {
19240                    if (app.thread != null) {
19241                        try {
19242                            app.thread.setSchedulingGroup(app.curSchedGroup);
19243                        } catch (RemoteException e) {
19244                        }
19245                    }
19246                }
19247            }
19248        }
19249        if (app.repForegroundActivities != app.foregroundActivities) {
19250            app.repForegroundActivities = app.foregroundActivities;
19251            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19252        }
19253        if (app.repProcState != app.curProcState) {
19254            app.repProcState = app.curProcState;
19255            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19256            if (app.thread != null) {
19257                try {
19258                    if (false) {
19259                        //RuntimeException h = new RuntimeException("here");
19260                        Slog.i(TAG, "Sending new process state " + app.repProcState
19261                                + " to " + app /*, h*/);
19262                    }
19263                    app.thread.setProcessState(app.repProcState);
19264                } catch (RemoteException e) {
19265                }
19266            }
19267        }
19268        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19269                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19270            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19271                // Experimental code to more aggressively collect pss while
19272                // running test...  the problem is that this tends to collect
19273                // the data right when a process is transitioning between process
19274                // states, which well tend to give noisy data.
19275                long start = SystemClock.uptimeMillis();
19276                long pss = Debug.getPss(app.pid, mTmpLong, null);
19277                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
19278                mPendingPssProcesses.remove(app);
19279                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19280                        + " to " + app.curProcState + ": "
19281                        + (SystemClock.uptimeMillis()-start) + "ms");
19282            }
19283            app.lastStateTime = now;
19284            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19285                    mTestPssMode, isSleeping(), now);
19286            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19287                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19288                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19289                    + (app.nextPssTime-now) + ": " + app);
19290        } else {
19291            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19292                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19293                    mTestPssMode)))) {
19294                requestPssLocked(app, app.setProcState);
19295                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19296                        mTestPssMode, isSleeping(), now);
19297            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19298                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19299        }
19300        if (app.setProcState != app.curProcState) {
19301            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19302                    "Proc state change of " + app.processName
19303                            + " to " + app.curProcState);
19304            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19305            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19306            if (setImportant && !curImportant) {
19307                // This app is no longer something we consider important enough to allow to
19308                // use arbitrary amounts of battery power.  Note
19309                // its current wake lock time to later know to kill it if
19310                // it is not behaving well.
19311                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19312                synchronized (stats) {
19313                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19314                            app.pid, nowElapsed);
19315                }
19316                app.lastCpuTime = app.curCpuTime;
19317
19318            }
19319            // Inform UsageStats of important process state change
19320            // Must be called before updating setProcState
19321            maybeUpdateUsageStatsLocked(app, nowElapsed);
19322
19323            app.setProcState = app.curProcState;
19324            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19325                app.notCachedSinceIdle = false;
19326            }
19327            if (!doingAll) {
19328                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19329            } else {
19330                app.procStateChanged = true;
19331            }
19332        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19333                > USAGE_STATS_INTERACTION_INTERVAL) {
19334            // For apps that sit around for a long time in the interactive state, we need
19335            // to report this at least once a day so they don't go idle.
19336            maybeUpdateUsageStatsLocked(app, nowElapsed);
19337        }
19338
19339        if (changes != 0) {
19340            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19341                    "Changes in " + app + ": " + changes);
19342            int i = mPendingProcessChanges.size()-1;
19343            ProcessChangeItem item = null;
19344            while (i >= 0) {
19345                item = mPendingProcessChanges.get(i);
19346                if (item.pid == app.pid) {
19347                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19348                            "Re-using existing item: " + item);
19349                    break;
19350                }
19351                i--;
19352            }
19353            if (i < 0) {
19354                // No existing item in pending changes; need a new one.
19355                final int NA = mAvailProcessChanges.size();
19356                if (NA > 0) {
19357                    item = mAvailProcessChanges.remove(NA-1);
19358                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19359                            "Retrieving available item: " + item);
19360                } else {
19361                    item = new ProcessChangeItem();
19362                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19363                            "Allocating new item: " + item);
19364                }
19365                item.changes = 0;
19366                item.pid = app.pid;
19367                item.uid = app.info.uid;
19368                if (mPendingProcessChanges.size() == 0) {
19369                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19370                            "*** Enqueueing dispatch processes changed!");
19371                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19372                }
19373                mPendingProcessChanges.add(item);
19374            }
19375            item.changes |= changes;
19376            item.processState = app.repProcState;
19377            item.foregroundActivities = app.repForegroundActivities;
19378            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19379                    "Item " + Integer.toHexString(System.identityHashCode(item))
19380                    + " " + app.toShortString() + ": changes=" + item.changes
19381                    + " procState=" + item.processState
19382                    + " foreground=" + item.foregroundActivities
19383                    + " type=" + app.adjType + " source=" + app.adjSource
19384                    + " target=" + app.adjTarget);
19385        }
19386
19387        return success;
19388    }
19389
19390    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19391        final UidRecord.ChangeItem pendingChange;
19392        if (uidRec == null || uidRec.pendingChange == null) {
19393            if (mPendingUidChanges.size() == 0) {
19394                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19395                        "*** Enqueueing dispatch uid changed!");
19396                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19397            }
19398            final int NA = mAvailUidChanges.size();
19399            if (NA > 0) {
19400                pendingChange = mAvailUidChanges.remove(NA-1);
19401                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19402                        "Retrieving available item: " + pendingChange);
19403            } else {
19404                pendingChange = new UidRecord.ChangeItem();
19405                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19406                        "Allocating new item: " + pendingChange);
19407            }
19408            if (uidRec != null) {
19409                uidRec.pendingChange = pendingChange;
19410                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19411                    // If this uid is going away, and we haven't yet reported it is gone,
19412                    // then do so now.
19413                    change = UidRecord.CHANGE_GONE_IDLE;
19414                }
19415            } else if (uid < 0) {
19416                throw new IllegalArgumentException("No UidRecord or uid");
19417            }
19418            pendingChange.uidRecord = uidRec;
19419            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19420            mPendingUidChanges.add(pendingChange);
19421        } else {
19422            pendingChange = uidRec.pendingChange;
19423            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19424                change = UidRecord.CHANGE_GONE_IDLE;
19425            }
19426        }
19427        pendingChange.change = change;
19428        pendingChange.processState = uidRec != null
19429                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19430    }
19431
19432    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19433            String authority) {
19434        if (app == null) return;
19435        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19436            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19437            if (userState == null) return;
19438            final long now = SystemClock.elapsedRealtime();
19439            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19440            if (lastReported == null || lastReported < now - 60 * 1000L) {
19441                mUsageStatsService.reportContentProviderUsage(
19442                        authority, providerPkgName, app.userId);
19443                userState.mProviderLastReportedFg.put(authority, now);
19444            }
19445        }
19446    }
19447
19448    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19449        if (DEBUG_USAGE_STATS) {
19450            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19451                    + "] state changes: old = " + app.setProcState + ", new = "
19452                    + app.curProcState);
19453        }
19454        if (mUsageStatsService == null) {
19455            return;
19456        }
19457        boolean isInteraction;
19458        // To avoid some abuse patterns, we are going to be careful about what we consider
19459        // to be an app interaction.  Being the top activity doesn't count while the display
19460        // is sleeping, nor do short foreground services.
19461        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19462            isInteraction = true;
19463            app.fgInteractionTime = 0;
19464        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19465            if (app.fgInteractionTime == 0) {
19466                app.fgInteractionTime = nowElapsed;
19467                isInteraction = false;
19468            } else {
19469                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19470            }
19471        } else {
19472            isInteraction = app.curProcState
19473                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19474            app.fgInteractionTime = 0;
19475        }
19476        if (isInteraction && (!app.reportedInteraction
19477                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19478            app.interactionEventTime = nowElapsed;
19479            String[] packages = app.getPackageList();
19480            if (packages != null) {
19481                for (int i = 0; i < packages.length; i++) {
19482                    mUsageStatsService.reportEvent(packages[i], app.userId,
19483                            UsageEvents.Event.SYSTEM_INTERACTION);
19484                }
19485            }
19486        }
19487        app.reportedInteraction = isInteraction;
19488        if (!isInteraction) {
19489            app.interactionEventTime = 0;
19490        }
19491    }
19492
19493    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19494        if (proc.thread != null) {
19495            if (proc.baseProcessTracker != null) {
19496                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19497            }
19498        }
19499    }
19500
19501    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19502            ProcessRecord TOP_APP, boolean doingAll, long now) {
19503        if (app.thread == null) {
19504            return false;
19505        }
19506
19507        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19508
19509        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19510    }
19511
19512    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19513            boolean oomAdj) {
19514        if (isForeground != proc.foregroundServices) {
19515            proc.foregroundServices = isForeground;
19516            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19517                    proc.info.uid);
19518            if (isForeground) {
19519                if (curProcs == null) {
19520                    curProcs = new ArrayList<ProcessRecord>();
19521                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19522                }
19523                if (!curProcs.contains(proc)) {
19524                    curProcs.add(proc);
19525                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19526                            proc.info.packageName, proc.info.uid);
19527                }
19528            } else {
19529                if (curProcs != null) {
19530                    if (curProcs.remove(proc)) {
19531                        mBatteryStatsService.noteEvent(
19532                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19533                                proc.info.packageName, proc.info.uid);
19534                        if (curProcs.size() <= 0) {
19535                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19536                        }
19537                    }
19538                }
19539            }
19540            if (oomAdj) {
19541                updateOomAdjLocked();
19542            }
19543        }
19544    }
19545
19546    private final ActivityRecord resumedAppLocked() {
19547        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19548        String pkg;
19549        int uid;
19550        if (act != null) {
19551            pkg = act.packageName;
19552            uid = act.info.applicationInfo.uid;
19553        } else {
19554            pkg = null;
19555            uid = -1;
19556        }
19557        // Has the UID or resumed package name changed?
19558        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19559                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19560            if (mCurResumedPackage != null) {
19561                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19562                        mCurResumedPackage, mCurResumedUid);
19563            }
19564            mCurResumedPackage = pkg;
19565            mCurResumedUid = uid;
19566            if (mCurResumedPackage != null) {
19567                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19568                        mCurResumedPackage, mCurResumedUid);
19569            }
19570        }
19571        return act;
19572    }
19573
19574    final boolean updateOomAdjLocked(ProcessRecord app) {
19575        final ActivityRecord TOP_ACT = resumedAppLocked();
19576        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19577        final boolean wasCached = app.cached;
19578
19579        mAdjSeq++;
19580
19581        // This is the desired cached adjusment we want to tell it to use.
19582        // If our app is currently cached, we know it, and that is it.  Otherwise,
19583        // we don't know it yet, and it needs to now be cached we will then
19584        // need to do a complete oom adj.
19585        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19586                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19587        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19588                SystemClock.uptimeMillis());
19589        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19590            // Changed to/from cached state, so apps after it in the LRU
19591            // list may also be changed.
19592            updateOomAdjLocked();
19593        }
19594        return success;
19595    }
19596
19597    final void updateOomAdjLocked() {
19598        final ActivityRecord TOP_ACT = resumedAppLocked();
19599        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19600        final long now = SystemClock.uptimeMillis();
19601        final long nowElapsed = SystemClock.elapsedRealtime();
19602        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19603        final int N = mLruProcesses.size();
19604
19605        if (false) {
19606            RuntimeException e = new RuntimeException();
19607            e.fillInStackTrace();
19608            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19609        }
19610
19611        // Reset state in all uid records.
19612        for (int i=mActiveUids.size()-1; i>=0; i--) {
19613            final UidRecord uidRec = mActiveUids.valueAt(i);
19614            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19615                    "Starting update of " + uidRec);
19616            uidRec.reset();
19617        }
19618
19619        mStackSupervisor.rankTaskLayersIfNeeded();
19620
19621        mAdjSeq++;
19622        mNewNumServiceProcs = 0;
19623        mNewNumAServiceProcs = 0;
19624
19625        final int emptyProcessLimit;
19626        final int cachedProcessLimit;
19627        if (mProcessLimit <= 0) {
19628            emptyProcessLimit = cachedProcessLimit = 0;
19629        } else if (mProcessLimit == 1) {
19630            emptyProcessLimit = 1;
19631            cachedProcessLimit = 0;
19632        } else {
19633            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19634            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19635        }
19636
19637        // Let's determine how many processes we have running vs.
19638        // how many slots we have for background processes; we may want
19639        // to put multiple processes in a slot of there are enough of
19640        // them.
19641        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19642                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19643        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19644        if (numEmptyProcs > cachedProcessLimit) {
19645            // If there are more empty processes than our limit on cached
19646            // processes, then use the cached process limit for the factor.
19647            // This ensures that the really old empty processes get pushed
19648            // down to the bottom, so if we are running low on memory we will
19649            // have a better chance at keeping around more cached processes
19650            // instead of a gazillion empty processes.
19651            numEmptyProcs = cachedProcessLimit;
19652        }
19653        int emptyFactor = numEmptyProcs/numSlots;
19654        if (emptyFactor < 1) emptyFactor = 1;
19655        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19656        if (cachedFactor < 1) cachedFactor = 1;
19657        int stepCached = 0;
19658        int stepEmpty = 0;
19659        int numCached = 0;
19660        int numEmpty = 0;
19661        int numTrimming = 0;
19662
19663        mNumNonCachedProcs = 0;
19664        mNumCachedHiddenProcs = 0;
19665
19666        // First update the OOM adjustment for each of the
19667        // application processes based on their current state.
19668        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19669        int nextCachedAdj = curCachedAdj+1;
19670        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19671        int nextEmptyAdj = curEmptyAdj+2;
19672        for (int i=N-1; i>=0; i--) {
19673            ProcessRecord app = mLruProcesses.get(i);
19674            if (!app.killedByAm && app.thread != null) {
19675                app.procStateChanged = false;
19676                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19677
19678                // If we haven't yet assigned the final cached adj
19679                // to the process, do that now.
19680                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19681                    switch (app.curProcState) {
19682                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19683                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19684                            // This process is a cached process holding activities...
19685                            // assign it the next cached value for that type, and then
19686                            // step that cached level.
19687                            app.curRawAdj = curCachedAdj;
19688                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19689                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19690                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19691                                    + ")");
19692                            if (curCachedAdj != nextCachedAdj) {
19693                                stepCached++;
19694                                if (stepCached >= cachedFactor) {
19695                                    stepCached = 0;
19696                                    curCachedAdj = nextCachedAdj;
19697                                    nextCachedAdj += 2;
19698                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19699                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19700                                    }
19701                                }
19702                            }
19703                            break;
19704                        default:
19705                            // For everything else, assign next empty cached process
19706                            // level and bump that up.  Note that this means that
19707                            // long-running services that have dropped down to the
19708                            // cached level will be treated as empty (since their process
19709                            // state is still as a service), which is what we want.
19710                            app.curRawAdj = curEmptyAdj;
19711                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19712                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19713                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19714                                    + ")");
19715                            if (curEmptyAdj != nextEmptyAdj) {
19716                                stepEmpty++;
19717                                if (stepEmpty >= emptyFactor) {
19718                                    stepEmpty = 0;
19719                                    curEmptyAdj = nextEmptyAdj;
19720                                    nextEmptyAdj += 2;
19721                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19722                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19723                                    }
19724                                }
19725                            }
19726                            break;
19727                    }
19728                }
19729
19730                applyOomAdjLocked(app, true, now, nowElapsed);
19731
19732                // Count the number of process types.
19733                switch (app.curProcState) {
19734                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19735                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19736                        mNumCachedHiddenProcs++;
19737                        numCached++;
19738                        if (numCached > cachedProcessLimit) {
19739                            app.kill("cached #" + numCached, true);
19740                        }
19741                        break;
19742                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19743                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19744                                && app.lastActivityTime < oldTime) {
19745                            app.kill("empty for "
19746                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19747                                    / 1000) + "s", true);
19748                        } else {
19749                            numEmpty++;
19750                            if (numEmpty > emptyProcessLimit) {
19751                                app.kill("empty #" + numEmpty, true);
19752                            }
19753                        }
19754                        break;
19755                    default:
19756                        mNumNonCachedProcs++;
19757                        break;
19758                }
19759
19760                if (app.isolated && app.services.size() <= 0) {
19761                    // If this is an isolated process, and there are no
19762                    // services running in it, then the process is no longer
19763                    // needed.  We agressively kill these because we can by
19764                    // definition not re-use the same process again, and it is
19765                    // good to avoid having whatever code was running in them
19766                    // left sitting around after no longer needed.
19767                    app.kill("isolated not needed", true);
19768                } else {
19769                    // Keeping this process, update its uid.
19770                    final UidRecord uidRec = app.uidRecord;
19771                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
19772                        uidRec.curProcState = app.curProcState;
19773                    }
19774                }
19775
19776                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19777                        && !app.killedByAm) {
19778                    numTrimming++;
19779                }
19780            }
19781        }
19782
19783        mNumServiceProcs = mNewNumServiceProcs;
19784
19785        // Now determine the memory trimming level of background processes.
19786        // Unfortunately we need to start at the back of the list to do this
19787        // properly.  We only do this if the number of background apps we
19788        // are managing to keep around is less than half the maximum we desire;
19789        // if we are keeping a good number around, we'll let them use whatever
19790        // memory they want.
19791        final int numCachedAndEmpty = numCached + numEmpty;
19792        int memFactor;
19793        if (numCached <= ProcessList.TRIM_CACHED_APPS
19794                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19795            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19796                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19797            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19798                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19799            } else {
19800                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19801            }
19802        } else {
19803            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19804        }
19805        // We always allow the memory level to go up (better).  We only allow it to go
19806        // down if we are in a state where that is allowed, *and* the total number of processes
19807        // has gone down since last time.
19808        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19809                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19810                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19811        if (memFactor > mLastMemoryLevel) {
19812            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19813                memFactor = mLastMemoryLevel;
19814                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19815            }
19816        }
19817        mLastMemoryLevel = memFactor;
19818        mLastNumProcesses = mLruProcesses.size();
19819        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19820        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19821        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19822            if (mLowRamStartTime == 0) {
19823                mLowRamStartTime = now;
19824            }
19825            int step = 0;
19826            int fgTrimLevel;
19827            switch (memFactor) {
19828                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19829                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19830                    break;
19831                case ProcessStats.ADJ_MEM_FACTOR_LOW:
19832                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19833                    break;
19834                default:
19835                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19836                    break;
19837            }
19838            int factor = numTrimming/3;
19839            int minFactor = 2;
19840            if (mHomeProcess != null) minFactor++;
19841            if (mPreviousProcess != null) minFactor++;
19842            if (factor < minFactor) factor = minFactor;
19843            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19844            for (int i=N-1; i>=0; i--) {
19845                ProcessRecord app = mLruProcesses.get(i);
19846                if (allChanged || app.procStateChanged) {
19847                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19848                    app.procStateChanged = false;
19849                }
19850                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19851                        && !app.killedByAm) {
19852                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
19853                        try {
19854                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19855                                    "Trimming memory of " + app.processName + " to " + curLevel);
19856                            app.thread.scheduleTrimMemory(curLevel);
19857                        } catch (RemoteException e) {
19858                        }
19859                        if (false) {
19860                            // For now we won't do this; our memory trimming seems
19861                            // to be good enough at this point that destroying
19862                            // activities causes more harm than good.
19863                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19864                                    && app != mHomeProcess && app != mPreviousProcess) {
19865                                // Need to do this on its own message because the stack may not
19866                                // be in a consistent state at this point.
19867                                // For these apps we will also finish their activities
19868                                // to help them free memory.
19869                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19870                            }
19871                        }
19872                    }
19873                    app.trimMemoryLevel = curLevel;
19874                    step++;
19875                    if (step >= factor) {
19876                        step = 0;
19877                        switch (curLevel) {
19878                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19879                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19880                                break;
19881                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19882                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19883                                break;
19884                        }
19885                    }
19886                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19887                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19888                            && app.thread != null) {
19889                        try {
19890                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19891                                    "Trimming memory of heavy-weight " + app.processName
19892                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19893                            app.thread.scheduleTrimMemory(
19894                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19895                        } catch (RemoteException e) {
19896                        }
19897                    }
19898                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19899                } else {
19900                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19901                            || app.systemNoUi) && app.pendingUiClean) {
19902                        // If this application is now in the background and it
19903                        // had done UI, then give it the special trim level to
19904                        // have it free UI resources.
19905                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19906                        if (app.trimMemoryLevel < level && app.thread != null) {
19907                            try {
19908                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19909                                        "Trimming memory of bg-ui " + app.processName
19910                                        + " to " + level);
19911                                app.thread.scheduleTrimMemory(level);
19912                            } catch (RemoteException e) {
19913                            }
19914                        }
19915                        app.pendingUiClean = false;
19916                    }
19917                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19918                        try {
19919                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19920                                    "Trimming memory of fg " + app.processName
19921                                    + " to " + fgTrimLevel);
19922                            app.thread.scheduleTrimMemory(fgTrimLevel);
19923                        } catch (RemoteException e) {
19924                        }
19925                    }
19926                    app.trimMemoryLevel = fgTrimLevel;
19927                }
19928            }
19929        } else {
19930            if (mLowRamStartTime != 0) {
19931                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19932                mLowRamStartTime = 0;
19933            }
19934            for (int i=N-1; i>=0; i--) {
19935                ProcessRecord app = mLruProcesses.get(i);
19936                if (allChanged || app.procStateChanged) {
19937                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19938                    app.procStateChanged = false;
19939                }
19940                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19941                        || app.systemNoUi) && app.pendingUiClean) {
19942                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19943                            && app.thread != null) {
19944                        try {
19945                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19946                                    "Trimming memory of ui hidden " + app.processName
19947                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19948                            app.thread.scheduleTrimMemory(
19949                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19950                        } catch (RemoteException e) {
19951                        }
19952                    }
19953                    app.pendingUiClean = false;
19954                }
19955                app.trimMemoryLevel = 0;
19956            }
19957        }
19958
19959        if (mAlwaysFinishActivities) {
19960            // Need to do this on its own message because the stack may not
19961            // be in a consistent state at this point.
19962            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19963        }
19964
19965        if (allChanged) {
19966            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19967        }
19968
19969        // Update from any uid changes.
19970        for (int i=mActiveUids.size()-1; i>=0; i--) {
19971            final UidRecord uidRec = mActiveUids.valueAt(i);
19972            int uidChange = UidRecord.CHANGE_PROCSTATE;
19973            if (uidRec.setProcState != uidRec.curProcState) {
19974                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19975                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19976                        + " to " + uidRec.curProcState);
19977                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
19978                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
19979                        uidRec.lastBackgroundTime = nowElapsed;
19980                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
19981                            // Note: the background settle time is in elapsed realtime, while
19982                            // the handler time base is uptime.  All this means is that we may
19983                            // stop background uids later than we had intended, but that only
19984                            // happens because the device was sleeping so we are okay anyway.
19985                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
19986                        }
19987                    }
19988                } else {
19989                    if (uidRec.idle) {
19990                        uidChange = UidRecord.CHANGE_ACTIVE;
19991                        uidRec.idle = false;
19992                    }
19993                    uidRec.lastBackgroundTime = 0;
19994                }
19995                uidRec.setProcState = uidRec.curProcState;
19996                enqueueUidChangeLocked(uidRec, -1, uidChange);
19997                mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
19998            }
19999        }
20000
20001        if (mProcessStats.shouldWriteNowLocked(now)) {
20002            mHandler.post(new Runnable() {
20003                @Override public void run() {
20004                    synchronized (ActivityManagerService.this) {
20005                        mProcessStats.writeStateAsyncLocked();
20006                    }
20007                }
20008            });
20009        }
20010
20011        if (DEBUG_OOM_ADJ) {
20012            final long duration = SystemClock.uptimeMillis() - now;
20013            if (false) {
20014                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20015                        new RuntimeException("here").fillInStackTrace());
20016            } else {
20017                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20018            }
20019        }
20020    }
20021
20022    final void idleUids() {
20023        synchronized (this) {
20024            final long nowElapsed = SystemClock.elapsedRealtime();
20025            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20026            long nextTime = 0;
20027            for (int i=mActiveUids.size()-1; i>=0; i--) {
20028                final UidRecord uidRec = mActiveUids.valueAt(i);
20029                final long bgTime = uidRec.lastBackgroundTime;
20030                if (bgTime > 0 && !uidRec.idle) {
20031                    if (bgTime <= maxBgTime) {
20032                        uidRec.idle = true;
20033                        doStopUidLocked(uidRec.uid, uidRec);
20034                    } else {
20035                        if (nextTime == 0 || nextTime > bgTime) {
20036                            nextTime = bgTime;
20037                        }
20038                    }
20039                }
20040            }
20041            if (nextTime > 0) {
20042                mHandler.removeMessages(IDLE_UIDS_MSG);
20043                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20044                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20045            }
20046        }
20047    }
20048
20049    final void runInBackgroundDisabled(int uid) {
20050        synchronized (this) {
20051            UidRecord uidRec = mActiveUids.get(uid);
20052            if (uidRec != null) {
20053                // This uid is actually running...  should it be considered background now?
20054                if (uidRec.idle) {
20055                    doStopUidLocked(uidRec.uid, uidRec);
20056                }
20057            } else {
20058                // This uid isn't actually running...  still send a report about it being "stopped".
20059                doStopUidLocked(uid, null);
20060            }
20061        }
20062    }
20063
20064    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20065        mServices.stopInBackgroundLocked(uid);
20066        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20067    }
20068
20069    final void trimApplications() {
20070        synchronized (this) {
20071            int i;
20072
20073            // First remove any unused application processes whose package
20074            // has been removed.
20075            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20076                final ProcessRecord app = mRemovedProcesses.get(i);
20077                if (app.activities.size() == 0
20078                        && app.curReceiver == null && app.services.size() == 0) {
20079                    Slog.i(
20080                        TAG, "Exiting empty application process "
20081                        + app.processName + " ("
20082                        + (app.thread != null ? app.thread.asBinder() : null)
20083                        + ")\n");
20084                    if (app.pid > 0 && app.pid != MY_PID) {
20085                        app.kill("empty", false);
20086                    } else {
20087                        try {
20088                            app.thread.scheduleExit();
20089                        } catch (Exception e) {
20090                            // Ignore exceptions.
20091                        }
20092                    }
20093                    cleanUpApplicationRecordLocked(app, false, true, -1);
20094                    mRemovedProcesses.remove(i);
20095
20096                    if (app.persistent) {
20097                        addAppLocked(app.info, false, null /* ABI override */);
20098                    }
20099                }
20100            }
20101
20102            // Now update the oom adj for all processes.
20103            updateOomAdjLocked();
20104        }
20105    }
20106
20107    /** This method sends the specified signal to each of the persistent apps */
20108    public void signalPersistentProcesses(int sig) throws RemoteException {
20109        if (sig != Process.SIGNAL_USR1) {
20110            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20111        }
20112
20113        synchronized (this) {
20114            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20115                    != PackageManager.PERMISSION_GRANTED) {
20116                throw new SecurityException("Requires permission "
20117                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20118            }
20119
20120            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20121                ProcessRecord r = mLruProcesses.get(i);
20122                if (r.thread != null && r.persistent) {
20123                    Process.sendSignal(r.pid, sig);
20124                }
20125            }
20126        }
20127    }
20128
20129    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20130        if (proc == null || proc == mProfileProc) {
20131            proc = mProfileProc;
20132            profileType = mProfileType;
20133            clearProfilerLocked();
20134        }
20135        if (proc == null) {
20136            return;
20137        }
20138        try {
20139            proc.thread.profilerControl(false, null, profileType);
20140        } catch (RemoteException e) {
20141            throw new IllegalStateException("Process disappeared");
20142        }
20143    }
20144
20145    private void clearProfilerLocked() {
20146        if (mProfileFd != null) {
20147            try {
20148                mProfileFd.close();
20149            } catch (IOException e) {
20150            }
20151        }
20152        mProfileApp = null;
20153        mProfileProc = null;
20154        mProfileFile = null;
20155        mProfileType = 0;
20156        mAutoStopProfiler = false;
20157        mSamplingInterval = 0;
20158    }
20159
20160    public boolean profileControl(String process, int userId, boolean start,
20161            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20162
20163        try {
20164            synchronized (this) {
20165                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20166                // its own permission.
20167                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20168                        != PackageManager.PERMISSION_GRANTED) {
20169                    throw new SecurityException("Requires permission "
20170                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20171                }
20172
20173                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20174                    throw new IllegalArgumentException("null profile info or fd");
20175                }
20176
20177                ProcessRecord proc = null;
20178                if (process != null) {
20179                    proc = findProcessLocked(process, userId, "profileControl");
20180                }
20181
20182                if (start && (proc == null || proc.thread == null)) {
20183                    throw new IllegalArgumentException("Unknown process: " + process);
20184                }
20185
20186                if (start) {
20187                    stopProfilerLocked(null, 0);
20188                    setProfileApp(proc.info, proc.processName, profilerInfo);
20189                    mProfileProc = proc;
20190                    mProfileType = profileType;
20191                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20192                    try {
20193                        fd = fd.dup();
20194                    } catch (IOException e) {
20195                        fd = null;
20196                    }
20197                    profilerInfo.profileFd = fd;
20198                    proc.thread.profilerControl(start, profilerInfo, profileType);
20199                    fd = null;
20200                    mProfileFd = null;
20201                } else {
20202                    stopProfilerLocked(proc, profileType);
20203                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20204                        try {
20205                            profilerInfo.profileFd.close();
20206                        } catch (IOException e) {
20207                        }
20208                    }
20209                }
20210
20211                return true;
20212            }
20213        } catch (RemoteException e) {
20214            throw new IllegalStateException("Process disappeared");
20215        } finally {
20216            if (profilerInfo != null && profilerInfo.profileFd != null) {
20217                try {
20218                    profilerInfo.profileFd.close();
20219                } catch (IOException e) {
20220                }
20221            }
20222        }
20223    }
20224
20225    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20226        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20227                userId, true, ALLOW_FULL_ONLY, callName, null);
20228        ProcessRecord proc = null;
20229        try {
20230            int pid = Integer.parseInt(process);
20231            synchronized (mPidsSelfLocked) {
20232                proc = mPidsSelfLocked.get(pid);
20233            }
20234        } catch (NumberFormatException e) {
20235        }
20236
20237        if (proc == null) {
20238            ArrayMap<String, SparseArray<ProcessRecord>> all
20239                    = mProcessNames.getMap();
20240            SparseArray<ProcessRecord> procs = all.get(process);
20241            if (procs != null && procs.size() > 0) {
20242                proc = procs.valueAt(0);
20243                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20244                    for (int i=1; i<procs.size(); i++) {
20245                        ProcessRecord thisProc = procs.valueAt(i);
20246                        if (thisProc.userId == userId) {
20247                            proc = thisProc;
20248                            break;
20249                        }
20250                    }
20251                }
20252            }
20253        }
20254
20255        return proc;
20256    }
20257
20258    public boolean dumpHeap(String process, int userId, boolean managed,
20259            String path, ParcelFileDescriptor fd) throws RemoteException {
20260
20261        try {
20262            synchronized (this) {
20263                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20264                // its own permission (same as profileControl).
20265                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20266                        != PackageManager.PERMISSION_GRANTED) {
20267                    throw new SecurityException("Requires permission "
20268                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20269                }
20270
20271                if (fd == null) {
20272                    throw new IllegalArgumentException("null fd");
20273                }
20274
20275                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20276                if (proc == null || proc.thread == null) {
20277                    throw new IllegalArgumentException("Unknown process: " + process);
20278                }
20279
20280                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20281                if (!isDebuggable) {
20282                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20283                        throw new SecurityException("Process not debuggable: " + proc);
20284                    }
20285                }
20286
20287                proc.thread.dumpHeap(managed, path, fd);
20288                fd = null;
20289                return true;
20290            }
20291        } catch (RemoteException e) {
20292            throw new IllegalStateException("Process disappeared");
20293        } finally {
20294            if (fd != null) {
20295                try {
20296                    fd.close();
20297                } catch (IOException e) {
20298                }
20299            }
20300        }
20301    }
20302
20303    @Override
20304    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20305            String reportPackage) {
20306        if (processName != null) {
20307            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20308                    "setDumpHeapDebugLimit()");
20309        } else {
20310            synchronized (mPidsSelfLocked) {
20311                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20312                if (proc == null) {
20313                    throw new SecurityException("No process found for calling pid "
20314                            + Binder.getCallingPid());
20315                }
20316                if (!Build.IS_DEBUGGABLE
20317                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20318                    throw new SecurityException("Not running a debuggable build");
20319                }
20320                processName = proc.processName;
20321                uid = proc.uid;
20322                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20323                    throw new SecurityException("Package " + reportPackage + " is not running in "
20324                            + proc);
20325                }
20326            }
20327        }
20328        synchronized (this) {
20329            if (maxMemSize > 0) {
20330                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20331            } else {
20332                if (uid != 0) {
20333                    mMemWatchProcesses.remove(processName, uid);
20334                } else {
20335                    mMemWatchProcesses.getMap().remove(processName);
20336                }
20337            }
20338        }
20339    }
20340
20341    @Override
20342    public void dumpHeapFinished(String path) {
20343        synchronized (this) {
20344            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20345                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20346                        + " does not match last pid " + mMemWatchDumpPid);
20347                return;
20348            }
20349            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20350                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20351                        + " does not match last path " + mMemWatchDumpFile);
20352                return;
20353            }
20354            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20355            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20356        }
20357    }
20358
20359    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20360    public void monitor() {
20361        synchronized (this) { }
20362    }
20363
20364    void onCoreSettingsChange(Bundle settings) {
20365        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20366            ProcessRecord processRecord = mLruProcesses.get(i);
20367            try {
20368                if (processRecord.thread != null) {
20369                    processRecord.thread.setCoreSettings(settings);
20370                }
20371            } catch (RemoteException re) {
20372                /* ignore */
20373            }
20374        }
20375    }
20376
20377    // Multi-user methods
20378
20379    /**
20380     * Start user, if its not already running, but don't bring it to foreground.
20381     */
20382    @Override
20383    public boolean startUserInBackground(final int userId) {
20384        return mUserController.startUser(userId, /* foreground */ false);
20385    }
20386
20387    @Override
20388    public boolean unlockUser(int userId, byte[] token) {
20389        return mUserController.unlockUser(userId, token);
20390    }
20391
20392    @Override
20393    public boolean switchUser(final int targetUserId) {
20394        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20395        UserInfo currentUserInfo;
20396        UserInfo targetUserInfo;
20397        synchronized (this) {
20398            int currentUserId = mUserController.getCurrentUserIdLocked();
20399            currentUserInfo = mUserController.getUserInfo(currentUserId);
20400            targetUserInfo = mUserController.getUserInfo(targetUserId);
20401            if (targetUserInfo == null) {
20402                Slog.w(TAG, "No user info for user #" + targetUserId);
20403                return false;
20404            }
20405            if (targetUserInfo.isManagedProfile()) {
20406                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20407                return false;
20408            }
20409            mUserController.setTargetUserIdLocked(targetUserId);
20410        }
20411        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20412        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20413        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20414        return true;
20415    }
20416
20417    void scheduleStartProfilesLocked() {
20418        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20419            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20420                    DateUtils.SECOND_IN_MILLIS);
20421        }
20422    }
20423
20424    @Override
20425    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20426        return mUserController.stopUser(userId, force, callback);
20427    }
20428
20429    void onUserRemovedLocked(int userId) {
20430        mRecentTasks.removeTasksForUserLocked(userId);
20431    }
20432
20433    @Override
20434    public UserInfo getCurrentUser() {
20435        return mUserController.getCurrentUser();
20436    }
20437
20438    @Override
20439    public boolean isUserRunning(int userId, int flags) {
20440        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20441                != PackageManager.PERMISSION_GRANTED) {
20442            String msg = "Permission Denial: isUserRunning() from pid="
20443                    + Binder.getCallingPid()
20444                    + ", uid=" + Binder.getCallingUid()
20445                    + " requires " + INTERACT_ACROSS_USERS;
20446            Slog.w(TAG, msg);
20447            throw new SecurityException(msg);
20448        }
20449        synchronized (this) {
20450            return mUserController.isUserRunningLocked(userId, flags);
20451        }
20452    }
20453
20454    @Override
20455    public int[] getRunningUserIds() {
20456        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20457                != PackageManager.PERMISSION_GRANTED) {
20458            String msg = "Permission Denial: isUserRunning() from pid="
20459                    + Binder.getCallingPid()
20460                    + ", uid=" + Binder.getCallingUid()
20461                    + " requires " + INTERACT_ACROSS_USERS;
20462            Slog.w(TAG, msg);
20463            throw new SecurityException(msg);
20464        }
20465        synchronized (this) {
20466            return mUserController.getStartedUserArrayLocked();
20467        }
20468    }
20469
20470    @Override
20471    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20472        mUserController.registerUserSwitchObserver(observer);
20473    }
20474
20475    @Override
20476    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20477        mUserController.unregisterUserSwitchObserver(observer);
20478    }
20479
20480    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20481        if (info == null) return null;
20482        ApplicationInfo newInfo = new ApplicationInfo(info);
20483        newInfo.initForUser(userId);
20484        return newInfo;
20485    }
20486
20487    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20488        if (aInfo == null
20489                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20490            return aInfo;
20491        }
20492
20493        ActivityInfo info = new ActivityInfo(aInfo);
20494        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20495        return info;
20496    }
20497
20498    private boolean processSanityChecksLocked(ProcessRecord process) {
20499        if (process == null || process.thread == null) {
20500            return false;
20501        }
20502
20503        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20504        if (!isDebuggable) {
20505            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20506                return false;
20507            }
20508        }
20509
20510        return true;
20511    }
20512
20513    public boolean startBinderTracking() throws RemoteException {
20514        synchronized (this) {
20515            mBinderTransactionTrackingEnabled = true;
20516            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20517            // permission (same as profileControl).
20518            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20519                    != PackageManager.PERMISSION_GRANTED) {
20520                throw new SecurityException("Requires permission "
20521                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20522            }
20523
20524            for (int i = 0; i < mLruProcesses.size(); i++) {
20525                ProcessRecord process = mLruProcesses.get(i);
20526                if (!processSanityChecksLocked(process)) {
20527                    continue;
20528                }
20529                try {
20530                    process.thread.startBinderTracking();
20531                } catch (RemoteException e) {
20532                    Log.v(TAG, "Process disappared");
20533                }
20534            }
20535            return true;
20536        }
20537    }
20538
20539    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20540        try {
20541            synchronized (this) {
20542                mBinderTransactionTrackingEnabled = false;
20543                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20544                // permission (same as profileControl).
20545                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20546                        != PackageManager.PERMISSION_GRANTED) {
20547                    throw new SecurityException("Requires permission "
20548                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20549                }
20550
20551                if (fd == null) {
20552                    throw new IllegalArgumentException("null fd");
20553                }
20554
20555                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20556                pw.println("Binder transaction traces for all processes.\n");
20557                for (ProcessRecord process : mLruProcesses) {
20558                    if (!processSanityChecksLocked(process)) {
20559                        continue;
20560                    }
20561
20562                    pw.println("Traces for process: " + process.processName);
20563                    pw.flush();
20564                    try {
20565                        TransferPipe tp = new TransferPipe();
20566                        try {
20567                            process.thread.stopBinderTrackingAndDump(
20568                                    tp.getWriteFd().getFileDescriptor());
20569                            tp.go(fd.getFileDescriptor());
20570                        } finally {
20571                            tp.kill();
20572                        }
20573                    } catch (IOException e) {
20574                        pw.println("Failure while dumping IPC traces from " + process +
20575                                ".  Exception: " + e);
20576                        pw.flush();
20577                    } catch (RemoteException e) {
20578                        pw.println("Got a RemoteException while dumping IPC traces from " +
20579                                process + ".  Exception: " + e);
20580                        pw.flush();
20581                    }
20582                }
20583                fd = null;
20584                return true;
20585            }
20586        } finally {
20587            if (fd != null) {
20588                try {
20589                    fd.close();
20590                } catch (IOException e) {
20591                }
20592            }
20593        }
20594    }
20595
20596    void stopReportingCrashesLocked(ProcessRecord proc) {
20597        if (mAppsNotReportingCrashes == null) {
20598            mAppsNotReportingCrashes = new ArraySet<>();
20599        }
20600        mAppsNotReportingCrashes.add(proc.info.packageName);
20601    }
20602
20603    private final class LocalService extends ActivityManagerInternal {
20604        @Override
20605        public void onWakefulnessChanged(int wakefulness) {
20606            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20607        }
20608
20609        @Override
20610        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20611                String processName, String abiOverride, int uid, Runnable crashHandler) {
20612            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20613                    processName, abiOverride, uid, crashHandler);
20614        }
20615
20616        @Override
20617        public SleepToken acquireSleepToken(String tag) {
20618            Preconditions.checkNotNull(tag);
20619
20620            synchronized (ActivityManagerService.this) {
20621                SleepTokenImpl token = new SleepTokenImpl(tag);
20622                mSleepTokens.add(token);
20623                updateSleepIfNeededLocked();
20624                return token;
20625            }
20626        }
20627
20628        @Override
20629        public ComponentName getHomeActivityForUser(int userId) {
20630            synchronized (ActivityManagerService.this) {
20631                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20632                return homeActivity == null ? null : homeActivity.realActivity;
20633            }
20634        }
20635
20636        @Override
20637        public void onUserRemoved(int userId) {
20638            synchronized (ActivityManagerService.this) {
20639                ActivityManagerService.this.onUserRemovedLocked(userId);
20640            }
20641        }
20642    }
20643
20644    private final class SleepTokenImpl extends SleepToken {
20645        private final String mTag;
20646        private final long mAcquireTime;
20647
20648        public SleepTokenImpl(String tag) {
20649            mTag = tag;
20650            mAcquireTime = SystemClock.uptimeMillis();
20651        }
20652
20653        @Override
20654        public void release() {
20655            synchronized (ActivityManagerService.this) {
20656                if (mSleepTokens.remove(this)) {
20657                    updateSleepIfNeededLocked();
20658                }
20659            }
20660        }
20661
20662        @Override
20663        public String toString() {
20664            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20665        }
20666    }
20667
20668    /**
20669     * An implementation of IAppTask, that allows an app to manage its own tasks via
20670     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20671     * only the process that calls getAppTasks() can call the AppTask methods.
20672     */
20673    class AppTaskImpl extends IAppTask.Stub {
20674        private int mTaskId;
20675        private int mCallingUid;
20676
20677        public AppTaskImpl(int taskId, int callingUid) {
20678            mTaskId = taskId;
20679            mCallingUid = callingUid;
20680        }
20681
20682        private void checkCaller() {
20683            if (mCallingUid != Binder.getCallingUid()) {
20684                throw new SecurityException("Caller " + mCallingUid
20685                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20686            }
20687        }
20688
20689        @Override
20690        public void finishAndRemoveTask() {
20691            checkCaller();
20692
20693            synchronized (ActivityManagerService.this) {
20694                long origId = Binder.clearCallingIdentity();
20695                try {
20696                    // We remove the task from recents to preserve backwards
20697                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
20698                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20699                    }
20700                } finally {
20701                    Binder.restoreCallingIdentity(origId);
20702                }
20703            }
20704        }
20705
20706        @Override
20707        public ActivityManager.RecentTaskInfo getTaskInfo() {
20708            checkCaller();
20709
20710            synchronized (ActivityManagerService.this) {
20711                long origId = Binder.clearCallingIdentity();
20712                try {
20713                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20714                    if (tr == null) {
20715                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20716                    }
20717                    return createRecentTaskInfoFromTaskRecord(tr);
20718                } finally {
20719                    Binder.restoreCallingIdentity(origId);
20720                }
20721            }
20722        }
20723
20724        @Override
20725        public void moveToFront() {
20726            checkCaller();
20727            // Will bring task to front if it already has a root activity.
20728            startActivityFromRecentsInner(mTaskId, INVALID_STACK_ID, null);
20729        }
20730
20731        @Override
20732        public int startActivity(IBinder whoThread, String callingPackage,
20733                Intent intent, String resolvedType, Bundle bOptions) {
20734            checkCaller();
20735
20736            int callingUser = UserHandle.getCallingUserId();
20737            TaskRecord tr;
20738            IApplicationThread appThread;
20739            synchronized (ActivityManagerService.this) {
20740                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20741                if (tr == null) {
20742                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20743                }
20744                appThread = ApplicationThreadNative.asInterface(whoThread);
20745                if (appThread == null) {
20746                    throw new IllegalArgumentException("Bad app thread " + appThread);
20747                }
20748            }
20749            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20750                    resolvedType, null, null, null, null, 0, 0, null, null,
20751                    null, bOptions, false, callingUser, null, tr);
20752        }
20753
20754        @Override
20755        public void setExcludeFromRecents(boolean exclude) {
20756            checkCaller();
20757
20758            synchronized (ActivityManagerService.this) {
20759                long origId = Binder.clearCallingIdentity();
20760                try {
20761                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20762                    if (tr == null) {
20763                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20764                    }
20765                    Intent intent = tr.getBaseIntent();
20766                    if (exclude) {
20767                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20768                    } else {
20769                        intent.setFlags(intent.getFlags()
20770                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20771                    }
20772                } finally {
20773                    Binder.restoreCallingIdentity(origId);
20774                }
20775            }
20776        }
20777    }
20778}
20779