ActivityManagerService.java revision 8924e8759f9a8cffb5ad538ca40a7826793aac07
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.ParceledListSlice;
133import android.content.pm.PathPermission;
134import android.content.pm.PermissionInfo;
135import android.content.pm.ProviderInfo;
136import android.content.pm.ResolveInfo;
137import android.content.pm.ServiceInfo;
138import android.content.pm.UserInfo;
139import android.content.res.CompatibilityInfo;
140import android.content.res.Configuration;
141import android.content.res.Resources;
142import android.graphics.Bitmap;
143import android.graphics.Point;
144import android.graphics.Rect;
145import android.net.Proxy;
146import android.net.ProxyInfo;
147import android.net.Uri;
148import android.os.BatteryStats;
149import android.os.Binder;
150import android.os.Build;
151import android.os.Bundle;
152import android.os.Debug;
153import android.os.DropBoxManager;
154import android.os.Environment;
155import android.os.FactoryTest;
156import android.os.FileObserver;
157import android.os.FileUtils;
158import android.os.Handler;
159import android.os.IBinder;
160import android.os.IPermissionController;
161import android.os.IProcessInfoService;
162import android.os.Looper;
163import android.os.Message;
164import android.os.Parcel;
165import android.os.ParcelFileDescriptor;
166import android.os.PersistableBundle;
167import android.os.PowerManager;
168import android.os.PowerManagerInternal;
169import android.os.Process;
170import android.os.RemoteCallbackList;
171import android.os.RemoteException;
172import android.os.ResultReceiver;
173import android.os.ServiceManager;
174import android.os.StrictMode;
175import android.os.SystemClock;
176import android.os.SystemProperties;
177import android.os.Trace;
178import android.os.TransactionTooLargeException;
179import android.os.UpdateLock;
180import android.os.UserHandle;
181import android.os.UserManager;
182import android.os.WorkSource;
183import android.os.storage.IMountService;
184import android.os.storage.MountServiceInternal;
185import android.os.storage.StorageManager;
186import android.provider.Settings;
187import android.service.voice.IVoiceInteractionSession;
188import android.service.voice.VoiceInteractionSession;
189import android.text.format.DateUtils;
190import android.text.format.Time;
191import android.util.ArrayMap;
192import android.util.ArraySet;
193import android.util.AtomicFile;
194import android.util.DebugUtils;
195import android.util.EventLog;
196import android.util.LocaleList;
197import android.util.Log;
198import android.util.Pair;
199import android.util.PrintWriterPrinter;
200import android.util.Slog;
201import android.util.SparseArray;
202import android.util.TimeUtils;
203import android.util.Xml;
204import android.view.Display;
205import android.view.Gravity;
206import android.view.LayoutInflater;
207import android.view.View;
208import android.view.WindowManager;
209
210import java.io.BufferedInputStream;
211import java.io.BufferedOutputStream;
212import java.io.DataInputStream;
213import java.io.DataOutputStream;
214import java.io.File;
215import java.io.FileDescriptor;
216import java.io.FileInputStream;
217import java.io.FileNotFoundException;
218import java.io.FileOutputStream;
219import java.io.IOException;
220import java.io.InputStreamReader;
221import java.io.PrintWriter;
222import java.io.StringWriter;
223import java.lang.ref.WeakReference;
224import java.nio.charset.StandardCharsets;
225import java.util.ArrayList;
226import java.util.Arrays;
227import java.util.Collections;
228import java.util.Comparator;
229import java.util.HashMap;
230import java.util.HashSet;
231import java.util.Iterator;
232import java.util.List;
233import java.util.Locale;
234import java.util.Map;
235import java.util.Set;
236import java.util.concurrent.atomic.AtomicBoolean;
237import java.util.concurrent.atomic.AtomicLong;
238
239import dalvik.system.VMRuntime;
240import libcore.io.IoUtils;
241import libcore.util.EmptyArray;
242
243import static android.Manifest.permission.INTERACT_ACROSS_USERS;
244import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
245import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
246import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
247import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
248import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
249import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
250import static android.app.ActivityManager.StackId.HOME_STACK_ID;
251import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
252import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
253import static android.content.pm.PackageManager.PERMISSION_GRANTED;
254import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
255import static android.provider.Settings.Global.DEBUG_APP;
256import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
257import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
258import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
259import static com.android.internal.util.XmlUtils.readBooleanAttribute;
260import static com.android.internal.util.XmlUtils.readIntAttribute;
261import static com.android.internal.util.XmlUtils.readLongAttribute;
262import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
263import static com.android.internal.util.XmlUtils.writeIntAttribute;
264import static com.android.internal.util.XmlUtils.writeLongAttribute;
265import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
266import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
267import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
268import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
269import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
270import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
271import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
272import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
273import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
274import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
275import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
276import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
277import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
278import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
279import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
280import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
281import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
282import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
283import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
284import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
285import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
286import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
287import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
296import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
297import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
298import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
299import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
300import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
301import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
302import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
303import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
304import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
305import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
306import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
307import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
308import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
309import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
310import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
311import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
312import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
313import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
314import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
315import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
316import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
317import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
318import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
319import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
320import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
321import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
322import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
323import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
324import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
325import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
326import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
327import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
328import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
329import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
330import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
331import static org.xmlpull.v1.XmlPullParser.START_TAG;
332
333public final class ActivityManagerService extends ActivityManagerNative
334        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
335
336    // File that stores last updated system version and called preboot receivers
337    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
338
339    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
340    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
341    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
342    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
343    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
344    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
345    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
346    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
347    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
348    private static final String TAG_LRU = TAG + POSTFIX_LRU;
349    private static final String TAG_MU = TAG + POSTFIX_MU;
350    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
351    private static final String TAG_POWER = TAG + POSTFIX_POWER;
352    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
353    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
354    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
355    private static final String TAG_PSS = TAG + POSTFIX_PSS;
356    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
357    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
358    private static final String TAG_STACK = TAG + POSTFIX_STACK;
359    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
360    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
361    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
362    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
363    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
364
365    /** Control over CPU and battery monitoring */
366    // write battery stats every 30 minutes.
367    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
368    static final boolean MONITOR_CPU_USAGE = true;
369    // don't sample cpu less than every 5 seconds.
370    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
371    // wait possibly forever for next cpu sample.
372    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
373    static final boolean MONITOR_THREAD_CPU_USAGE = false;
374
375    // The flags that are set for all calls we make to the package manager.
376    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
377
378    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
379
380    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
381
382    // Amount of time after a call to stopAppSwitches() during which we will
383    // prevent further untrusted switches from happening.
384    static final long APP_SWITCH_DELAY_TIME = 5*1000;
385
386    // How long we wait for a launched process to attach to the activity manager
387    // before we decide it's never going to come up for real.
388    static final int PROC_START_TIMEOUT = 10*1000;
389    // How long we wait for an attached process to publish its content providers
390    // before we decide it must be hung.
391    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
392
393    // How long we will retain processes hosting content providers in the "last activity"
394    // state before allowing them to drop down to the regular cached LRU list.  This is
395    // to avoid thrashing of provider processes under low memory situations.
396    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
397
398    // How long we wait for a launched process to attach to the activity manager
399    // before we decide it's never going to come up for real, when the process was
400    // started with a wrapper for instrumentation (such as Valgrind) because it
401    // could take much longer than usual.
402    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
403
404    // How long to wait after going idle before forcing apps to GC.
405    static final int GC_TIMEOUT = 5*1000;
406
407    // The minimum amount of time between successive GC requests for a process.
408    static final int GC_MIN_INTERVAL = 60*1000;
409
410    // The minimum amount of time between successive PSS requests for a process.
411    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
412
413    // The minimum amount of time between successive PSS requests for a process
414    // when the request is due to the memory state being lowered.
415    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
416
417    // The rate at which we check for apps using excessive power -- 15 mins.
418    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
419
420    // The minimum sample duration we will allow before deciding we have
421    // enough data on wake locks to start killing things.
422    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
423
424    // The minimum sample duration we will allow before deciding we have
425    // enough data on CPU usage to start killing things.
426    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
427
428    // How long we allow a receiver to run before giving up on it.
429    static final int BROADCAST_FG_TIMEOUT = 10*1000;
430    static final int BROADCAST_BG_TIMEOUT = 60*1000;
431
432    // How long we wait until we timeout on key dispatching.
433    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
434
435    // How long we wait until we timeout on key dispatching during instrumentation.
436    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
437
438    // This is the amount of time an app needs to be running a foreground service before
439    // we will consider it to be doing interaction for usage stats.
440    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
441
442    // Maximum amount of time we will allow to elapse before re-reporting usage stats
443    // interaction with foreground processes.
444    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
445
446    // Maximum number of users we allow to be running at a time.
447    static final int MAX_RUNNING_USERS = 3;
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
1435    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1436    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1437    static final int FIRST_COMPAT_MODE_MSG = 300;
1438    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1439
1440    CompatModeDialog mCompatModeDialog;
1441    long mLastMemUsageReportTime = 0;
1442
1443    /**
1444     * Flag whether the current user is a "monkey", i.e. whether
1445     * the UI is driven by a UI automation tool.
1446     */
1447    private boolean mUserIsMonkey;
1448
1449    /** Flag whether the device has a Recents UI */
1450    boolean mHasRecents;
1451
1452    /** The dimensions of the thumbnails in the Recents UI. */
1453    int mThumbnailWidth;
1454    int mThumbnailHeight;
1455
1456    final ServiceThread mHandlerThread;
1457    final MainHandler mHandler;
1458    final UiHandler mUiHandler;
1459
1460    final class UiHandler extends Handler {
1461        public UiHandler() {
1462            super(com.android.server.UiThread.get().getLooper(), null, true);
1463        }
1464
1465        @Override
1466        public void handleMessage(Message msg) {
1467            switch (msg.what) {
1468            case SHOW_ERROR_UI_MSG: {
1469                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1470                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1471                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1472                synchronized (ActivityManagerService.this) {
1473                    ProcessRecord proc = (ProcessRecord)data.get("app");
1474                    AppErrorResult res = (AppErrorResult) data.get("result");
1475                    if (proc != null && proc.crashDialog != null) {
1476                        Slog.e(TAG, "App already has crash dialog: " + proc);
1477                        if (res != null) {
1478                            res.set(0);
1479                        }
1480                        return;
1481                    }
1482                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1483                            >= Process.FIRST_APPLICATION_UID
1484                            && proc.pid != MY_PID);
1485                    for (int userId : mUserController.getCurrentProfileIdsLocked()) {
1486                        isBackground &= (proc.userId != userId);
1487                    }
1488                    if (isBackground && !showBackground) {
1489                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1490                        if (res != null) {
1491                            res.set(0);
1492                        }
1493                        return;
1494                    }
1495                    final boolean crashSilenced = mAppsNotReportingCrashes != null &&
1496                            mAppsNotReportingCrashes.contains(proc.info.packageName);
1497                    if (mShowDialogs && !mSleeping && !mShuttingDown && !crashSilenced) {
1498                        Dialog d = new AppErrorDialog(mContext,
1499                                ActivityManagerService.this, res, proc);
1500                        d.show();
1501                        proc.crashDialog = d;
1502                    } else {
1503                        // The device is asleep, so just pretend that the user
1504                        // saw a crash dialog and hit "force quit".
1505                        if (res != null) {
1506                            res.set(0);
1507                        }
1508                    }
1509                }
1510
1511                ensureBootCompleted();
1512            } break;
1513            case SHOW_NOT_RESPONDING_UI_MSG: {
1514                synchronized (ActivityManagerService.this) {
1515                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1516                    ProcessRecord proc = (ProcessRecord)data.get("app");
1517                    if (proc != null && proc.anrDialog != null) {
1518                        Slog.e(TAG, "App already has anr dialog: " + proc);
1519                        return;
1520                    }
1521
1522                    Intent intent = new Intent("android.intent.action.ANR");
1523                    if (!mProcessesReady) {
1524                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1525                                | Intent.FLAG_RECEIVER_FOREGROUND);
1526                    }
1527                    broadcastIntentLocked(null, null, intent,
1528                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1529                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1530
1531                    if (mShowDialogs) {
1532                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1533                                mContext, proc, (ActivityRecord)data.get("activity"),
1534                                msg.arg1 != 0);
1535                        d.show();
1536                        proc.anrDialog = d;
1537                    } else {
1538                        // Just kill the app if there is no dialog to be shown.
1539                        killAppAtUsersRequest(proc, null);
1540                    }
1541                }
1542
1543                ensureBootCompleted();
1544            } break;
1545            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1546                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1547                synchronized (ActivityManagerService.this) {
1548                    ProcessRecord proc = (ProcessRecord) data.get("app");
1549                    if (proc == null) {
1550                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1551                        break;
1552                    }
1553                    if (proc.crashDialog != null) {
1554                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1555                        return;
1556                    }
1557                    AppErrorResult res = (AppErrorResult) data.get("result");
1558                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1559                        Dialog d = new StrictModeViolationDialog(mContext,
1560                                ActivityManagerService.this, res, proc);
1561                        d.show();
1562                        proc.crashDialog = d;
1563                    } else {
1564                        // The device is asleep, so just pretend that the user
1565                        // saw a crash dialog and hit "force quit".
1566                        res.set(0);
1567                    }
1568                }
1569                ensureBootCompleted();
1570            } break;
1571            case SHOW_FACTORY_ERROR_UI_MSG: {
1572                Dialog d = new FactoryErrorDialog(
1573                    mContext, msg.getData().getCharSequence("msg"));
1574                d.show();
1575                ensureBootCompleted();
1576            } break;
1577            case WAIT_FOR_DEBUGGER_UI_MSG: {
1578                synchronized (ActivityManagerService.this) {
1579                    ProcessRecord app = (ProcessRecord)msg.obj;
1580                    if (msg.arg1 != 0) {
1581                        if (!app.waitedForDebugger) {
1582                            Dialog d = new AppWaitingForDebuggerDialog(
1583                                    ActivityManagerService.this,
1584                                    mContext, app);
1585                            app.waitDialog = d;
1586                            app.waitedForDebugger = true;
1587                            d.show();
1588                        }
1589                    } else {
1590                        if (app.waitDialog != null) {
1591                            app.waitDialog.dismiss();
1592                            app.waitDialog = null;
1593                        }
1594                    }
1595                }
1596            } break;
1597            case SHOW_UID_ERROR_UI_MSG: {
1598                if (mShowDialogs) {
1599                    AlertDialog d = new BaseErrorDialog(mContext);
1600                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1601                    d.setCancelable(false);
1602                    d.setTitle(mContext.getText(R.string.android_system_label));
1603                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1604                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1605                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1606                    d.show();
1607                }
1608            } break;
1609            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1610                if (mShowDialogs) {
1611                    AlertDialog d = new BaseErrorDialog(mContext);
1612                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1613                    d.setCancelable(false);
1614                    d.setTitle(mContext.getText(R.string.android_system_label));
1615                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1616                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1617                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1618                    d.show();
1619                }
1620            } break;
1621            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1622                synchronized (ActivityManagerService.this) {
1623                    ActivityRecord ar = (ActivityRecord) msg.obj;
1624                    if (mCompatModeDialog != null) {
1625                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1626                                ar.info.applicationInfo.packageName)) {
1627                            return;
1628                        }
1629                        mCompatModeDialog.dismiss();
1630                        mCompatModeDialog = null;
1631                    }
1632                    if (ar != null && false) {
1633                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1634                                ar.packageName)) {
1635                            int mode = mCompatModePackages.computeCompatModeLocked(
1636                                    ar.info.applicationInfo);
1637                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1638                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1639                                mCompatModeDialog = new CompatModeDialog(
1640                                        ActivityManagerService.this, mContext,
1641                                        ar.info.applicationInfo);
1642                                mCompatModeDialog.show();
1643                            }
1644                        }
1645                    }
1646                }
1647                break;
1648            }
1649            case START_USER_SWITCH_UI_MSG: {
1650                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1651                break;
1652            }
1653            case DISMISS_DIALOG_UI_MSG: {
1654                final Dialog d = (Dialog) msg.obj;
1655                d.dismiss();
1656                break;
1657            }
1658            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1659                dispatchProcessesChanged();
1660                break;
1661            }
1662            case DISPATCH_PROCESS_DIED_UI_MSG: {
1663                final int pid = msg.arg1;
1664                final int uid = msg.arg2;
1665                dispatchProcessDied(pid, uid);
1666                break;
1667            }
1668            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1669                dispatchUidsChanged();
1670            } break;
1671            }
1672        }
1673    }
1674
1675    final class MainHandler extends Handler {
1676        public MainHandler(Looper looper) {
1677            super(looper, null, true);
1678        }
1679
1680        @Override
1681        public void handleMessage(Message msg) {
1682            switch (msg.what) {
1683            case UPDATE_CONFIGURATION_MSG: {
1684                final ContentResolver resolver = mContext.getContentResolver();
1685                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1686                        msg.arg1);
1687            } break;
1688            case GC_BACKGROUND_PROCESSES_MSG: {
1689                synchronized (ActivityManagerService.this) {
1690                    performAppGcsIfAppropriateLocked();
1691                }
1692            } break;
1693            case SERVICE_TIMEOUT_MSG: {
1694                if (mDidDexOpt) {
1695                    mDidDexOpt = false;
1696                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1697                    nmsg.obj = msg.obj;
1698                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1699                    return;
1700                }
1701                mServices.serviceTimeout((ProcessRecord)msg.obj);
1702            } break;
1703            case UPDATE_TIME_ZONE: {
1704                synchronized (ActivityManagerService.this) {
1705                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1706                        ProcessRecord r = mLruProcesses.get(i);
1707                        if (r.thread != null) {
1708                            try {
1709                                r.thread.updateTimeZone();
1710                            } catch (RemoteException ex) {
1711                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1712                            }
1713                        }
1714                    }
1715                }
1716            } break;
1717            case CLEAR_DNS_CACHE_MSG: {
1718                synchronized (ActivityManagerService.this) {
1719                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1720                        ProcessRecord r = mLruProcesses.get(i);
1721                        if (r.thread != null) {
1722                            try {
1723                                r.thread.clearDnsCache();
1724                            } catch (RemoteException ex) {
1725                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1726                            }
1727                        }
1728                    }
1729                }
1730            } break;
1731            case UPDATE_HTTP_PROXY_MSG: {
1732                ProxyInfo proxy = (ProxyInfo)msg.obj;
1733                String host = "";
1734                String port = "";
1735                String exclList = "";
1736                Uri pacFileUrl = Uri.EMPTY;
1737                if (proxy != null) {
1738                    host = proxy.getHost();
1739                    port = Integer.toString(proxy.getPort());
1740                    exclList = proxy.getExclusionListAsString();
1741                    pacFileUrl = proxy.getPacFileUrl();
1742                }
1743                synchronized (ActivityManagerService.this) {
1744                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1745                        ProcessRecord r = mLruProcesses.get(i);
1746                        if (r.thread != null) {
1747                            try {
1748                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1749                            } catch (RemoteException ex) {
1750                                Slog.w(TAG, "Failed to update http proxy for: " +
1751                                        r.info.processName);
1752                            }
1753                        }
1754                    }
1755                }
1756            } break;
1757            case PROC_START_TIMEOUT_MSG: {
1758                if (mDidDexOpt) {
1759                    mDidDexOpt = false;
1760                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1761                    nmsg.obj = msg.obj;
1762                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1763                    return;
1764                }
1765                ProcessRecord app = (ProcessRecord)msg.obj;
1766                synchronized (ActivityManagerService.this) {
1767                    processStartTimedOutLocked(app);
1768                }
1769            } break;
1770            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1771                ProcessRecord app = (ProcessRecord)msg.obj;
1772                synchronized (ActivityManagerService.this) {
1773                    processContentProviderPublishTimedOutLocked(app);
1774                }
1775            } break;
1776            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1777                synchronized (ActivityManagerService.this) {
1778                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1779                }
1780            } break;
1781            case KILL_APPLICATION_MSG: {
1782                synchronized (ActivityManagerService.this) {
1783                    int appid = msg.arg1;
1784                    boolean restart = (msg.arg2 == 1);
1785                    Bundle bundle = (Bundle)msg.obj;
1786                    String pkg = bundle.getString("pkg");
1787                    String reason = bundle.getString("reason");
1788                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1789                            false, UserHandle.USER_ALL, reason);
1790                }
1791            } break;
1792            case FINALIZE_PENDING_INTENT_MSG: {
1793                ((PendingIntentRecord)msg.obj).completeFinalize();
1794            } break;
1795            case POST_HEAVY_NOTIFICATION_MSG: {
1796                INotificationManager inm = NotificationManager.getService();
1797                if (inm == null) {
1798                    return;
1799                }
1800
1801                ActivityRecord root = (ActivityRecord)msg.obj;
1802                ProcessRecord process = root.app;
1803                if (process == null) {
1804                    return;
1805                }
1806
1807                try {
1808                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1809                    String text = mContext.getString(R.string.heavy_weight_notification,
1810                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1811                    Notification notification = new Notification.Builder(context)
1812                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1813                            .setWhen(0)
1814                            .setOngoing(true)
1815                            .setTicker(text)
1816                            .setColor(mContext.getColor(
1817                                    com.android.internal.R.color.system_notification_accent_color))
1818                            .setContentTitle(text)
1819                            .setContentText(
1820                                    mContext.getText(R.string.heavy_weight_notification_detail))
1821                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1822                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1823                                    new UserHandle(root.userId)))
1824                            .build();
1825                    try {
1826                        int[] outId = new int[1];
1827                        inm.enqueueNotificationWithTag("android", "android", null,
1828                                R.string.heavy_weight_notification,
1829                                notification, outId, root.userId);
1830                    } catch (RuntimeException e) {
1831                        Slog.w(ActivityManagerService.TAG,
1832                                "Error showing notification for heavy-weight app", e);
1833                    } catch (RemoteException e) {
1834                    }
1835                } catch (NameNotFoundException e) {
1836                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1837                }
1838            } break;
1839            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1840                INotificationManager inm = NotificationManager.getService();
1841                if (inm == null) {
1842                    return;
1843                }
1844                try {
1845                    inm.cancelNotificationWithTag("android", null,
1846                            R.string.heavy_weight_notification,  msg.arg1);
1847                } catch (RuntimeException e) {
1848                    Slog.w(ActivityManagerService.TAG,
1849                            "Error canceling notification for service", e);
1850                } catch (RemoteException e) {
1851                }
1852            } break;
1853            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1854                synchronized (ActivityManagerService.this) {
1855                    checkExcessivePowerUsageLocked(true);
1856                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1857                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1858                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1859                }
1860            } break;
1861            case REPORT_MEM_USAGE_MSG: {
1862                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1863                Thread thread = new Thread() {
1864                    @Override public void run() {
1865                        reportMemUsage(memInfos);
1866                    }
1867                };
1868                thread.start();
1869                break;
1870            }
1871            case REPORT_USER_SWITCH_MSG: {
1872                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1873                break;
1874            }
1875            case CONTINUE_USER_SWITCH_MSG: {
1876                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1877                break;
1878            }
1879            case USER_SWITCH_TIMEOUT_MSG: {
1880                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1881                break;
1882            }
1883            case IMMERSIVE_MODE_LOCK_MSG: {
1884                final boolean nextState = (msg.arg1 != 0);
1885                if (mUpdateLock.isHeld() != nextState) {
1886                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1887                            "Applying new update lock state '" + nextState
1888                            + "' for " + (ActivityRecord)msg.obj);
1889                    if (nextState) {
1890                        mUpdateLock.acquire();
1891                    } else {
1892                        mUpdateLock.release();
1893                    }
1894                }
1895                break;
1896            }
1897            case PERSIST_URI_GRANTS_MSG: {
1898                writeGrantedUriPermissions();
1899                break;
1900            }
1901            case REQUEST_ALL_PSS_MSG: {
1902                synchronized (ActivityManagerService.this) {
1903                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1904                }
1905                break;
1906            }
1907            case START_PROFILES_MSG: {
1908                synchronized (ActivityManagerService.this) {
1909                    mUserController.startProfilesLocked();
1910                }
1911                break;
1912            }
1913            case UPDATE_TIME: {
1914                synchronized (ActivityManagerService.this) {
1915                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1916                        ProcessRecord r = mLruProcesses.get(i);
1917                        if (r.thread != null) {
1918                            try {
1919                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1920                            } catch (RemoteException ex) {
1921                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1922                            }
1923                        }
1924                    }
1925                }
1926                break;
1927            }
1928            case SYSTEM_USER_START_MSG: {
1929                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1930                        Integer.toString(msg.arg1), msg.arg1);
1931                mSystemServiceManager.startUser(msg.arg1);
1932                break;
1933            }
1934            case SYSTEM_USER_CURRENT_MSG: {
1935                mBatteryStatsService.noteEvent(
1936                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1937                        Integer.toString(msg.arg2), msg.arg2);
1938                mBatteryStatsService.noteEvent(
1939                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1940                        Integer.toString(msg.arg1), msg.arg1);
1941                mSystemServiceManager.switchUser(msg.arg1);
1942                break;
1943            }
1944            case ENTER_ANIMATION_COMPLETE_MSG: {
1945                synchronized (ActivityManagerService.this) {
1946                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1947                    if (r != null && r.app != null && r.app.thread != null) {
1948                        try {
1949                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1950                        } catch (RemoteException e) {
1951                        }
1952                    }
1953                }
1954                break;
1955            }
1956            case FINISH_BOOTING_MSG: {
1957                if (msg.arg1 != 0) {
1958                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1959                    finishBooting();
1960                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1961                }
1962                if (msg.arg2 != 0) {
1963                    enableScreenAfterBoot();
1964                }
1965                break;
1966            }
1967            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1968                try {
1969                    Locale l = (Locale) msg.obj;
1970                    IBinder service = ServiceManager.getService("mount");
1971                    IMountService mountService = IMountService.Stub.asInterface(service);
1972                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1973                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1974                } catch (RemoteException e) {
1975                    Log.e(TAG, "Error storing locale for decryption UI", e);
1976                }
1977                break;
1978            }
1979            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1980                synchronized (ActivityManagerService.this) {
1981                    int i = mTaskStackListeners.beginBroadcast();
1982                    while (i > 0) {
1983                        i--;
1984                        try {
1985                            // Make a one-way callback to the listener
1986                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1987                        } catch (RemoteException e){
1988                            // Handled by the RemoteCallbackList
1989                        }
1990                    }
1991                    mTaskStackListeners.finishBroadcast();
1992                }
1993                break;
1994            }
1995            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1996                final int uid = msg.arg1;
1997                final byte[] firstPacket = (byte[]) msg.obj;
1998
1999                synchronized (mPidsSelfLocked) {
2000                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2001                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2002                        if (p.uid == uid) {
2003                            try {
2004                                p.thread.notifyCleartextNetwork(firstPacket);
2005                            } catch (RemoteException ignored) {
2006                            }
2007                        }
2008                    }
2009                }
2010                break;
2011            }
2012            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2013                final String procName;
2014                final int uid;
2015                final long memLimit;
2016                final String reportPackage;
2017                synchronized (ActivityManagerService.this) {
2018                    procName = mMemWatchDumpProcName;
2019                    uid = mMemWatchDumpUid;
2020                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2021                    if (val == null) {
2022                        val = mMemWatchProcesses.get(procName, 0);
2023                    }
2024                    if (val != null) {
2025                        memLimit = val.first;
2026                        reportPackage = val.second;
2027                    } else {
2028                        memLimit = 0;
2029                        reportPackage = null;
2030                    }
2031                }
2032                if (procName == null) {
2033                    return;
2034                }
2035
2036                if (DEBUG_PSS) Slog.d(TAG_PSS,
2037                        "Showing dump heap notification from " + procName + "/" + uid);
2038
2039                INotificationManager inm = NotificationManager.getService();
2040                if (inm == null) {
2041                    return;
2042                }
2043
2044                String text = mContext.getString(R.string.dump_heap_notification, procName);
2045
2046
2047                Intent deleteIntent = new Intent();
2048                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2049                Intent intent = new Intent();
2050                intent.setClassName("android", DumpHeapActivity.class.getName());
2051                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2052                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2053                if (reportPackage != null) {
2054                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2055                }
2056                int userId = UserHandle.getUserId(uid);
2057                Notification notification = new Notification.Builder(mContext)
2058                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2059                        .setWhen(0)
2060                        .setOngoing(true)
2061                        .setAutoCancel(true)
2062                        .setTicker(text)
2063                        .setColor(mContext.getColor(
2064                                com.android.internal.R.color.system_notification_accent_color))
2065                        .setContentTitle(text)
2066                        .setContentText(
2067                                mContext.getText(R.string.dump_heap_notification_detail))
2068                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2069                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2070                                new UserHandle(userId)))
2071                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2072                                deleteIntent, 0, UserHandle.SYSTEM))
2073                        .build();
2074
2075                try {
2076                    int[] outId = new int[1];
2077                    inm.enqueueNotificationWithTag("android", "android", null,
2078                            R.string.dump_heap_notification,
2079                            notification, outId, userId);
2080                } catch (RuntimeException e) {
2081                    Slog.w(ActivityManagerService.TAG,
2082                            "Error showing notification for dump heap", e);
2083                } catch (RemoteException e) {
2084                }
2085            } break;
2086            case DELETE_DUMPHEAP_MSG: {
2087                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2088                        DumpHeapActivity.JAVA_URI,
2089                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2090                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2091                        UserHandle.myUserId());
2092                synchronized (ActivityManagerService.this) {
2093                    mMemWatchDumpFile = null;
2094                    mMemWatchDumpProcName = null;
2095                    mMemWatchDumpPid = -1;
2096                    mMemWatchDumpUid = -1;
2097                }
2098            } break;
2099            case FOREGROUND_PROFILE_CHANGED_MSG: {
2100                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2101            } break;
2102            case REPORT_TIME_TRACKER_MSG: {
2103                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2104                tracker.deliverResult(mContext);
2105            } break;
2106            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2107                mUserController.dispatchUserSwitchComplete(msg.arg1);
2108            } break;
2109            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2110                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2111                try {
2112                    connection.shutdown();
2113                } catch (RemoteException e) {
2114                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2115                }
2116                // Only a UiAutomation can set this flag and now that
2117                // it is finished we make sure it is reset to its default.
2118                mUserIsMonkey = false;
2119            } break;
2120            case APP_BOOST_DEACTIVATE_MSG: {
2121                synchronized(ActivityManagerService.this) {
2122                    if (mIsBoosted) {
2123                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2124                            nativeMigrateFromBoost();
2125                            mIsBoosted = false;
2126                            mBoostStartTime = 0;
2127                        } else {
2128                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2129                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2130                        }
2131                    }
2132                }
2133            } break;
2134            case IDLE_UIDS_MSG: {
2135                idleUids();
2136            } break;
2137            }
2138        }
2139    };
2140
2141    static final int COLLECT_PSS_BG_MSG = 1;
2142
2143    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2144        @Override
2145        public void handleMessage(Message msg) {
2146            switch (msg.what) {
2147            case COLLECT_PSS_BG_MSG: {
2148                long start = SystemClock.uptimeMillis();
2149                MemInfoReader memInfo = null;
2150                synchronized (ActivityManagerService.this) {
2151                    if (mFullPssPending) {
2152                        mFullPssPending = false;
2153                        memInfo = new MemInfoReader();
2154                    }
2155                }
2156                if (memInfo != null) {
2157                    updateCpuStatsNow();
2158                    long nativeTotalPss = 0;
2159                    synchronized (mProcessCpuTracker) {
2160                        final int N = mProcessCpuTracker.countStats();
2161                        for (int j=0; j<N; j++) {
2162                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2163                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2164                                // This is definitely an application process; skip it.
2165                                continue;
2166                            }
2167                            synchronized (mPidsSelfLocked) {
2168                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2169                                    // This is one of our own processes; skip it.
2170                                    continue;
2171                                }
2172                            }
2173                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2174                        }
2175                    }
2176                    memInfo.readMemInfo();
2177                    synchronized (ActivityManagerService.this) {
2178                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2179                                + (SystemClock.uptimeMillis()-start) + "ms");
2180                        final long cachedKb = memInfo.getCachedSizeKb();
2181                        final long freeKb = memInfo.getFreeSizeKb();
2182                        final long zramKb = memInfo.getZramTotalSizeKb();
2183                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2184                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2185                                kernelKb*1024, nativeTotalPss*1024);
2186                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2187                                nativeTotalPss);
2188                    }
2189                }
2190
2191                int num = 0;
2192                long[] tmp = new long[1];
2193                do {
2194                    ProcessRecord proc;
2195                    int procState;
2196                    int pid;
2197                    long lastPssTime;
2198                    synchronized (ActivityManagerService.this) {
2199                        if (mPendingPssProcesses.size() <= 0) {
2200                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2201                                    "Collected PSS of " + num + " processes in "
2202                                    + (SystemClock.uptimeMillis() - start) + "ms");
2203                            mPendingPssProcesses.clear();
2204                            return;
2205                        }
2206                        proc = mPendingPssProcesses.remove(0);
2207                        procState = proc.pssProcState;
2208                        lastPssTime = proc.lastPssTime;
2209                        if (proc.thread != null && procState == proc.setProcState
2210                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2211                                        < SystemClock.uptimeMillis()) {
2212                            pid = proc.pid;
2213                        } else {
2214                            proc = null;
2215                            pid = 0;
2216                        }
2217                    }
2218                    if (proc != null) {
2219                        long pss = Debug.getPss(pid, tmp, null);
2220                        synchronized (ActivityManagerService.this) {
2221                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2222                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2223                                num++;
2224                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2225                                        SystemClock.uptimeMillis());
2226                            }
2227                        }
2228                    }
2229                } while (true);
2230            }
2231            }
2232        }
2233    };
2234
2235    public void setSystemProcess() {
2236        try {
2237            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2238            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2239            ServiceManager.addService("meminfo", new MemBinder(this));
2240            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2241            ServiceManager.addService("dbinfo", new DbBinder(this));
2242            if (MONITOR_CPU_USAGE) {
2243                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2244            }
2245            ServiceManager.addService("permission", new PermissionController(this));
2246            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2247
2248            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2249                    "android", STOCK_PM_FLAGS);
2250            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2251
2252            synchronized (this) {
2253                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2254                app.persistent = true;
2255                app.pid = MY_PID;
2256                app.maxAdj = ProcessList.SYSTEM_ADJ;
2257                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2258                synchronized (mPidsSelfLocked) {
2259                    mPidsSelfLocked.put(app.pid, app);
2260                }
2261                updateLruProcessLocked(app, false, null);
2262                updateOomAdjLocked();
2263            }
2264        } catch (PackageManager.NameNotFoundException e) {
2265            throw new RuntimeException(
2266                    "Unable to find android system package", e);
2267        }
2268    }
2269
2270    public void setWindowManager(WindowManagerService wm) {
2271        mWindowManager = wm;
2272        mStackSupervisor.setWindowManager(wm);
2273    }
2274
2275    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2276        mUsageStatsService = usageStatsManager;
2277    }
2278
2279    public void startObservingNativeCrashes() {
2280        final NativeCrashListener ncl = new NativeCrashListener(this);
2281        ncl.start();
2282    }
2283
2284    public IAppOpsService getAppOpsService() {
2285        return mAppOpsService;
2286    }
2287
2288    static class MemBinder extends Binder {
2289        ActivityManagerService mActivityManagerService;
2290        MemBinder(ActivityManagerService activityManagerService) {
2291            mActivityManagerService = activityManagerService;
2292        }
2293
2294        @Override
2295        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2296            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2297                    != PackageManager.PERMISSION_GRANTED) {
2298                pw.println("Permission Denial: can't dump meminfo from from pid="
2299                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2300                        + " without permission " + android.Manifest.permission.DUMP);
2301                return;
2302            }
2303
2304            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2305        }
2306    }
2307
2308    static class GraphicsBinder extends Binder {
2309        ActivityManagerService mActivityManagerService;
2310        GraphicsBinder(ActivityManagerService activityManagerService) {
2311            mActivityManagerService = activityManagerService;
2312        }
2313
2314        @Override
2315        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2316            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2317                    != PackageManager.PERMISSION_GRANTED) {
2318                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2319                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2320                        + " without permission " + android.Manifest.permission.DUMP);
2321                return;
2322            }
2323
2324            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2325        }
2326    }
2327
2328    static class DbBinder extends Binder {
2329        ActivityManagerService mActivityManagerService;
2330        DbBinder(ActivityManagerService activityManagerService) {
2331            mActivityManagerService = activityManagerService;
2332        }
2333
2334        @Override
2335        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2336            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2337                    != PackageManager.PERMISSION_GRANTED) {
2338                pw.println("Permission Denial: can't dump dbinfo from from pid="
2339                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2340                        + " without permission " + android.Manifest.permission.DUMP);
2341                return;
2342            }
2343
2344            mActivityManagerService.dumpDbInfo(fd, pw, args);
2345        }
2346    }
2347
2348    static class CpuBinder extends Binder {
2349        ActivityManagerService mActivityManagerService;
2350        CpuBinder(ActivityManagerService activityManagerService) {
2351            mActivityManagerService = activityManagerService;
2352        }
2353
2354        @Override
2355        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2356            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2357                    != PackageManager.PERMISSION_GRANTED) {
2358                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2359                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2360                        + " without permission " + android.Manifest.permission.DUMP);
2361                return;
2362            }
2363
2364            synchronized (mActivityManagerService.mProcessCpuTracker) {
2365                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2366                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2367                        SystemClock.uptimeMillis()));
2368            }
2369        }
2370    }
2371
2372    public static final class Lifecycle extends SystemService {
2373        private final ActivityManagerService mService;
2374
2375        public Lifecycle(Context context) {
2376            super(context);
2377            mService = new ActivityManagerService(context);
2378        }
2379
2380        @Override
2381        public void onStart() {
2382            mService.start();
2383        }
2384
2385        public ActivityManagerService getService() {
2386            return mService;
2387        }
2388    }
2389
2390    // Note: This method is invoked on the main thread but may need to attach various
2391    // handlers to other threads.  So take care to be explicit about the looper.
2392    public ActivityManagerService(Context systemContext) {
2393        mContext = systemContext;
2394        mFactoryTest = FactoryTest.getMode();
2395        mSystemThread = ActivityThread.currentActivityThread();
2396
2397        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2398
2399        mHandlerThread = new ServiceThread(TAG,
2400                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2401        mHandlerThread.start();
2402        mHandler = new MainHandler(mHandlerThread.getLooper());
2403        mUiHandler = new UiHandler();
2404
2405        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2406                "foreground", BROADCAST_FG_TIMEOUT, false);
2407        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2408                "background", BROADCAST_BG_TIMEOUT, true);
2409        mBroadcastQueues[0] = mFgBroadcastQueue;
2410        mBroadcastQueues[1] = mBgBroadcastQueue;
2411
2412        mServices = new ActiveServices(this);
2413        mProviderMap = new ProviderMap(this);
2414
2415        // TODO: Move creation of battery stats service outside of activity manager service.
2416        File dataDir = Environment.getDataDirectory();
2417        File systemDir = new File(dataDir, "system");
2418        systemDir.mkdirs();
2419        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2420        mBatteryStatsService.getActiveStatistics().readLocked();
2421        mBatteryStatsService.scheduleWriteToDisk();
2422        mOnBattery = DEBUG_POWER ? true
2423                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2424        mBatteryStatsService.getActiveStatistics().setCallback(this);
2425
2426        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2427
2428        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2429        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2430                new IAppOpsCallback.Stub() {
2431                    @Override public void opChanged(int op, int uid, String packageName) {
2432                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2433                            if (mAppOpsService.checkOperation(op, uid, packageName)
2434                                    != AppOpsManager.MODE_ALLOWED) {
2435                                runInBackgroundDisabled(uid);
2436                            }
2437                        }
2438                    }
2439                });
2440
2441        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2442
2443        mUserController = new UserController(this);
2444
2445        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2446            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2447
2448        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2449
2450        mConfiguration.setToDefaults();
2451        mConfiguration.setLocales(LocaleList.getDefault());
2452
2453        mConfigurationSeq = mConfiguration.seq = 1;
2454        mProcessCpuTracker.init();
2455
2456        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2457        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2458        mRecentTasks = new RecentTasks(this);
2459        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2460        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2461
2462        mProcessCpuThread = new Thread("CpuTracker") {
2463            @Override
2464            public void run() {
2465                while (true) {
2466                    try {
2467                        try {
2468                            synchronized(this) {
2469                                final long now = SystemClock.uptimeMillis();
2470                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2471                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2472                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2473                                //        + ", write delay=" + nextWriteDelay);
2474                                if (nextWriteDelay < nextCpuDelay) {
2475                                    nextCpuDelay = nextWriteDelay;
2476                                }
2477                                if (nextCpuDelay > 0) {
2478                                    mProcessCpuMutexFree.set(true);
2479                                    this.wait(nextCpuDelay);
2480                                }
2481                            }
2482                        } catch (InterruptedException e) {
2483                        }
2484                        updateCpuStatsNow();
2485                    } catch (Exception e) {
2486                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2487                    }
2488                }
2489            }
2490        };
2491
2492        Watchdog.getInstance().addMonitor(this);
2493        Watchdog.getInstance().addThread(mHandler);
2494    }
2495
2496    public void setSystemServiceManager(SystemServiceManager mgr) {
2497        mSystemServiceManager = mgr;
2498    }
2499
2500    public void setInstaller(Installer installer) {
2501        mInstaller = installer;
2502    }
2503
2504    private void start() {
2505        Process.removeAllProcessGroups();
2506        mProcessCpuThread.start();
2507
2508        mBatteryStatsService.publish(mContext);
2509        mAppOpsService.publish(mContext);
2510        Slog.d("AppOps", "AppOpsService published");
2511        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2512    }
2513
2514    public void initPowerManagement() {
2515        mStackSupervisor.initPowerManagement();
2516        mBatteryStatsService.initPowerManagement();
2517        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2518        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2519        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2520        mVoiceWakeLock.setReferenceCounted(false);
2521    }
2522
2523    @Override
2524    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2525            throws RemoteException {
2526        if (code == SYSPROPS_TRANSACTION) {
2527            // We need to tell all apps about the system property change.
2528            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2529            synchronized(this) {
2530                final int NP = mProcessNames.getMap().size();
2531                for (int ip=0; ip<NP; ip++) {
2532                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2533                    final int NA = apps.size();
2534                    for (int ia=0; ia<NA; ia++) {
2535                        ProcessRecord app = apps.valueAt(ia);
2536                        if (app.thread != null) {
2537                            procs.add(app.thread.asBinder());
2538                        }
2539                    }
2540                }
2541            }
2542
2543            int N = procs.size();
2544            for (int i=0; i<N; i++) {
2545                Parcel data2 = Parcel.obtain();
2546                try {
2547                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2548                } catch (RemoteException e) {
2549                }
2550                data2.recycle();
2551            }
2552        }
2553        try {
2554            return super.onTransact(code, data, reply, flags);
2555        } catch (RuntimeException e) {
2556            // The activity manager only throws security exceptions, so let's
2557            // log all others.
2558            if (!(e instanceof SecurityException)) {
2559                Slog.wtf(TAG, "Activity Manager Crash", e);
2560            }
2561            throw e;
2562        }
2563    }
2564
2565    void updateCpuStats() {
2566        final long now = SystemClock.uptimeMillis();
2567        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2568            return;
2569        }
2570        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2571            synchronized (mProcessCpuThread) {
2572                mProcessCpuThread.notify();
2573            }
2574        }
2575    }
2576
2577    void updateCpuStatsNow() {
2578        synchronized (mProcessCpuTracker) {
2579            mProcessCpuMutexFree.set(false);
2580            final long now = SystemClock.uptimeMillis();
2581            boolean haveNewCpuStats = false;
2582
2583            if (MONITOR_CPU_USAGE &&
2584                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2585                mLastCpuTime.set(now);
2586                mProcessCpuTracker.update();
2587                if (mProcessCpuTracker.hasGoodLastStats()) {
2588                    haveNewCpuStats = true;
2589                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2590                    //Slog.i(TAG, "Total CPU usage: "
2591                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2592
2593                    // Slog the cpu usage if the property is set.
2594                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2595                        int user = mProcessCpuTracker.getLastUserTime();
2596                        int system = mProcessCpuTracker.getLastSystemTime();
2597                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2598                        int irq = mProcessCpuTracker.getLastIrqTime();
2599                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2600                        int idle = mProcessCpuTracker.getLastIdleTime();
2601
2602                        int total = user + system + iowait + irq + softIrq + idle;
2603                        if (total == 0) total = 1;
2604
2605                        EventLog.writeEvent(EventLogTags.CPU,
2606                                ((user+system+iowait+irq+softIrq) * 100) / total,
2607                                (user * 100) / total,
2608                                (system * 100) / total,
2609                                (iowait * 100) / total,
2610                                (irq * 100) / total,
2611                                (softIrq * 100) / total);
2612                    }
2613                }
2614            }
2615
2616            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2617            synchronized(bstats) {
2618                synchronized(mPidsSelfLocked) {
2619                    if (haveNewCpuStats) {
2620                        if (bstats.startAddingCpuLocked()) {
2621                            int totalUTime = 0;
2622                            int totalSTime = 0;
2623                            final int N = mProcessCpuTracker.countStats();
2624                            for (int i=0; i<N; i++) {
2625                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2626                                if (!st.working) {
2627                                    continue;
2628                                }
2629                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2630                                totalUTime += st.rel_utime;
2631                                totalSTime += st.rel_stime;
2632                                if (pr != null) {
2633                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2634                                    if (ps == null || !ps.isActive()) {
2635                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2636                                                pr.info.uid, pr.processName);
2637                                    }
2638                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2639                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2640                                } else {
2641                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2642                                    if (ps == null || !ps.isActive()) {
2643                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2644                                                bstats.mapUid(st.uid), st.name);
2645                                    }
2646                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2647                                }
2648                            }
2649                            final int userTime = mProcessCpuTracker.getLastUserTime();
2650                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2651                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2652                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2653                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2654                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2655                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2656                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2657                        }
2658                    }
2659                }
2660
2661                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2662                    mLastWriteTime = now;
2663                    mBatteryStatsService.scheduleWriteToDisk();
2664                }
2665            }
2666        }
2667    }
2668
2669    @Override
2670    public void batteryNeedsCpuUpdate() {
2671        updateCpuStatsNow();
2672    }
2673
2674    @Override
2675    public void batteryPowerChanged(boolean onBattery) {
2676        // When plugging in, update the CPU stats first before changing
2677        // the plug state.
2678        updateCpuStatsNow();
2679        synchronized (this) {
2680            synchronized(mPidsSelfLocked) {
2681                mOnBattery = DEBUG_POWER ? true : onBattery;
2682            }
2683        }
2684    }
2685
2686    @Override
2687    public void batterySendBroadcast(Intent intent) {
2688        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2689                AppOpsManager.OP_NONE, null, false, false,
2690                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2691    }
2692
2693    /**
2694     * Initialize the application bind args. These are passed to each
2695     * process when the bindApplication() IPC is sent to the process. They're
2696     * lazily setup to make sure the services are running when they're asked for.
2697     */
2698    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2699        if (mAppBindArgs == null) {
2700            mAppBindArgs = new HashMap<>();
2701
2702            // Isolated processes won't get this optimization, so that we don't
2703            // violate the rules about which services they have access to.
2704            if (!isolated) {
2705                // Setup the application init args
2706                mAppBindArgs.put("package", ServiceManager.getService("package"));
2707                mAppBindArgs.put("window", ServiceManager.getService("window"));
2708                mAppBindArgs.put(Context.ALARM_SERVICE,
2709                        ServiceManager.getService(Context.ALARM_SERVICE));
2710            }
2711        }
2712        return mAppBindArgs;
2713    }
2714
2715    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2716        if (r != null && mFocusedActivity != r) {
2717            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2718            ActivityRecord last = mFocusedActivity;
2719            mFocusedActivity = r;
2720            if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2721                    && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2722                if (mCurAppTimeTracker != r.appTimeTracker) {
2723                    // We are switching app tracking.  Complete the current one.
2724                    if (mCurAppTimeTracker != null) {
2725                        mCurAppTimeTracker.stop();
2726                        mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2727                                mCurAppTimeTracker).sendToTarget();
2728                        mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2729                        mCurAppTimeTracker = null;
2730                    }
2731                    if (r.appTimeTracker != null) {
2732                        mCurAppTimeTracker = r.appTimeTracker;
2733                        startTimeTrackingFocusedActivityLocked();
2734                    }
2735                } else {
2736                    startTimeTrackingFocusedActivityLocked();
2737                }
2738            } else {
2739                r.appTimeTracker = null;
2740            }
2741            if (r.task != null && r.task.voiceInteractor != null) {
2742                startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2743            } else {
2744                finishRunningVoiceLocked();
2745                if (last != null && last.task.voiceSession != null) {
2746                    // We had been in a voice interaction session, but now focused has
2747                    // move to something different.  Just finish the session, we can't
2748                    // return to it and retain the proper state and synchronization with
2749                    // the voice interaction service.
2750                    finishVoiceTask(last.task.voiceSession);
2751                }
2752            }
2753            if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2754                mWindowManager.setFocusedApp(r.appToken, true);
2755            }
2756            applyUpdateLockStateLocked(r);
2757            if (mFocusedActivity.userId != mLastFocusedUserId) {
2758                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2759                mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2760                        mFocusedActivity.userId, 0));
2761                mLastFocusedUserId = mFocusedActivity.userId;
2762            }
2763        }
2764        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2765                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2766                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2767    }
2768
2769    final void clearFocusedActivity(ActivityRecord r) {
2770        if (mFocusedActivity == r) {
2771            ActivityStack stack = mStackSupervisor.getFocusedStack();
2772            if (stack != null) {
2773                ActivityRecord top = stack.topActivity();
2774                if (top != null && top.userId != mLastFocusedUserId) {
2775                    mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2776                    mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2777                                    top.userId, 0));
2778                    mLastFocusedUserId = top.userId;
2779                }
2780            }
2781            mFocusedActivity = null;
2782            EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2783        }
2784    }
2785
2786    @Override
2787    public void setFocusedStack(int stackId) {
2788        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2789        synchronized (ActivityManagerService.this) {
2790            ActivityStack stack = mStackSupervisor.getStack(stackId);
2791            if (stack != null) {
2792                ActivityRecord r = stack.topRunningActivityLocked();
2793                if (r != null) {
2794                    setFocusedActivityLocked(r, "setFocusedStack");
2795                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2796                }
2797            }
2798        }
2799    }
2800
2801    @Override
2802    public void setFocusedTask(int taskId) {
2803        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2804        long callingId = Binder.clearCallingIdentity();
2805        try {
2806            synchronized (ActivityManagerService.this) {
2807                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2808                if (task != null) {
2809                    ActivityRecord r = task.topRunningActivityLocked();
2810                    if (r != null) {
2811                        setFocusedActivityLocked(r, "setFocusedTask");
2812                        mStackSupervisor.resumeTopActivitiesLocked(task.stack, null, null);
2813                    }
2814                }
2815            }
2816        } finally {
2817            Binder.restoreCallingIdentity(callingId);
2818        }
2819    }
2820
2821    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2822    @Override
2823    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2824        synchronized (ActivityManagerService.this) {
2825            if (listener != null) {
2826                mTaskStackListeners.register(listener);
2827            }
2828        }
2829    }
2830
2831    @Override
2832    public void notifyActivityDrawn(IBinder token) {
2833        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2834        synchronized (this) {
2835            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2836            if (r != null) {
2837                r.task.stack.notifyActivityDrawnLocked(r);
2838            }
2839        }
2840    }
2841
2842    final void applyUpdateLockStateLocked(ActivityRecord r) {
2843        // Modifications to the UpdateLock state are done on our handler, outside
2844        // the activity manager's locks.  The new state is determined based on the
2845        // state *now* of the relevant activity record.  The object is passed to
2846        // the handler solely for logging detail, not to be consulted/modified.
2847        final boolean nextState = r != null && r.immersive;
2848        mHandler.sendMessage(
2849                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2850    }
2851
2852    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2853        Message msg = Message.obtain();
2854        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
2855        msg.obj = r.task.askedCompatMode ? null : r;
2856        mUiHandler.sendMessage(msg);
2857    }
2858
2859    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2860            String what, Object obj, ProcessRecord srcApp) {
2861        app.lastActivityTime = now;
2862
2863        if (app.activities.size() > 0) {
2864            // Don't want to touch dependent processes that are hosting activities.
2865            return index;
2866        }
2867
2868        int lrui = mLruProcesses.lastIndexOf(app);
2869        if (lrui < 0) {
2870            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2871                    + what + " " + obj + " from " + srcApp);
2872            return index;
2873        }
2874
2875        if (lrui >= index) {
2876            // Don't want to cause this to move dependent processes *back* in the
2877            // list as if they were less frequently used.
2878            return index;
2879        }
2880
2881        if (lrui >= mLruProcessActivityStart) {
2882            // Don't want to touch dependent processes that are hosting activities.
2883            return index;
2884        }
2885
2886        mLruProcesses.remove(lrui);
2887        if (index > 0) {
2888            index--;
2889        }
2890        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2891                + " in LRU list: " + app);
2892        mLruProcesses.add(index, app);
2893        return index;
2894    }
2895
2896    private static void killProcessGroup(int uid, int pid) {
2897        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2898        Process.killProcessGroup(uid, pid);
2899        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2900    }
2901
2902    final void removeLruProcessLocked(ProcessRecord app) {
2903        int lrui = mLruProcesses.lastIndexOf(app);
2904        if (lrui >= 0) {
2905            if (!app.killed) {
2906                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2907                Process.killProcessQuiet(app.pid);
2908                killProcessGroup(app.info.uid, app.pid);
2909            }
2910            if (lrui <= mLruProcessActivityStart) {
2911                mLruProcessActivityStart--;
2912            }
2913            if (lrui <= mLruProcessServiceStart) {
2914                mLruProcessServiceStart--;
2915            }
2916            mLruProcesses.remove(lrui);
2917        }
2918    }
2919
2920    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2921            ProcessRecord client) {
2922        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2923                || app.treatLikeActivity;
2924        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2925        if (!activityChange && hasActivity) {
2926            // The process has activities, so we are only allowing activity-based adjustments
2927            // to move it.  It should be kept in the front of the list with other
2928            // processes that have activities, and we don't want those to change their
2929            // order except due to activity operations.
2930            return;
2931        }
2932
2933        mLruSeq++;
2934        final long now = SystemClock.uptimeMillis();
2935        app.lastActivityTime = now;
2936
2937        // First a quick reject: if the app is already at the position we will
2938        // put it, then there is nothing to do.
2939        if (hasActivity) {
2940            final int N = mLruProcesses.size();
2941            if (N > 0 && mLruProcesses.get(N-1) == app) {
2942                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2943                return;
2944            }
2945        } else {
2946            if (mLruProcessServiceStart > 0
2947                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2948                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2949                return;
2950            }
2951        }
2952
2953        int lrui = mLruProcesses.lastIndexOf(app);
2954
2955        if (app.persistent && lrui >= 0) {
2956            // We don't care about the position of persistent processes, as long as
2957            // they are in the list.
2958            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2959            return;
2960        }
2961
2962        /* In progress: compute new position first, so we can avoid doing work
2963           if the process is not actually going to move.  Not yet working.
2964        int addIndex;
2965        int nextIndex;
2966        boolean inActivity = false, inService = false;
2967        if (hasActivity) {
2968            // Process has activities, put it at the very tipsy-top.
2969            addIndex = mLruProcesses.size();
2970            nextIndex = mLruProcessServiceStart;
2971            inActivity = true;
2972        } else if (hasService) {
2973            // Process has services, put it at the top of the service list.
2974            addIndex = mLruProcessActivityStart;
2975            nextIndex = mLruProcessServiceStart;
2976            inActivity = true;
2977            inService = true;
2978        } else  {
2979            // Process not otherwise of interest, it goes to the top of the non-service area.
2980            addIndex = mLruProcessServiceStart;
2981            if (client != null) {
2982                int clientIndex = mLruProcesses.lastIndexOf(client);
2983                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2984                        + app);
2985                if (clientIndex >= 0 && addIndex > clientIndex) {
2986                    addIndex = clientIndex;
2987                }
2988            }
2989            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2990        }
2991
2992        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2993                + mLruProcessActivityStart + "): " + app);
2994        */
2995
2996        if (lrui >= 0) {
2997            if (lrui < mLruProcessActivityStart) {
2998                mLruProcessActivityStart--;
2999            }
3000            if (lrui < mLruProcessServiceStart) {
3001                mLruProcessServiceStart--;
3002            }
3003            /*
3004            if (addIndex > lrui) {
3005                addIndex--;
3006            }
3007            if (nextIndex > lrui) {
3008                nextIndex--;
3009            }
3010            */
3011            mLruProcesses.remove(lrui);
3012        }
3013
3014        /*
3015        mLruProcesses.add(addIndex, app);
3016        if (inActivity) {
3017            mLruProcessActivityStart++;
3018        }
3019        if (inService) {
3020            mLruProcessActivityStart++;
3021        }
3022        */
3023
3024        int nextIndex;
3025        if (hasActivity) {
3026            final int N = mLruProcesses.size();
3027            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3028                // Process doesn't have activities, but has clients with
3029                // activities...  move it up, but one below the top (the top
3030                // should always have a real activity).
3031                if (DEBUG_LRU) Slog.d(TAG_LRU,
3032                        "Adding to second-top of LRU activity list: " + app);
3033                mLruProcesses.add(N - 1, app);
3034                // To keep it from spamming the LRU list (by making a bunch of clients),
3035                // we will push down any other entries owned by the app.
3036                final int uid = app.info.uid;
3037                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3038                    ProcessRecord subProc = mLruProcesses.get(i);
3039                    if (subProc.info.uid == uid) {
3040                        // We want to push this one down the list.  If the process after
3041                        // it is for the same uid, however, don't do so, because we don't
3042                        // want them internally to be re-ordered.
3043                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3044                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3045                                    "Pushing uid " + uid + " swapping at " + i + ": "
3046                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3047                            ProcessRecord tmp = mLruProcesses.get(i);
3048                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3049                            mLruProcesses.set(i - 1, tmp);
3050                            i--;
3051                        }
3052                    } else {
3053                        // A gap, we can stop here.
3054                        break;
3055                    }
3056                }
3057            } else {
3058                // Process has activities, put it at the very tipsy-top.
3059                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3060                mLruProcesses.add(app);
3061            }
3062            nextIndex = mLruProcessServiceStart;
3063        } else if (hasService) {
3064            // Process has services, put it at the top of the service list.
3065            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3066            mLruProcesses.add(mLruProcessActivityStart, app);
3067            nextIndex = mLruProcessServiceStart;
3068            mLruProcessActivityStart++;
3069        } else  {
3070            // Process not otherwise of interest, it goes to the top of the non-service area.
3071            int index = mLruProcessServiceStart;
3072            if (client != null) {
3073                // If there is a client, don't allow the process to be moved up higher
3074                // in the list than that client.
3075                int clientIndex = mLruProcesses.lastIndexOf(client);
3076                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3077                        + " when updating " + app);
3078                if (clientIndex <= lrui) {
3079                    // Don't allow the client index restriction to push it down farther in the
3080                    // list than it already is.
3081                    clientIndex = lrui;
3082                }
3083                if (clientIndex >= 0 && index > clientIndex) {
3084                    index = clientIndex;
3085                }
3086            }
3087            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3088            mLruProcesses.add(index, app);
3089            nextIndex = index-1;
3090            mLruProcessActivityStart++;
3091            mLruProcessServiceStart++;
3092        }
3093
3094        // If the app is currently using a content provider or service,
3095        // bump those processes as well.
3096        for (int j=app.connections.size()-1; j>=0; j--) {
3097            ConnectionRecord cr = app.connections.valueAt(j);
3098            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3099                    && cr.binding.service.app != null
3100                    && cr.binding.service.app.lruSeq != mLruSeq
3101                    && !cr.binding.service.app.persistent) {
3102                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3103                        "service connection", cr, app);
3104            }
3105        }
3106        for (int j=app.conProviders.size()-1; j>=0; j--) {
3107            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3108            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3109                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3110                        "provider reference", cpr, app);
3111            }
3112        }
3113    }
3114
3115    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3116        if (uid == Process.SYSTEM_UID) {
3117            // The system gets to run in any process.  If there are multiple
3118            // processes with the same uid, just pick the first (this
3119            // should never happen).
3120            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3121            if (procs == null) return null;
3122            final int procCount = procs.size();
3123            for (int i = 0; i < procCount; i++) {
3124                final int procUid = procs.keyAt(i);
3125                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3126                    // Don't use an app process or different user process for system component.
3127                    continue;
3128                }
3129                return procs.valueAt(i);
3130            }
3131        }
3132        ProcessRecord proc = mProcessNames.get(processName, uid);
3133        if (false && proc != null && !keepIfLarge
3134                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3135                && proc.lastCachedPss >= 4000) {
3136            // Turn this condition on to cause killing to happen regularly, for testing.
3137            if (proc.baseProcessTracker != null) {
3138                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3139            }
3140            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3141        } else if (proc != null && !keepIfLarge
3142                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3143                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3144            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3145            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3146                if (proc.baseProcessTracker != null) {
3147                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3148                }
3149                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3150            }
3151        }
3152        return proc;
3153    }
3154
3155    void notifyPackageUse(String packageName) {
3156        IPackageManager pm = AppGlobals.getPackageManager();
3157        try {
3158            pm.notifyPackageUse(packageName);
3159        } catch (RemoteException e) {
3160        }
3161    }
3162
3163    boolean isNextTransitionForward() {
3164        int transit = mWindowManager.getPendingAppTransition();
3165        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3166                || transit == AppTransition.TRANSIT_TASK_OPEN
3167                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3168    }
3169
3170    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3171            String processName, String abiOverride, int uid, Runnable crashHandler) {
3172        synchronized(this) {
3173            ApplicationInfo info = new ApplicationInfo();
3174            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3175            // For isolated processes, the former contains the parent's uid and the latter the
3176            // actual uid of the isolated process.
3177            // In the special case introduced by this method (which is, starting an isolated
3178            // process directly from the SystemServer without an actual parent app process) the
3179            // closest thing to a parent's uid is SYSTEM_UID.
3180            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3181            // the |isolated| logic in the ProcessRecord constructor.
3182            info.uid = Process.SYSTEM_UID;
3183            info.processName = processName;
3184            info.className = entryPoint;
3185            info.packageName = "android";
3186            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3187                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3188                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3189                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3190                    crashHandler);
3191            return proc != null ? proc.pid : 0;
3192        }
3193    }
3194
3195    final ProcessRecord startProcessLocked(String processName,
3196            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3197            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3198            boolean isolated, boolean keepIfLarge) {
3199        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3200                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3201                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3202                null /* crashHandler */);
3203    }
3204
3205    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3206            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3207            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3208            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3209        long startTime = SystemClock.elapsedRealtime();
3210        ProcessRecord app;
3211        if (!isolated) {
3212            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3213            checkTime(startTime, "startProcess: after getProcessRecord");
3214
3215            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3216                // If we are in the background, then check to see if this process
3217                // is bad.  If so, we will just silently fail.
3218                if (mBadProcesses.get(info.processName, info.uid) != null) {
3219                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3220                            + "/" + info.processName);
3221                    return null;
3222                }
3223            } else {
3224                // When the user is explicitly starting a process, then clear its
3225                // crash count so that we won't make it bad until they see at
3226                // least one crash dialog again, and make the process good again
3227                // if it had been bad.
3228                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3229                        + "/" + info.processName);
3230                mProcessCrashTimes.remove(info.processName, info.uid);
3231                if (mBadProcesses.get(info.processName, info.uid) != null) {
3232                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3233                            UserHandle.getUserId(info.uid), info.uid,
3234                            info.processName);
3235                    mBadProcesses.remove(info.processName, info.uid);
3236                    if (app != null) {
3237                        app.bad = false;
3238                    }
3239                }
3240            }
3241        } else {
3242            // If this is an isolated process, it can't re-use an existing process.
3243            app = null;
3244        }
3245
3246        // app launch boost for big.little configurations
3247        // use cpusets to migrate freshly launched tasks to big cores
3248        synchronized(ActivityManagerService.this) {
3249            nativeMigrateToBoost();
3250            mIsBoosted = true;
3251            mBoostStartTime = SystemClock.uptimeMillis();
3252            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3253            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3254        }
3255
3256        // We don't have to do anything more if:
3257        // (1) There is an existing application record; and
3258        // (2) The caller doesn't think it is dead, OR there is no thread
3259        //     object attached to it so we know it couldn't have crashed; and
3260        // (3) There is a pid assigned to it, so it is either starting or
3261        //     already running.
3262        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3263                + " app=" + app + " knownToBeDead=" + knownToBeDead
3264                + " thread=" + (app != null ? app.thread : null)
3265                + " pid=" + (app != null ? app.pid : -1));
3266        if (app != null && app.pid > 0) {
3267            if (!knownToBeDead || app.thread == null) {
3268                // We already have the app running, or are waiting for it to
3269                // come up (we have a pid but not yet its thread), so keep it.
3270                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3271                // If this is a new package in the process, add the package to the list
3272                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3273                checkTime(startTime, "startProcess: done, added package to proc");
3274                return app;
3275            }
3276
3277            // An application record is attached to a previous process,
3278            // clean it up now.
3279            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3280            checkTime(startTime, "startProcess: bad proc running, killing");
3281            killProcessGroup(app.info.uid, app.pid);
3282            handleAppDiedLocked(app, true, true);
3283            checkTime(startTime, "startProcess: done killing old proc");
3284        }
3285
3286        String hostingNameStr = hostingName != null
3287                ? hostingName.flattenToShortString() : null;
3288
3289        if (app == null) {
3290            checkTime(startTime, "startProcess: creating new process record");
3291            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3292            if (app == null) {
3293                Slog.w(TAG, "Failed making new process record for "
3294                        + processName + "/" + info.uid + " isolated=" + isolated);
3295                return null;
3296            }
3297            app.crashHandler = crashHandler;
3298            checkTime(startTime, "startProcess: done creating new process record");
3299        } else {
3300            // If this is a new package in the process, add the package to the list
3301            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3302            checkTime(startTime, "startProcess: added package to existing proc");
3303        }
3304
3305        // If the system is not ready yet, then hold off on starting this
3306        // process until it is.
3307        if (!mProcessesReady
3308                && !isAllowedWhileBooting(info)
3309                && !allowWhileBooting) {
3310            if (!mProcessesOnHold.contains(app)) {
3311                mProcessesOnHold.add(app);
3312            }
3313            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3314                    "System not ready, putting on hold: " + app);
3315            checkTime(startTime, "startProcess: returning with proc on hold");
3316            return app;
3317        }
3318
3319        checkTime(startTime, "startProcess: stepping in to startProcess");
3320        startProcessLocked(
3321                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3322        checkTime(startTime, "startProcess: done starting proc!");
3323        return (app.pid != 0) ? app : null;
3324    }
3325
3326    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3327        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3328    }
3329
3330    private final void startProcessLocked(ProcessRecord app,
3331            String hostingType, String hostingNameStr) {
3332        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3333                null /* entryPoint */, null /* entryPointArgs */);
3334    }
3335
3336    private final void startProcessLocked(ProcessRecord app, String hostingType,
3337            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3338        long startTime = SystemClock.elapsedRealtime();
3339        if (app.pid > 0 && app.pid != MY_PID) {
3340            checkTime(startTime, "startProcess: removing from pids map");
3341            synchronized (mPidsSelfLocked) {
3342                mPidsSelfLocked.remove(app.pid);
3343                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3344            }
3345            checkTime(startTime, "startProcess: done removing from pids map");
3346            app.setPid(0);
3347        }
3348
3349        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3350                "startProcessLocked removing on hold: " + app);
3351        mProcessesOnHold.remove(app);
3352
3353        checkTime(startTime, "startProcess: starting to update cpu stats");
3354        updateCpuStats();
3355        checkTime(startTime, "startProcess: done updating cpu stats");
3356
3357        try {
3358            try {
3359                final int userId = UserHandle.getUserId(app.uid);
3360                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3361            } catch (RemoteException e) {
3362                throw e.rethrowAsRuntimeException();
3363            }
3364
3365            int uid = app.uid;
3366            int[] gids = null;
3367            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3368            if (!app.isolated) {
3369                int[] permGids = null;
3370                try {
3371                    checkTime(startTime, "startProcess: getting gids from package manager");
3372                    final IPackageManager pm = AppGlobals.getPackageManager();
3373                    permGids = pm.getPackageGids(app.info.packageName, app.userId);
3374                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3375                            MountServiceInternal.class);
3376                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3377                            app.info.packageName);
3378                } catch (RemoteException e) {
3379                    throw e.rethrowAsRuntimeException();
3380                }
3381
3382                /*
3383                 * Add shared application and profile GIDs so applications can share some
3384                 * resources like shared libraries and access user-wide resources
3385                 */
3386                if (ArrayUtils.isEmpty(permGids)) {
3387                    gids = new int[2];
3388                } else {
3389                    gids = new int[permGids.length + 2];
3390                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3391                }
3392                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3393                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3394            }
3395            checkTime(startTime, "startProcess: building args");
3396            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3397                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3398                        && mTopComponent != null
3399                        && app.processName.equals(mTopComponent.getPackageName())) {
3400                    uid = 0;
3401                }
3402                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3403                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3404                    uid = 0;
3405                }
3406            }
3407            int debugFlags = 0;
3408            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3409                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3410                // Also turn on CheckJNI for debuggable apps. It's quite
3411                // awkward to turn on otherwise.
3412                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3413            }
3414            // Run the app in safe mode if its manifest requests so or the
3415            // system is booted in safe mode.
3416            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3417                mSafeMode == true) {
3418                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3419            }
3420            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3421                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3422            }
3423            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3424            if ("true".equals(genDebugInfoProperty)) {
3425                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3426            }
3427            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3428                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3429            }
3430            if ("1".equals(SystemProperties.get("debug.assert"))) {
3431                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3432            }
3433
3434            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3435            if (requiredAbi == null) {
3436                requiredAbi = Build.SUPPORTED_ABIS[0];
3437            }
3438
3439            String instructionSet = null;
3440            if (app.info.primaryCpuAbi != null) {
3441                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3442            }
3443
3444            app.gids = gids;
3445            app.requiredAbi = requiredAbi;
3446            app.instructionSet = instructionSet;
3447
3448            // Start the process.  It will either succeed and return a result containing
3449            // the PID of the new process, or else throw a RuntimeException.
3450            boolean isActivityProcess = (entryPoint == null);
3451            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3452            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3453                    app.processName);
3454            checkTime(startTime, "startProcess: asking zygote to start proc");
3455            Process.ProcessStartResult startResult = Process.start(entryPoint,
3456                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3457                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3458                    app.info.dataDir, entryPointArgs);
3459            checkTime(startTime, "startProcess: returned from zygote!");
3460            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3461
3462            if (app.isolated) {
3463                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3464            }
3465            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3466            checkTime(startTime, "startProcess: done updating battery stats");
3467
3468            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3469                    UserHandle.getUserId(uid), startResult.pid, uid,
3470                    app.processName, hostingType,
3471                    hostingNameStr != null ? hostingNameStr : "");
3472
3473            if (app.persistent) {
3474                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3475            }
3476
3477            checkTime(startTime, "startProcess: building log message");
3478            StringBuilder buf = mStringBuilder;
3479            buf.setLength(0);
3480            buf.append("Start proc ");
3481            buf.append(startResult.pid);
3482            buf.append(':');
3483            buf.append(app.processName);
3484            buf.append('/');
3485            UserHandle.formatUid(buf, uid);
3486            if (!isActivityProcess) {
3487                buf.append(" [");
3488                buf.append(entryPoint);
3489                buf.append("]");
3490            }
3491            buf.append(" for ");
3492            buf.append(hostingType);
3493            if (hostingNameStr != null) {
3494                buf.append(" ");
3495                buf.append(hostingNameStr);
3496            }
3497            Slog.i(TAG, buf.toString());
3498            app.setPid(startResult.pid);
3499            app.usingWrapper = startResult.usingWrapper;
3500            app.removed = false;
3501            app.killed = false;
3502            app.killedByAm = false;
3503            checkTime(startTime, "startProcess: starting to update pids map");
3504            synchronized (mPidsSelfLocked) {
3505                this.mPidsSelfLocked.put(startResult.pid, app);
3506                if (isActivityProcess) {
3507                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3508                    msg.obj = app;
3509                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3510                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3511                }
3512            }
3513            checkTime(startTime, "startProcess: done updating pids map");
3514        } catch (RuntimeException e) {
3515            // XXX do better error recovery.
3516            app.setPid(0);
3517            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3518            if (app.isolated) {
3519                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3520            }
3521            Slog.e(TAG, "Failure starting process " + app.processName, e);
3522        }
3523    }
3524
3525    void updateUsageStats(ActivityRecord component, boolean resumed) {
3526        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3527                "updateUsageStats: comp=" + component + "res=" + resumed);
3528        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3529        if (resumed) {
3530            if (mUsageStatsService != null) {
3531                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3532                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3533            }
3534            synchronized (stats) {
3535                stats.noteActivityResumedLocked(component.app.uid);
3536            }
3537        } else {
3538            if (mUsageStatsService != null) {
3539                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3540                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3541            }
3542            synchronized (stats) {
3543                stats.noteActivityPausedLocked(component.app.uid);
3544            }
3545        }
3546    }
3547
3548    Intent getHomeIntent() {
3549        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3550        intent.setComponent(mTopComponent);
3551        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3552            intent.addCategory(Intent.CATEGORY_HOME);
3553        }
3554        return intent;
3555    }
3556
3557    boolean startHomeActivityLocked(int userId, String reason) {
3558        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3559                && mTopAction == null) {
3560            // We are running in factory test mode, but unable to find
3561            // the factory test app, so just sit around displaying the
3562            // error message and don't try to start anything.
3563            return false;
3564        }
3565        Intent intent = getHomeIntent();
3566        ActivityInfo aInfo =
3567            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3568        if (aInfo != null) {
3569            intent.setComponent(new ComponentName(
3570                    aInfo.applicationInfo.packageName, aInfo.name));
3571            // Don't do this if the home app is currently being
3572            // instrumented.
3573            aInfo = new ActivityInfo(aInfo);
3574            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3575            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3576                    aInfo.applicationInfo.uid, true);
3577            if (app == null || app.instrumentationClass == null) {
3578                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3579                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3580            }
3581        }
3582
3583        return true;
3584    }
3585
3586    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3587        ActivityInfo ai = null;
3588        ComponentName comp = intent.getComponent();
3589        try {
3590            if (comp != null) {
3591                // Factory test.
3592                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3593            } else {
3594                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3595                        intent,
3596                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3597                        flags, userId);
3598
3599                if (info != null) {
3600                    ai = info.activityInfo;
3601                }
3602            }
3603        } catch (RemoteException e) {
3604            // ignore
3605        }
3606
3607        return ai;
3608    }
3609
3610    /**
3611     * Starts the "new version setup screen" if appropriate.
3612     */
3613    void startSetupActivityLocked() {
3614        // Only do this once per boot.
3615        if (mCheckedForSetup) {
3616            return;
3617        }
3618
3619        // We will show this screen if the current one is a different
3620        // version than the last one shown, and we are not running in
3621        // low-level factory test mode.
3622        final ContentResolver resolver = mContext.getContentResolver();
3623        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3624                Settings.Global.getInt(resolver,
3625                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3626            mCheckedForSetup = true;
3627
3628            // See if we should be showing the platform update setup UI.
3629            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3630            List<ResolveInfo> ris = mContext.getPackageManager()
3631                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3632
3633            // We don't allow third party apps to replace this.
3634            ResolveInfo ri = null;
3635            for (int i=0; ris != null && i<ris.size(); i++) {
3636                if ((ris.get(i).activityInfo.applicationInfo.flags
3637                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3638                    ri = ris.get(i);
3639                    break;
3640                }
3641            }
3642
3643            if (ri != null) {
3644                String vers = ri.activityInfo.metaData != null
3645                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3646                        : null;
3647                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3648                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3649                            Intent.METADATA_SETUP_VERSION);
3650                }
3651                String lastVers = Settings.Secure.getString(
3652                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3653                if (vers != null && !vers.equals(lastVers)) {
3654                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3655                    intent.setComponent(new ComponentName(
3656                            ri.activityInfo.packageName, ri.activityInfo.name));
3657                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3658                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
3659                            null, null, null);
3660                }
3661            }
3662        }
3663    }
3664
3665    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3666        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3667    }
3668
3669    void enforceNotIsolatedCaller(String caller) {
3670        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3671            throw new SecurityException("Isolated process not allowed to call " + caller);
3672        }
3673    }
3674
3675    void enforceShellRestriction(String restriction, int userHandle) {
3676        if (Binder.getCallingUid() == Process.SHELL_UID) {
3677            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3678                throw new SecurityException("Shell does not have permission to access user "
3679                        + userHandle);
3680            }
3681        }
3682    }
3683
3684    @Override
3685    public int getFrontActivityScreenCompatMode() {
3686        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3687        synchronized (this) {
3688            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3689        }
3690    }
3691
3692    @Override
3693    public void setFrontActivityScreenCompatMode(int mode) {
3694        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3695                "setFrontActivityScreenCompatMode");
3696        synchronized (this) {
3697            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3698        }
3699    }
3700
3701    @Override
3702    public int getPackageScreenCompatMode(String packageName) {
3703        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3704        synchronized (this) {
3705            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3706        }
3707    }
3708
3709    @Override
3710    public void setPackageScreenCompatMode(String packageName, int mode) {
3711        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3712                "setPackageScreenCompatMode");
3713        synchronized (this) {
3714            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3715        }
3716    }
3717
3718    @Override
3719    public boolean getPackageAskScreenCompat(String packageName) {
3720        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3721        synchronized (this) {
3722            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3723        }
3724    }
3725
3726    @Override
3727    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3728        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3729                "setPackageAskScreenCompat");
3730        synchronized (this) {
3731            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3732        }
3733    }
3734
3735    private boolean hasUsageStatsPermission(String callingPackage) {
3736        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3737                Binder.getCallingUid(), callingPackage);
3738        if (mode == AppOpsManager.MODE_DEFAULT) {
3739            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3740                    == PackageManager.PERMISSION_GRANTED;
3741        }
3742        return mode == AppOpsManager.MODE_ALLOWED;
3743    }
3744
3745    @Override
3746    public int getPackageProcessState(String packageName, String callingPackage) {
3747        if (!hasUsageStatsPermission(callingPackage)) {
3748            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3749                    "getPackageProcessState");
3750        }
3751
3752        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3753        synchronized (this) {
3754            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3755                final ProcessRecord proc = mLruProcesses.get(i);
3756                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3757                        || procState > proc.setProcState) {
3758                    boolean found = false;
3759                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3760                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3761                            procState = proc.setProcState;
3762                            found = true;
3763                        }
3764                    }
3765                    if (proc.pkgDeps != null && !found) {
3766                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3767                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3768                                procState = proc.setProcState;
3769                                break;
3770                            }
3771                        }
3772                    }
3773                }
3774            }
3775        }
3776        return procState;
3777    }
3778
3779    @Override
3780    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3781        synchronized (this) {
3782            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3783            if (app == null) {
3784                return false;
3785            }
3786            if (app.trimMemoryLevel < level && app.thread != null &&
3787                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3788                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3789                try {
3790                    app.thread.scheduleTrimMemory(level);
3791                    app.trimMemoryLevel = level;
3792                    return true;
3793                } catch (RemoteException e) {
3794                    // Fallthrough to failure case.
3795                }
3796            }
3797        }
3798        return false;
3799    }
3800
3801    private void dispatchProcessesChanged() {
3802        int N;
3803        synchronized (this) {
3804            N = mPendingProcessChanges.size();
3805            if (mActiveProcessChanges.length < N) {
3806                mActiveProcessChanges = new ProcessChangeItem[N];
3807            }
3808            mPendingProcessChanges.toArray(mActiveProcessChanges);
3809            mPendingProcessChanges.clear();
3810            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3811                    "*** Delivering " + N + " process changes");
3812        }
3813
3814        int i = mProcessObservers.beginBroadcast();
3815        while (i > 0) {
3816            i--;
3817            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3818            if (observer != null) {
3819                try {
3820                    for (int j=0; j<N; j++) {
3821                        ProcessChangeItem item = mActiveProcessChanges[j];
3822                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3823                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3824                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3825                                    + item.uid + ": " + item.foregroundActivities);
3826                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3827                                    item.foregroundActivities);
3828                        }
3829                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3830                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3831                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3832                                    + ": " + item.processState);
3833                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3834                        }
3835                    }
3836                } catch (RemoteException e) {
3837                }
3838            }
3839        }
3840        mProcessObservers.finishBroadcast();
3841
3842        synchronized (this) {
3843            for (int j=0; j<N; j++) {
3844                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3845            }
3846        }
3847    }
3848
3849    private void dispatchProcessDied(int pid, int uid) {
3850        int i = mProcessObservers.beginBroadcast();
3851        while (i > 0) {
3852            i--;
3853            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3854            if (observer != null) {
3855                try {
3856                    observer.onProcessDied(pid, uid);
3857                } catch (RemoteException e) {
3858                }
3859            }
3860        }
3861        mProcessObservers.finishBroadcast();
3862    }
3863
3864    private void dispatchUidsChanged() {
3865        int N;
3866        synchronized (this) {
3867            N = mPendingUidChanges.size();
3868            if (mActiveUidChanges.length < N) {
3869                mActiveUidChanges = new UidRecord.ChangeItem[N];
3870            }
3871            for (int i=0; i<N; i++) {
3872                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3873                mActiveUidChanges[i] = change;
3874                if (change.uidRecord != null) {
3875                    change.uidRecord.pendingChange = null;
3876                    change.uidRecord = null;
3877                }
3878            }
3879            mPendingUidChanges.clear();
3880            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3881                    "*** Delivering " + N + " uid changes");
3882        }
3883
3884        if (mLocalPowerManager != null) {
3885            for (int j=0; j<N; j++) {
3886                UidRecord.ChangeItem item = mActiveUidChanges[j];
3887                if (item.change == UidRecord.CHANGE_GONE
3888                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
3889                    mLocalPowerManager.uidGone(item.uid);
3890                } else {
3891                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3892                }
3893            }
3894        }
3895
3896        int i = mUidObservers.beginBroadcast();
3897        while (i > 0) {
3898            i--;
3899            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3900            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
3901            if (observer != null) {
3902                try {
3903                    for (int j=0; j<N; j++) {
3904                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3905                        final int change = item.change;
3906                        UidRecord validateUid = null;
3907                        if (VALIDATE_UID_STATES && i == 0) {
3908                            validateUid = mValidateUids.get(item.uid);
3909                            if (validateUid == null && change != UidRecord.CHANGE_GONE
3910                                    && change != UidRecord.CHANGE_GONE_IDLE) {
3911                                validateUid = new UidRecord(item.uid);
3912                                mValidateUids.put(item.uid, validateUid);
3913                            }
3914                        }
3915                        if (change == UidRecord.CHANGE_IDLE
3916                                || change == UidRecord.CHANGE_GONE_IDLE) {
3917                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
3918                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3919                                        "UID idle uid=" + item.uid);
3920                                observer.onUidIdle(item.uid);
3921                            }
3922                            if (VALIDATE_UID_STATES && i == 0) {
3923                                if (validateUid != null) {
3924                                    validateUid.idle = true;
3925                                }
3926                            }
3927                        } else if (change == UidRecord.CHANGE_ACTIVE) {
3928                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
3929                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3930                                        "UID active uid=" + item.uid);
3931                                observer.onUidActive(item.uid);
3932                            }
3933                            if (VALIDATE_UID_STATES && i == 0) {
3934                                validateUid.idle = false;
3935                            }
3936                        }
3937                        if (change == UidRecord.CHANGE_GONE
3938                                || change == UidRecord.CHANGE_GONE_IDLE) {
3939                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
3940                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3941                                        "UID gone uid=" + item.uid);
3942                                observer.onUidGone(item.uid);
3943                            }
3944                            if (VALIDATE_UID_STATES && i == 0) {
3945                                if (validateUid != null) {
3946                                    mValidateUids.remove(item.uid);
3947                                }
3948                            }
3949                        } else {
3950                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
3951                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3952                                        "UID CHANGED uid=" + item.uid
3953                                                + ": " + item.processState);
3954                                observer.onUidStateChanged(item.uid, item.processState);
3955                            }
3956                            if (VALIDATE_UID_STATES && i == 0) {
3957                                validateUid.curProcState = validateUid.setProcState
3958                                        = item.processState;
3959                            }
3960                        }
3961                    }
3962                } catch (RemoteException e) {
3963                }
3964            }
3965        }
3966        mUidObservers.finishBroadcast();
3967
3968        synchronized (this) {
3969            for (int j=0; j<N; j++) {
3970                mAvailUidChanges.add(mActiveUidChanges[j]);
3971            }
3972        }
3973    }
3974
3975    @Override
3976    public final int startActivity(IApplicationThread caller, String callingPackage,
3977            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3978            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
3979        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3980                resultWho, requestCode, startFlags, profilerInfo, bOptions,
3981                UserHandle.getCallingUserId());
3982    }
3983
3984    @Override
3985    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3986            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3987            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
3988        enforceNotIsolatedCaller("startActivity");
3989        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3990                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
3991        // TODO: Switch to user app stacks here.
3992        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3993                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3994                profilerInfo, null, null, bOptions, false, userId, null, null);
3995    }
3996
3997    @Override
3998    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3999            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4000            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4001            int userId) {
4002
4003        // This is very dangerous -- it allows you to perform a start activity (including
4004        // permission grants) as any app that may launch one of your own activities.  So
4005        // we will only allow this to be done from activities that are part of the core framework,
4006        // and then only when they are running as the system.
4007        final ActivityRecord sourceRecord;
4008        final int targetUid;
4009        final String targetPackage;
4010        synchronized (this) {
4011            if (resultTo == null) {
4012                throw new SecurityException("Must be called from an activity");
4013            }
4014            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4015            if (sourceRecord == null) {
4016                throw new SecurityException("Called with bad activity token: " + resultTo);
4017            }
4018            if (!sourceRecord.info.packageName.equals("android")) {
4019                throw new SecurityException(
4020                        "Must be called from an activity that is declared in the android package");
4021            }
4022            if (sourceRecord.app == null) {
4023                throw new SecurityException("Called without a process attached to activity");
4024            }
4025            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4026                // This is still okay, as long as this activity is running under the
4027                // uid of the original calling activity.
4028                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4029                    throw new SecurityException(
4030                            "Calling activity in uid " + sourceRecord.app.uid
4031                                    + " must be system uid or original calling uid "
4032                                    + sourceRecord.launchedFromUid);
4033                }
4034            }
4035            if (ignoreTargetSecurity) {
4036                if (intent.getComponent() == null) {
4037                    throw new SecurityException(
4038                            "Component must be specified with ignoreTargetSecurity");
4039                }
4040                if (intent.getSelector() != null) {
4041                    throw new SecurityException(
4042                            "Selector not allowed with ignoreTargetSecurity");
4043                }
4044            }
4045            targetUid = sourceRecord.launchedFromUid;
4046            targetPackage = sourceRecord.launchedFromPackage;
4047        }
4048
4049        if (userId == UserHandle.USER_NULL) {
4050            userId = UserHandle.getUserId(sourceRecord.app.uid);
4051        }
4052
4053        // TODO: Switch to user app stacks here.
4054        try {
4055            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
4056                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4057                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4058            return ret;
4059        } catch (SecurityException e) {
4060            // XXX need to figure out how to propagate to original app.
4061            // A SecurityException here is generally actually a fault of the original
4062            // calling activity (such as a fairly granting permissions), so propagate it
4063            // back to them.
4064            /*
4065            StringBuilder msg = new StringBuilder();
4066            msg.append("While launching");
4067            msg.append(intent.toString());
4068            msg.append(": ");
4069            msg.append(e.getMessage());
4070            */
4071            throw e;
4072        }
4073    }
4074
4075    @Override
4076    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4077            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4078            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4079        enforceNotIsolatedCaller("startActivityAndWait");
4080        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4081                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4082        WaitResult res = new WaitResult();
4083        // TODO: Switch to user app stacks here.
4084        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4085                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4086                bOptions, false, userId, null, null);
4087        return res;
4088    }
4089
4090    @Override
4091    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4092            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4093            int startFlags, Configuration config, Bundle bOptions, int userId) {
4094        enforceNotIsolatedCaller("startActivityWithConfig");
4095        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4096                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4097        // TODO: Switch to user app stacks here.
4098        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
4099                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4100                null, null, config, bOptions, false, userId, null, null);
4101        return ret;
4102    }
4103
4104    @Override
4105    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4106            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4107            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4108            throws TransactionTooLargeException {
4109        enforceNotIsolatedCaller("startActivityIntentSender");
4110        // Refuse possible leaked file descriptors
4111        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4112            throw new IllegalArgumentException("File descriptors passed in Intent");
4113        }
4114
4115        IIntentSender sender = intent.getTarget();
4116        if (!(sender instanceof PendingIntentRecord)) {
4117            throw new IllegalArgumentException("Bad PendingIntent object");
4118        }
4119
4120        PendingIntentRecord pir = (PendingIntentRecord)sender;
4121
4122        synchronized (this) {
4123            // If this is coming from the currently resumed activity, it is
4124            // effectively saying that app switches are allowed at this point.
4125            final ActivityStack stack = getFocusedStack();
4126            if (stack.mResumedActivity != null &&
4127                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4128                mAppSwitchesAllowedTime = 0;
4129            }
4130        }
4131        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4132                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4133        return ret;
4134    }
4135
4136    @Override
4137    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4138            Intent intent, String resolvedType, IVoiceInteractionSession session,
4139            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4140            Bundle bOptions, int userId) {
4141        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4142                != PackageManager.PERMISSION_GRANTED) {
4143            String msg = "Permission Denial: startVoiceActivity() from pid="
4144                    + Binder.getCallingPid()
4145                    + ", uid=" + Binder.getCallingUid()
4146                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4147            Slog.w(TAG, msg);
4148            throw new SecurityException(msg);
4149        }
4150        if (session == null || interactor == null) {
4151            throw new NullPointerException("null session or interactor");
4152        }
4153        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4154                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4155        // TODO: Switch to user app stacks here.
4156        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
4157                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4158                null, bOptions, false, userId, null, null);
4159    }
4160
4161    @Override
4162    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4163        synchronized (this) {
4164            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4165                if (keepAwake) {
4166                    mVoiceWakeLock.acquire();
4167                } else {
4168                    mVoiceWakeLock.release();
4169                }
4170            }
4171        }
4172    }
4173
4174    @Override
4175    public boolean startNextMatchingActivity(IBinder callingActivity,
4176            Intent intent, Bundle bOptions) {
4177        // Refuse possible leaked file descriptors
4178        if (intent != null && intent.hasFileDescriptors() == true) {
4179            throw new IllegalArgumentException("File descriptors passed in Intent");
4180        }
4181        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4182
4183        synchronized (this) {
4184            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4185            if (r == null) {
4186                ActivityOptions.abort(options);
4187                return false;
4188            }
4189            if (r.app == null || r.app.thread == null) {
4190                // The caller is not running...  d'oh!
4191                ActivityOptions.abort(options);
4192                return false;
4193            }
4194            intent = new Intent(intent);
4195            // The caller is not allowed to change the data.
4196            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4197            // And we are resetting to find the next component...
4198            intent.setComponent(null);
4199
4200            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4201
4202            ActivityInfo aInfo = null;
4203            try {
4204                List<ResolveInfo> resolves =
4205                    AppGlobals.getPackageManager().queryIntentActivities(
4206                            intent, r.resolvedType,
4207                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4208                            UserHandle.getCallingUserId());
4209
4210                // Look for the original activity in the list...
4211                final int N = resolves != null ? resolves.size() : 0;
4212                for (int i=0; i<N; i++) {
4213                    ResolveInfo rInfo = resolves.get(i);
4214                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4215                            && rInfo.activityInfo.name.equals(r.info.name)) {
4216                        // We found the current one...  the next matching is
4217                        // after it.
4218                        i++;
4219                        if (i<N) {
4220                            aInfo = resolves.get(i).activityInfo;
4221                        }
4222                        if (debug) {
4223                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4224                                    + "/" + r.info.name);
4225                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4226                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4227                        }
4228                        break;
4229                    }
4230                }
4231            } catch (RemoteException e) {
4232            }
4233
4234            if (aInfo == null) {
4235                // Nobody who is next!
4236                ActivityOptions.abort(options);
4237                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4238                return false;
4239            }
4240
4241            intent.setComponent(new ComponentName(
4242                    aInfo.applicationInfo.packageName, aInfo.name));
4243            intent.setFlags(intent.getFlags()&~(
4244                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4245                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4246                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4247                    Intent.FLAG_ACTIVITY_NEW_TASK));
4248
4249            // Okay now we need to start the new activity, replacing the
4250            // currently running activity.  This is a little tricky because
4251            // we want to start the new one as if the current one is finished,
4252            // but not finish the current one first so that there is no flicker.
4253            // And thus...
4254            final boolean wasFinishing = r.finishing;
4255            r.finishing = true;
4256
4257            // Propagate reply information over to the new activity.
4258            final ActivityRecord resultTo = r.resultTo;
4259            final String resultWho = r.resultWho;
4260            final int requestCode = r.requestCode;
4261            r.resultTo = null;
4262            if (resultTo != null) {
4263                resultTo.removeResultsLocked(r, resultWho, requestCode);
4264            }
4265
4266            final long origId = Binder.clearCallingIdentity();
4267            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4268                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4269                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4270                    -1, r.launchedFromUid, 0, options, false, false, null, null, null);
4271            Binder.restoreCallingIdentity(origId);
4272
4273            r.finishing = wasFinishing;
4274            if (res != ActivityManager.START_SUCCESS) {
4275                return false;
4276            }
4277            return true;
4278        }
4279    }
4280
4281    @Override
4282    public final int startActivityFromRecents(int taskId, int launchStackId, Bundle bOptions) {
4283        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4284            String msg = "Permission Denial: startActivityFromRecents called without " +
4285                    START_TASKS_FROM_RECENTS;
4286            Slog.w(TAG, msg);
4287            throw new SecurityException(msg);
4288        }
4289        final long origId = Binder.clearCallingIdentity();
4290        try {
4291            return startActivityFromRecentsInner(taskId, launchStackId, bOptions);
4292        } finally {
4293            Binder.restoreCallingIdentity(origId);
4294        }
4295    }
4296
4297    final int startActivityFromRecentsInner(int taskId, int launchStackId, Bundle bOptions) {
4298        final TaskRecord task;
4299        final int callingUid;
4300        final String callingPackage;
4301        final Intent intent;
4302        final int userId;
4303        synchronized (this) {
4304            if (launchStackId == HOME_STACK_ID) {
4305                throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4306                        + taskId + " can't be launch in the home stack.");
4307            }
4308
4309            task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4310            if (task == null) {
4311                throw new IllegalArgumentException(
4312                        "startActivityFromRecentsInner: Task " + taskId + " not found.");
4313            }
4314
4315            if (launchStackId != INVALID_STACK_ID) {
4316                if (launchStackId == DOCKED_STACK_ID && bOptions != null) {
4317                    ActivityOptions activityOptions = new ActivityOptions(bOptions);
4318                    mWindowManager.setDockedStackCreateState(activityOptions.getDockCreateMode(),
4319                            null /* initialBounds */);
4320                }
4321                if (task.stack.mStackId != launchStackId) {
4322                    mStackSupervisor.moveTaskToStackLocked(
4323                            taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
4324                            true /* animate */);
4325                }
4326            }
4327
4328            if (task.getRootActivity() != null) {
4329                moveTaskToFrontLocked(task.taskId, 0, bOptions);
4330                return ActivityManager.START_TASK_TO_FRONT;
4331            }
4332            callingUid = task.mCallingUid;
4333            callingPackage = task.mCallingPackage;
4334            intent = task.intent;
4335            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4336            userId = task.userId;
4337        }
4338        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4339                bOptions, userId, null, task);
4340    }
4341
4342    final int startActivityInPackage(int uid, String callingPackage,
4343            Intent intent, String resolvedType, IBinder resultTo,
4344            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4345            IActivityContainer container, TaskRecord inTask) {
4346
4347        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4348                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4349
4350        // TODO: Switch to user app stacks here.
4351        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4352                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4353                null, null, null, bOptions, false, userId, container, inTask);
4354        return ret;
4355    }
4356
4357    @Override
4358    public final int startActivities(IApplicationThread caller, String callingPackage,
4359            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4360            int userId) {
4361        enforceNotIsolatedCaller("startActivities");
4362        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4363                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4364        // TODO: Switch to user app stacks here.
4365        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4366                resolvedTypes, resultTo, bOptions, userId);
4367        return ret;
4368    }
4369
4370    final int startActivitiesInPackage(int uid, String callingPackage,
4371            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4372            Bundle bOptions, int userId) {
4373
4374        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4375                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4376        // TODO: Switch to user app stacks here.
4377        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4378                resultTo, bOptions, userId);
4379        return ret;
4380    }
4381
4382    @Override
4383    public void reportActivityFullyDrawn(IBinder token) {
4384        synchronized (this) {
4385            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4386            if (r == null) {
4387                return;
4388            }
4389            r.reportFullyDrawnLocked();
4390        }
4391    }
4392
4393    @Override
4394    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4395        synchronized (this) {
4396            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4397            if (r == null) {
4398                return;
4399            }
4400            if (r.task != null && r.task.mResizeable) {
4401                // Fixed screen orientation isn't supported with resizeable activities.
4402                return;
4403            }
4404            final long origId = Binder.clearCallingIdentity();
4405            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4406            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4407                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4408            if (config != null) {
4409                r.frozenBeforeDestroy = true;
4410                if (!updateConfigurationLocked(config, r, false)) {
4411                    mStackSupervisor.resumeTopActivitiesLocked();
4412                }
4413            }
4414            Binder.restoreCallingIdentity(origId);
4415        }
4416    }
4417
4418    @Override
4419    public int getRequestedOrientation(IBinder token) {
4420        synchronized (this) {
4421            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4422            if (r == null) {
4423                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4424            }
4425            return mWindowManager.getAppOrientation(r.appToken);
4426        }
4427    }
4428
4429    /**
4430     * This is the internal entry point for handling Activity.finish().
4431     *
4432     * @param token The Binder token referencing the Activity we want to finish.
4433     * @param resultCode Result code, if any, from this Activity.
4434     * @param resultData Result data (Intent), if any, from this Activity.
4435     * @param finishTask Whether to finish the task associated with this Activity.
4436     *
4437     * @return Returns true if the activity successfully finished, or false if it is still running.
4438     */
4439    @Override
4440    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4441            int finishTask) {
4442        // Refuse possible leaked file descriptors
4443        if (resultData != null && resultData.hasFileDescriptors() == true) {
4444            throw new IllegalArgumentException("File descriptors passed in Intent");
4445        }
4446
4447        synchronized(this) {
4448            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4449            if (r == null) {
4450                return true;
4451            }
4452            // Keep track of the root activity of the task before we finish it
4453            TaskRecord tr = r.task;
4454            ActivityRecord rootR = tr.getRootActivity();
4455            if (rootR == null) {
4456                Slog.w(TAG, "Finishing task with all activities already finished");
4457            }
4458            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4459            // finish.
4460            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4461                    mStackSupervisor.isLastLockedTask(tr)) {
4462                Slog.i(TAG, "Not finishing task in lock task mode");
4463                mStackSupervisor.showLockTaskToast();
4464                return false;
4465            }
4466            if (mController != null) {
4467                // Find the first activity that is not finishing.
4468                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4469                if (next != null) {
4470                    // ask watcher if this is allowed
4471                    boolean resumeOK = true;
4472                    try {
4473                        resumeOK = mController.activityResuming(next.packageName);
4474                    } catch (RemoteException e) {
4475                        mController = null;
4476                        Watchdog.getInstance().setActivityController(null);
4477                    }
4478
4479                    if (!resumeOK) {
4480                        Slog.i(TAG, "Not finishing activity because controller resumed");
4481                        return false;
4482                    }
4483                }
4484            }
4485            final long origId = Binder.clearCallingIdentity();
4486            try {
4487                boolean res;
4488                final boolean finishWithRootActivity =
4489                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4490                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4491                        || (finishWithRootActivity && r == rootR)) {
4492                    // If requested, remove the task that is associated to this activity only if it
4493                    // was the root activity in the task. The result code and data is ignored
4494                    // because we don't support returning them across task boundaries. Also, to
4495                    // keep backwards compatibility we remove the task from recents when finishing
4496                    // task with root activity.
4497                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4498                    if (!res) {
4499                        Slog.i(TAG, "Removing task failed to finish activity");
4500                    }
4501                } else {
4502                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4503                            resultData, "app-request", true);
4504                    if (!res) {
4505                        Slog.i(TAG, "Failed to finish by app-request");
4506                    }
4507                }
4508                return res;
4509            } finally {
4510                Binder.restoreCallingIdentity(origId);
4511            }
4512        }
4513    }
4514
4515    @Override
4516    public final void finishHeavyWeightApp() {
4517        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4518                != PackageManager.PERMISSION_GRANTED) {
4519            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4520                    + Binder.getCallingPid()
4521                    + ", uid=" + Binder.getCallingUid()
4522                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4523            Slog.w(TAG, msg);
4524            throw new SecurityException(msg);
4525        }
4526
4527        synchronized(this) {
4528            if (mHeavyWeightProcess == null) {
4529                return;
4530            }
4531
4532            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4533            for (int i = 0; i < activities.size(); i++) {
4534                ActivityRecord r = activities.get(i);
4535                if (!r.finishing && r.isInStackLocked()) {
4536                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4537                            null, "finish-heavy", true);
4538                }
4539            }
4540
4541            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4542                    mHeavyWeightProcess.userId, 0));
4543            mHeavyWeightProcess = null;
4544        }
4545    }
4546
4547    @Override
4548    public void crashApplication(int uid, int initialPid, String packageName,
4549            String message) {
4550        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4551                != PackageManager.PERMISSION_GRANTED) {
4552            String msg = "Permission Denial: crashApplication() from pid="
4553                    + Binder.getCallingPid()
4554                    + ", uid=" + Binder.getCallingUid()
4555                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4556            Slog.w(TAG, msg);
4557            throw new SecurityException(msg);
4558        }
4559
4560        synchronized(this) {
4561            ProcessRecord proc = null;
4562
4563            // Figure out which process to kill.  We don't trust that initialPid
4564            // still has any relation to current pids, so must scan through the
4565            // list.
4566            synchronized (mPidsSelfLocked) {
4567                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4568                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4569                    if (p.uid != uid) {
4570                        continue;
4571                    }
4572                    if (p.pid == initialPid) {
4573                        proc = p;
4574                        break;
4575                    }
4576                    if (p.pkgList.containsKey(packageName)) {
4577                        proc = p;
4578                    }
4579                }
4580            }
4581
4582            if (proc == null) {
4583                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4584                        + " initialPid=" + initialPid
4585                        + " packageName=" + packageName);
4586                return;
4587            }
4588
4589            if (proc.thread != null) {
4590                if (proc.pid == Process.myPid()) {
4591                    Log.w(TAG, "crashApplication: trying to crash self!");
4592                    return;
4593                }
4594                long ident = Binder.clearCallingIdentity();
4595                try {
4596                    proc.thread.scheduleCrash(message);
4597                } catch (RemoteException e) {
4598                }
4599                Binder.restoreCallingIdentity(ident);
4600            }
4601        }
4602    }
4603
4604    @Override
4605    public final void finishSubActivity(IBinder token, String resultWho,
4606            int requestCode) {
4607        synchronized(this) {
4608            final long origId = Binder.clearCallingIdentity();
4609            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4610            if (r != null) {
4611                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4612            }
4613            Binder.restoreCallingIdentity(origId);
4614        }
4615    }
4616
4617    @Override
4618    public boolean finishActivityAffinity(IBinder token) {
4619        synchronized(this) {
4620            final long origId = Binder.clearCallingIdentity();
4621            try {
4622                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4623                if (r == null) {
4624                    return false;
4625                }
4626
4627                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4628                // can finish.
4629                final TaskRecord task = r.task;
4630                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4631                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4632                    mStackSupervisor.showLockTaskToast();
4633                    return false;
4634                }
4635                return task.stack.finishActivityAffinityLocked(r);
4636            } finally {
4637                Binder.restoreCallingIdentity(origId);
4638            }
4639        }
4640    }
4641
4642    @Override
4643    public void finishVoiceTask(IVoiceInteractionSession session) {
4644        synchronized(this) {
4645            final long origId = Binder.clearCallingIdentity();
4646            try {
4647                mStackSupervisor.finishVoiceTask(session);
4648            } finally {
4649                Binder.restoreCallingIdentity(origId);
4650            }
4651        }
4652
4653    }
4654
4655    @Override
4656    public boolean releaseActivityInstance(IBinder token) {
4657        synchronized(this) {
4658            final long origId = Binder.clearCallingIdentity();
4659            try {
4660                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4661                if (r == null) {
4662                    return false;
4663                }
4664                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4665            } finally {
4666                Binder.restoreCallingIdentity(origId);
4667            }
4668        }
4669    }
4670
4671    @Override
4672    public void releaseSomeActivities(IApplicationThread appInt) {
4673        synchronized(this) {
4674            final long origId = Binder.clearCallingIdentity();
4675            try {
4676                ProcessRecord app = getRecordForAppLocked(appInt);
4677                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4678            } finally {
4679                Binder.restoreCallingIdentity(origId);
4680            }
4681        }
4682    }
4683
4684    @Override
4685    public boolean willActivityBeVisible(IBinder token) {
4686        synchronized(this) {
4687            ActivityStack stack = ActivityRecord.getStackLocked(token);
4688            if (stack != null) {
4689                return stack.willActivityBeVisibleLocked(token);
4690            }
4691            return false;
4692        }
4693    }
4694
4695    @Override
4696    public void overridePendingTransition(IBinder token, String packageName,
4697            int enterAnim, int exitAnim) {
4698        synchronized(this) {
4699            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4700            if (self == null) {
4701                return;
4702            }
4703
4704            final long origId = Binder.clearCallingIdentity();
4705
4706            if (self.state == ActivityState.RESUMED
4707                    || self.state == ActivityState.PAUSING) {
4708                mWindowManager.overridePendingAppTransition(packageName,
4709                        enterAnim, exitAnim, null);
4710            }
4711
4712            Binder.restoreCallingIdentity(origId);
4713        }
4714    }
4715
4716    /**
4717     * Main function for removing an existing process from the activity manager
4718     * as a result of that process going away.  Clears out all connections
4719     * to the process.
4720     */
4721    private final void handleAppDiedLocked(ProcessRecord app,
4722            boolean restarting, boolean allowRestart) {
4723        int pid = app.pid;
4724        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4725        if (!kept && !restarting) {
4726            removeLruProcessLocked(app);
4727            if (pid > 0) {
4728                ProcessList.remove(pid);
4729            }
4730        }
4731
4732        if (mProfileProc == app) {
4733            clearProfilerLocked();
4734        }
4735
4736        // Remove this application's activities from active lists.
4737        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4738
4739        app.activities.clear();
4740
4741        if (app.instrumentationClass != null) {
4742            Slog.w(TAG, "Crash of app " + app.processName
4743                  + " running instrumentation " + app.instrumentationClass);
4744            Bundle info = new Bundle();
4745            info.putString("shortMsg", "Process crashed.");
4746            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4747        }
4748
4749        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4750            // If there was nothing to resume, and we are not already
4751            // restarting this process, but there is a visible activity that
4752            // is hosted by the process...  then make sure all visible
4753            // activities are running, taking care of restarting this
4754            // process.
4755            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4756        }
4757    }
4758
4759    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4760        IBinder threadBinder = thread.asBinder();
4761        // Find the application record.
4762        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4763            ProcessRecord rec = mLruProcesses.get(i);
4764            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4765                return i;
4766            }
4767        }
4768        return -1;
4769    }
4770
4771    final ProcessRecord getRecordForAppLocked(
4772            IApplicationThread thread) {
4773        if (thread == null) {
4774            return null;
4775        }
4776
4777        int appIndex = getLRURecordIndexForAppLocked(thread);
4778        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4779    }
4780
4781    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4782        // If there are no longer any background processes running,
4783        // and the app that died was not running instrumentation,
4784        // then tell everyone we are now low on memory.
4785        boolean haveBg = false;
4786        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4787            ProcessRecord rec = mLruProcesses.get(i);
4788            if (rec.thread != null
4789                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4790                haveBg = true;
4791                break;
4792            }
4793        }
4794
4795        if (!haveBg) {
4796            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4797            if (doReport) {
4798                long now = SystemClock.uptimeMillis();
4799                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4800                    doReport = false;
4801                } else {
4802                    mLastMemUsageReportTime = now;
4803                }
4804            }
4805            final ArrayList<ProcessMemInfo> memInfos
4806                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4807            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4808            long now = SystemClock.uptimeMillis();
4809            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4810                ProcessRecord rec = mLruProcesses.get(i);
4811                if (rec == dyingProc || rec.thread == null) {
4812                    continue;
4813                }
4814                if (doReport) {
4815                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4816                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4817                }
4818                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4819                    // The low memory report is overriding any current
4820                    // state for a GC request.  Make sure to do
4821                    // heavy/important/visible/foreground processes first.
4822                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4823                        rec.lastRequestedGc = 0;
4824                    } else {
4825                        rec.lastRequestedGc = rec.lastLowMemory;
4826                    }
4827                    rec.reportLowMemory = true;
4828                    rec.lastLowMemory = now;
4829                    mProcessesToGc.remove(rec);
4830                    addProcessToGcListLocked(rec);
4831                }
4832            }
4833            if (doReport) {
4834                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4835                mHandler.sendMessage(msg);
4836            }
4837            scheduleAppGcsLocked();
4838        }
4839    }
4840
4841    final void appDiedLocked(ProcessRecord app) {
4842       appDiedLocked(app, app.pid, app.thread, false);
4843    }
4844
4845    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4846            boolean fromBinderDied) {
4847        // First check if this ProcessRecord is actually active for the pid.
4848        synchronized (mPidsSelfLocked) {
4849            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4850            if (curProc != app) {
4851                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4852                return;
4853            }
4854        }
4855
4856        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4857        synchronized (stats) {
4858            stats.noteProcessDiedLocked(app.info.uid, pid);
4859        }
4860
4861        if (!app.killed) {
4862            if (!fromBinderDied) {
4863                Process.killProcessQuiet(pid);
4864            }
4865            killProcessGroup(app.info.uid, pid);
4866            app.killed = true;
4867        }
4868
4869        // Clean up already done if the process has been re-started.
4870        if (app.pid == pid && app.thread != null &&
4871                app.thread.asBinder() == thread.asBinder()) {
4872            boolean doLowMem = app.instrumentationClass == null;
4873            boolean doOomAdj = doLowMem;
4874            if (!app.killedByAm) {
4875                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4876                        + ") has died");
4877                mAllowLowerMemLevel = true;
4878            } else {
4879                // Note that we always want to do oom adj to update our state with the
4880                // new number of procs.
4881                mAllowLowerMemLevel = false;
4882                doLowMem = false;
4883            }
4884            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4885            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4886                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4887            handleAppDiedLocked(app, false, true);
4888
4889            if (doOomAdj) {
4890                updateOomAdjLocked();
4891            }
4892            if (doLowMem) {
4893                doLowMemReportIfNeededLocked(app);
4894            }
4895        } else if (app.pid != pid) {
4896            // A new process has already been started.
4897            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4898                    + ") has died and restarted (pid " + app.pid + ").");
4899            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4900        } else if (DEBUG_PROCESSES) {
4901            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4902                    + thread.asBinder());
4903        }
4904    }
4905
4906    /**
4907     * If a stack trace dump file is configured, dump process stack traces.
4908     * @param clearTraces causes the dump file to be erased prior to the new
4909     *    traces being written, if true; when false, the new traces will be
4910     *    appended to any existing file content.
4911     * @param firstPids of dalvik VM processes to dump stack traces for first
4912     * @param lastPids of dalvik VM processes to dump stack traces for last
4913     * @param nativeProcs optional list of native process names to dump stack crawls
4914     * @return file containing stack traces, or null if no dump file is configured
4915     */
4916    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4917            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4918        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4919        if (tracesPath == null || tracesPath.length() == 0) {
4920            return null;
4921        }
4922
4923        File tracesFile = new File(tracesPath);
4924        try {
4925            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4926            tracesFile.createNewFile();
4927            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4928        } catch (IOException e) {
4929            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4930            return null;
4931        }
4932
4933        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4934        return tracesFile;
4935    }
4936
4937    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4938            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4939        // Use a FileObserver to detect when traces finish writing.
4940        // The order of traces is considered important to maintain for legibility.
4941        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4942            @Override
4943            public synchronized void onEvent(int event, String path) { notify(); }
4944        };
4945
4946        try {
4947            observer.startWatching();
4948
4949            // First collect all of the stacks of the most important pids.
4950            if (firstPids != null) {
4951                try {
4952                    int num = firstPids.size();
4953                    for (int i = 0; i < num; i++) {
4954                        synchronized (observer) {
4955                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4956                            observer.wait(200);  // Wait for write-close, give up after 200msec
4957                        }
4958                    }
4959                } catch (InterruptedException e) {
4960                    Slog.wtf(TAG, e);
4961                }
4962            }
4963
4964            // Next collect the stacks of the native pids
4965            if (nativeProcs != null) {
4966                int[] pids = Process.getPidsForCommands(nativeProcs);
4967                if (pids != null) {
4968                    for (int pid : pids) {
4969                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4970                    }
4971                }
4972            }
4973
4974            // Lastly, measure CPU usage.
4975            if (processCpuTracker != null) {
4976                processCpuTracker.init();
4977                System.gc();
4978                processCpuTracker.update();
4979                try {
4980                    synchronized (processCpuTracker) {
4981                        processCpuTracker.wait(500); // measure over 1/2 second.
4982                    }
4983                } catch (InterruptedException e) {
4984                }
4985                processCpuTracker.update();
4986
4987                // We'll take the stack crawls of just the top apps using CPU.
4988                final int N = processCpuTracker.countWorkingStats();
4989                int numProcs = 0;
4990                for (int i=0; i<N && numProcs<5; i++) {
4991                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4992                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4993                        numProcs++;
4994                        try {
4995                            synchronized (observer) {
4996                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4997                                observer.wait(200);  // Wait for write-close, give up after 200msec
4998                            }
4999                        } catch (InterruptedException e) {
5000                            Slog.wtf(TAG, e);
5001                        }
5002
5003                    }
5004                }
5005            }
5006        } finally {
5007            observer.stopWatching();
5008        }
5009    }
5010
5011    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5012        if (true || IS_USER_BUILD) {
5013            return;
5014        }
5015        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5016        if (tracesPath == null || tracesPath.length() == 0) {
5017            return;
5018        }
5019
5020        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5021        StrictMode.allowThreadDiskWrites();
5022        try {
5023            final File tracesFile = new File(tracesPath);
5024            final File tracesDir = tracesFile.getParentFile();
5025            final File tracesTmp = new File(tracesDir, "__tmp__");
5026            try {
5027                if (tracesFile.exists()) {
5028                    tracesTmp.delete();
5029                    tracesFile.renameTo(tracesTmp);
5030                }
5031                StringBuilder sb = new StringBuilder();
5032                Time tobj = new Time();
5033                tobj.set(System.currentTimeMillis());
5034                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5035                sb.append(": ");
5036                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5037                sb.append(" since ");
5038                sb.append(msg);
5039                FileOutputStream fos = new FileOutputStream(tracesFile);
5040                fos.write(sb.toString().getBytes());
5041                if (app == null) {
5042                    fos.write("\n*** No application process!".getBytes());
5043                }
5044                fos.close();
5045                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5046            } catch (IOException e) {
5047                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5048                return;
5049            }
5050
5051            if (app != null) {
5052                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5053                firstPids.add(app.pid);
5054                dumpStackTraces(tracesPath, firstPids, null, null, null);
5055            }
5056
5057            File lastTracesFile = null;
5058            File curTracesFile = null;
5059            for (int i=9; i>=0; i--) {
5060                String name = String.format(Locale.US, "slow%02d.txt", i);
5061                curTracesFile = new File(tracesDir, name);
5062                if (curTracesFile.exists()) {
5063                    if (lastTracesFile != null) {
5064                        curTracesFile.renameTo(lastTracesFile);
5065                    } else {
5066                        curTracesFile.delete();
5067                    }
5068                }
5069                lastTracesFile = curTracesFile;
5070            }
5071            tracesFile.renameTo(curTracesFile);
5072            if (tracesTmp.exists()) {
5073                tracesTmp.renameTo(tracesFile);
5074            }
5075        } finally {
5076            StrictMode.setThreadPolicy(oldPolicy);
5077        }
5078    }
5079
5080    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5081            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5082        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5083        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5084
5085        if (mController != null) {
5086            try {
5087                // 0 == continue, -1 = kill process immediately
5088                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5089                if (res < 0 && app.pid != MY_PID) {
5090                    app.kill("anr", true);
5091                }
5092            } catch (RemoteException e) {
5093                mController = null;
5094                Watchdog.getInstance().setActivityController(null);
5095            }
5096        }
5097
5098        long anrTime = SystemClock.uptimeMillis();
5099        if (MONITOR_CPU_USAGE) {
5100            updateCpuStatsNow();
5101        }
5102
5103        synchronized (this) {
5104            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5105            if (mShuttingDown) {
5106                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5107                return;
5108            } else if (app.notResponding) {
5109                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5110                return;
5111            } else if (app.crashing) {
5112                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5113                return;
5114            }
5115
5116            // In case we come through here for the same app before completing
5117            // this one, mark as anring now so we will bail out.
5118            app.notResponding = true;
5119
5120            // Log the ANR to the event log.
5121            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5122                    app.processName, app.info.flags, annotation);
5123
5124            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5125            firstPids.add(app.pid);
5126
5127            int parentPid = app.pid;
5128            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5129            if (parentPid != app.pid) firstPids.add(parentPid);
5130
5131            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5132
5133            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5134                ProcessRecord r = mLruProcesses.get(i);
5135                if (r != null && r.thread != null) {
5136                    int pid = r.pid;
5137                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5138                        if (r.persistent) {
5139                            firstPids.add(pid);
5140                        } else {
5141                            lastPids.put(pid, Boolean.TRUE);
5142                        }
5143                    }
5144                }
5145            }
5146        }
5147
5148        // Log the ANR to the main log.
5149        StringBuilder info = new StringBuilder();
5150        info.setLength(0);
5151        info.append("ANR in ").append(app.processName);
5152        if (activity != null && activity.shortComponentName != null) {
5153            info.append(" (").append(activity.shortComponentName).append(")");
5154        }
5155        info.append("\n");
5156        info.append("PID: ").append(app.pid).append("\n");
5157        if (annotation != null) {
5158            info.append("Reason: ").append(annotation).append("\n");
5159        }
5160        if (parent != null && parent != activity) {
5161            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5162        }
5163
5164        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5165
5166        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5167                NATIVE_STACKS_OF_INTEREST);
5168
5169        String cpuInfo = null;
5170        if (MONITOR_CPU_USAGE) {
5171            updateCpuStatsNow();
5172            synchronized (mProcessCpuTracker) {
5173                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5174            }
5175            info.append(processCpuTracker.printCurrentLoad());
5176            info.append(cpuInfo);
5177        }
5178
5179        info.append(processCpuTracker.printCurrentState(anrTime));
5180
5181        Slog.e(TAG, info.toString());
5182        if (tracesFile == null) {
5183            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5184            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5185        }
5186
5187        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5188                cpuInfo, tracesFile, null);
5189
5190        if (mController != null) {
5191            try {
5192                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5193                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5194                if (res != 0) {
5195                    if (res < 0 && app.pid != MY_PID) {
5196                        app.kill("anr", true);
5197                    } else {
5198                        synchronized (this) {
5199                            mServices.scheduleServiceTimeoutLocked(app);
5200                        }
5201                    }
5202                    return;
5203                }
5204            } catch (RemoteException e) {
5205                mController = null;
5206                Watchdog.getInstance().setActivityController(null);
5207            }
5208        }
5209
5210        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5211        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5212                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5213
5214        synchronized (this) {
5215            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5216
5217            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5218                app.kill("bg anr", true);
5219                return;
5220            }
5221
5222            // Set the app's notResponding state, and look up the errorReportReceiver
5223            makeAppNotRespondingLocked(app,
5224                    activity != null ? activity.shortComponentName : null,
5225                    annotation != null ? "ANR " + annotation : "ANR",
5226                    info.toString());
5227
5228            // Bring up the infamous App Not Responding dialog
5229            Message msg = Message.obtain();
5230            HashMap<String, Object> map = new HashMap<String, Object>();
5231            msg.what = SHOW_NOT_RESPONDING_UI_MSG;
5232            msg.obj = map;
5233            msg.arg1 = aboveSystem ? 1 : 0;
5234            map.put("app", app);
5235            if (activity != null) {
5236                map.put("activity", activity);
5237            }
5238
5239            mUiHandler.sendMessage(msg);
5240        }
5241    }
5242
5243    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5244        if (!mLaunchWarningShown) {
5245            mLaunchWarningShown = true;
5246            mUiHandler.post(new Runnable() {
5247                @Override
5248                public void run() {
5249                    synchronized (ActivityManagerService.this) {
5250                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5251                        d.show();
5252                        mUiHandler.postDelayed(new Runnable() {
5253                            @Override
5254                            public void run() {
5255                                synchronized (ActivityManagerService.this) {
5256                                    d.dismiss();
5257                                    mLaunchWarningShown = false;
5258                                }
5259                            }
5260                        }, 4000);
5261                    }
5262                }
5263            });
5264        }
5265    }
5266
5267    @Override
5268    public boolean clearApplicationUserData(final String packageName,
5269            final IPackageDataObserver observer, int userId) {
5270        enforceNotIsolatedCaller("clearApplicationUserData");
5271        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5272            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5273        }
5274        int uid = Binder.getCallingUid();
5275        int pid = Binder.getCallingPid();
5276        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5277                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5278        long callingId = Binder.clearCallingIdentity();
5279        try {
5280            IPackageManager pm = AppGlobals.getPackageManager();
5281            int pkgUid = -1;
5282            synchronized(this) {
5283                try {
5284                    pkgUid = pm.getPackageUid(packageName, userId);
5285                } catch (RemoteException e) {
5286                }
5287                if (pkgUid == -1) {
5288                    Slog.w(TAG, "Invalid packageName: " + packageName);
5289                    if (observer != null) {
5290                        try {
5291                            observer.onRemoveCompleted(packageName, false);
5292                        } catch (RemoteException e) {
5293                            Slog.i(TAG, "Observer no longer exists.");
5294                        }
5295                    }
5296                    return false;
5297                }
5298                if (uid == pkgUid || checkComponentPermission(
5299                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5300                        pid, uid, -1, true)
5301                        == PackageManager.PERMISSION_GRANTED) {
5302                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5303                } else {
5304                    throw new SecurityException("PID " + pid + " does not have permission "
5305                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5306                                    + " of package " + packageName);
5307                }
5308
5309                // Remove all tasks match the cleared application package and user
5310                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5311                    final TaskRecord tr = mRecentTasks.get(i);
5312                    final String taskPackageName =
5313                            tr.getBaseIntent().getComponent().getPackageName();
5314                    if (tr.userId != userId) continue;
5315                    if (!taskPackageName.equals(packageName)) continue;
5316                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5317                }
5318            }
5319
5320            try {
5321                // Clear application user data
5322                pm.clearApplicationUserData(packageName, observer, userId);
5323
5324                synchronized(this) {
5325                    // Remove all permissions granted from/to this package
5326                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5327                }
5328
5329                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5330                        Uri.fromParts("package", packageName, null));
5331                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5332                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5333                        null, null, 0, null, null, null, null, false, false, userId);
5334            } catch (RemoteException e) {
5335            }
5336        } finally {
5337            Binder.restoreCallingIdentity(callingId);
5338        }
5339        return true;
5340    }
5341
5342    @Override
5343    public void killBackgroundProcesses(final String packageName, int userId) {
5344        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5345                != PackageManager.PERMISSION_GRANTED &&
5346                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5347                        != PackageManager.PERMISSION_GRANTED) {
5348            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5349                    + Binder.getCallingPid()
5350                    + ", uid=" + Binder.getCallingUid()
5351                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5352            Slog.w(TAG, msg);
5353            throw new SecurityException(msg);
5354        }
5355
5356        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5357                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5358        long callingId = Binder.clearCallingIdentity();
5359        try {
5360            IPackageManager pm = AppGlobals.getPackageManager();
5361            synchronized(this) {
5362                int appId = -1;
5363                try {
5364                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5365                } catch (RemoteException e) {
5366                }
5367                if (appId == -1) {
5368                    Slog.w(TAG, "Invalid packageName: " + packageName);
5369                    return;
5370                }
5371                killPackageProcessesLocked(packageName, appId, userId,
5372                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5373            }
5374        } finally {
5375            Binder.restoreCallingIdentity(callingId);
5376        }
5377    }
5378
5379    @Override
5380    public void killAllBackgroundProcesses() {
5381        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5382                != PackageManager.PERMISSION_GRANTED) {
5383            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5384                    + Binder.getCallingPid()
5385                    + ", uid=" + Binder.getCallingUid()
5386                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5387            Slog.w(TAG, msg);
5388            throw new SecurityException(msg);
5389        }
5390
5391        long callingId = Binder.clearCallingIdentity();
5392        try {
5393            synchronized(this) {
5394                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5395                final int NP = mProcessNames.getMap().size();
5396                for (int ip=0; ip<NP; ip++) {
5397                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5398                    final int NA = apps.size();
5399                    for (int ia=0; ia<NA; ia++) {
5400                        ProcessRecord app = apps.valueAt(ia);
5401                        if (app.persistent) {
5402                            // we don't kill persistent processes
5403                            continue;
5404                        }
5405                        if (app.removed) {
5406                            procs.add(app);
5407                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5408                            app.removed = true;
5409                            procs.add(app);
5410                        }
5411                    }
5412                }
5413
5414                int N = procs.size();
5415                for (int i=0; i<N; i++) {
5416                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5417                }
5418                mAllowLowerMemLevel = true;
5419                updateOomAdjLocked();
5420                doLowMemReportIfNeededLocked(null);
5421            }
5422        } finally {
5423            Binder.restoreCallingIdentity(callingId);
5424        }
5425    }
5426
5427    @Override
5428    public void forceStopPackage(final String packageName, int userId) {
5429        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5430                != PackageManager.PERMISSION_GRANTED) {
5431            String msg = "Permission Denial: forceStopPackage() from pid="
5432                    + Binder.getCallingPid()
5433                    + ", uid=" + Binder.getCallingUid()
5434                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5435            Slog.w(TAG, msg);
5436            throw new SecurityException(msg);
5437        }
5438        final int callingPid = Binder.getCallingPid();
5439        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5440                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5441        long callingId = Binder.clearCallingIdentity();
5442        try {
5443            IPackageManager pm = AppGlobals.getPackageManager();
5444            synchronized(this) {
5445                int[] users = userId == UserHandle.USER_ALL
5446                        ? mUserController.getUsers() : new int[] { userId };
5447                for (int user : users) {
5448                    int pkgUid = -1;
5449                    try {
5450                        pkgUid = pm.getPackageUid(packageName, user);
5451                    } catch (RemoteException e) {
5452                    }
5453                    if (pkgUid == -1) {
5454                        Slog.w(TAG, "Invalid packageName: " + packageName);
5455                        continue;
5456                    }
5457                    try {
5458                        pm.setPackageStoppedState(packageName, true, user);
5459                    } catch (RemoteException e) {
5460                    } catch (IllegalArgumentException e) {
5461                        Slog.w(TAG, "Failed trying to unstop package "
5462                                + packageName + ": " + e);
5463                    }
5464                    if (mUserController.isUserRunningLocked(user, 0)) {
5465                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5466                    }
5467                }
5468            }
5469        } finally {
5470            Binder.restoreCallingIdentity(callingId);
5471        }
5472    }
5473
5474    @Override
5475    public void addPackageDependency(String packageName) {
5476        synchronized (this) {
5477            int callingPid = Binder.getCallingPid();
5478            if (callingPid == Process.myPid()) {
5479                //  Yeah, um, no.
5480                return;
5481            }
5482            ProcessRecord proc;
5483            synchronized (mPidsSelfLocked) {
5484                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5485            }
5486            if (proc != null) {
5487                if (proc.pkgDeps == null) {
5488                    proc.pkgDeps = new ArraySet<String>(1);
5489                }
5490                proc.pkgDeps.add(packageName);
5491            }
5492        }
5493    }
5494
5495    /*
5496     * The pkg name and app id have to be specified.
5497     */
5498    @Override
5499    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5500        if (pkg == null) {
5501            return;
5502        }
5503        // Make sure the uid is valid.
5504        if (appid < 0) {
5505            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5506            return;
5507        }
5508        int callerUid = Binder.getCallingUid();
5509        // Only the system server can kill an application
5510        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5511            // Post an aysnc message to kill the application
5512            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5513            msg.arg1 = appid;
5514            msg.arg2 = 0;
5515            Bundle bundle = new Bundle();
5516            bundle.putString("pkg", pkg);
5517            bundle.putString("reason", reason);
5518            msg.obj = bundle;
5519            mHandler.sendMessage(msg);
5520        } else {
5521            throw new SecurityException(callerUid + " cannot kill pkg: " +
5522                    pkg);
5523        }
5524    }
5525
5526    @Override
5527    public void closeSystemDialogs(String reason) {
5528        enforceNotIsolatedCaller("closeSystemDialogs");
5529
5530        final int pid = Binder.getCallingPid();
5531        final int uid = Binder.getCallingUid();
5532        final long origId = Binder.clearCallingIdentity();
5533        try {
5534            synchronized (this) {
5535                // Only allow this from foreground processes, so that background
5536                // applications can't abuse it to prevent system UI from being shown.
5537                if (uid >= Process.FIRST_APPLICATION_UID) {
5538                    ProcessRecord proc;
5539                    synchronized (mPidsSelfLocked) {
5540                        proc = mPidsSelfLocked.get(pid);
5541                    }
5542                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5543                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5544                                + " from background process " + proc);
5545                        return;
5546                    }
5547                }
5548                closeSystemDialogsLocked(reason);
5549            }
5550        } finally {
5551            Binder.restoreCallingIdentity(origId);
5552        }
5553    }
5554
5555    void closeSystemDialogsLocked(String reason) {
5556        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5557        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5558                | Intent.FLAG_RECEIVER_FOREGROUND);
5559        if (reason != null) {
5560            intent.putExtra("reason", reason);
5561        }
5562        mWindowManager.closeSystemDialogs(reason);
5563
5564        mStackSupervisor.closeSystemDialogsLocked();
5565
5566        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5567                AppOpsManager.OP_NONE, null, false, false,
5568                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5569    }
5570
5571    @Override
5572    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5573        enforceNotIsolatedCaller("getProcessMemoryInfo");
5574        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5575        for (int i=pids.length-1; i>=0; i--) {
5576            ProcessRecord proc;
5577            int oomAdj;
5578            synchronized (this) {
5579                synchronized (mPidsSelfLocked) {
5580                    proc = mPidsSelfLocked.get(pids[i]);
5581                    oomAdj = proc != null ? proc.setAdj : 0;
5582                }
5583            }
5584            infos[i] = new Debug.MemoryInfo();
5585            Debug.getMemoryInfo(pids[i], infos[i]);
5586            if (proc != null) {
5587                synchronized (this) {
5588                    if (proc.thread != null && proc.setAdj == oomAdj) {
5589                        // Record this for posterity if the process has been stable.
5590                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5591                                infos[i].getTotalUss(), false, proc.pkgList);
5592                    }
5593                }
5594            }
5595        }
5596        return infos;
5597    }
5598
5599    @Override
5600    public long[] getProcessPss(int[] pids) {
5601        enforceNotIsolatedCaller("getProcessPss");
5602        long[] pss = new long[pids.length];
5603        for (int i=pids.length-1; i>=0; i--) {
5604            ProcessRecord proc;
5605            int oomAdj;
5606            synchronized (this) {
5607                synchronized (mPidsSelfLocked) {
5608                    proc = mPidsSelfLocked.get(pids[i]);
5609                    oomAdj = proc != null ? proc.setAdj : 0;
5610                }
5611            }
5612            long[] tmpUss = new long[1];
5613            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5614            if (proc != null) {
5615                synchronized (this) {
5616                    if (proc.thread != null && proc.setAdj == oomAdj) {
5617                        // Record this for posterity if the process has been stable.
5618                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5619                    }
5620                }
5621            }
5622        }
5623        return pss;
5624    }
5625
5626    @Override
5627    public void killApplicationProcess(String processName, int uid) {
5628        if (processName == null) {
5629            return;
5630        }
5631
5632        int callerUid = Binder.getCallingUid();
5633        // Only the system server can kill an application
5634        if (callerUid == Process.SYSTEM_UID) {
5635            synchronized (this) {
5636                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5637                if (app != null && app.thread != null) {
5638                    try {
5639                        app.thread.scheduleSuicide();
5640                    } catch (RemoteException e) {
5641                        // If the other end already died, then our work here is done.
5642                    }
5643                } else {
5644                    Slog.w(TAG, "Process/uid not found attempting kill of "
5645                            + processName + " / " + uid);
5646                }
5647            }
5648        } else {
5649            throw new SecurityException(callerUid + " cannot kill app process: " +
5650                    processName);
5651        }
5652    }
5653
5654    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5655        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5656                false, true, false, false, UserHandle.getUserId(uid), reason);
5657        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5658                Uri.fromParts("package", packageName, null));
5659        if (!mProcessesReady) {
5660            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5661                    | Intent.FLAG_RECEIVER_FOREGROUND);
5662        }
5663        intent.putExtra(Intent.EXTRA_UID, uid);
5664        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5665        broadcastIntentLocked(null, null, intent,
5666                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5667                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5668    }
5669
5670
5671    private final boolean killPackageProcessesLocked(String packageName, int appId,
5672            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5673            boolean doit, boolean evenPersistent, String reason) {
5674        ArrayList<ProcessRecord> procs = new ArrayList<>();
5675
5676        // Remove all processes this package may have touched: all with the
5677        // same UID (except for the system or root user), and all whose name
5678        // matches the package name.
5679        final int NP = mProcessNames.getMap().size();
5680        for (int ip=0; ip<NP; ip++) {
5681            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5682            final int NA = apps.size();
5683            for (int ia=0; ia<NA; ia++) {
5684                ProcessRecord app = apps.valueAt(ia);
5685                if (app.persistent && !evenPersistent) {
5686                    // we don't kill persistent processes
5687                    continue;
5688                }
5689                if (app.removed) {
5690                    if (doit) {
5691                        procs.add(app);
5692                    }
5693                    continue;
5694                }
5695
5696                // Skip process if it doesn't meet our oom adj requirement.
5697                if (app.setAdj < minOomAdj) {
5698                    continue;
5699                }
5700
5701                // If no package is specified, we call all processes under the
5702                // give user id.
5703                if (packageName == null) {
5704                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5705                        continue;
5706                    }
5707                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5708                        continue;
5709                    }
5710                // Package has been specified, we want to hit all processes
5711                // that match it.  We need to qualify this by the processes
5712                // that are running under the specified app and user ID.
5713                } else {
5714                    final boolean isDep = app.pkgDeps != null
5715                            && app.pkgDeps.contains(packageName);
5716                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5717                        continue;
5718                    }
5719                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5720                        continue;
5721                    }
5722                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5723                        continue;
5724                    }
5725                }
5726
5727                // Process has passed all conditions, kill it!
5728                if (!doit) {
5729                    return true;
5730                }
5731                app.removed = true;
5732                procs.add(app);
5733            }
5734        }
5735
5736        int N = procs.size();
5737        for (int i=0; i<N; i++) {
5738            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5739        }
5740        updateOomAdjLocked();
5741        return N > 0;
5742    }
5743
5744    private void cleanupDisabledPackageComponentsLocked(
5745            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5746
5747        Set<String> disabledClasses = null;
5748        boolean packageDisabled = false;
5749        IPackageManager pm = AppGlobals.getPackageManager();
5750
5751        if (changedClasses == null) {
5752            // Nothing changed...
5753            return;
5754        }
5755
5756        // Determine enable/disable state of the package and its components.
5757        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5758        for (int i = changedClasses.length - 1; i >= 0; i--) {
5759            final String changedClass = changedClasses[i];
5760
5761            if (changedClass.equals(packageName)) {
5762                try {
5763                    // Entire package setting changed
5764                    enabled = pm.getApplicationEnabledSetting(packageName,
5765                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5766                } catch (Exception e) {
5767                    // No such package/component; probably racing with uninstall.  In any
5768                    // event it means we have nothing further to do here.
5769                    return;
5770                }
5771                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5772                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5773                if (packageDisabled) {
5774                    // Entire package is disabled.
5775                    // No need to continue to check component states.
5776                    disabledClasses = null;
5777                    break;
5778                }
5779            } else {
5780                try {
5781                    enabled = pm.getComponentEnabledSetting(
5782                            new ComponentName(packageName, changedClass),
5783                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5784                } catch (Exception e) {
5785                    // As above, probably racing with uninstall.
5786                    return;
5787                }
5788                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5789                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5790                    if (disabledClasses == null) {
5791                        disabledClasses = new ArraySet<>(changedClasses.length);
5792                    }
5793                    disabledClasses.add(changedClass);
5794                }
5795            }
5796        }
5797
5798        if (!packageDisabled && disabledClasses == null) {
5799            // Nothing to do here...
5800            return;
5801        }
5802
5803        // Clean-up disabled activities.
5804        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5805                packageName, disabledClasses, true, false, userId) && mBooted) {
5806            mStackSupervisor.resumeTopActivitiesLocked();
5807            mStackSupervisor.scheduleIdleLocked();
5808        }
5809
5810        // Clean-up disabled tasks
5811        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5812
5813        // Clean-up disabled services.
5814        mServices.bringDownDisabledPackageServicesLocked(
5815                packageName, disabledClasses, userId, false, killProcess, true);
5816
5817        // Clean-up disabled providers.
5818        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5819        mProviderMap.collectPackageProvidersLocked(
5820                packageName, disabledClasses, true, false, userId, providers);
5821        for (int i = providers.size() - 1; i >= 0; i--) {
5822            removeDyingProviderLocked(null, providers.get(i), true);
5823        }
5824
5825        // Clean-up disabled broadcast receivers.
5826        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5827            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5828                    packageName, disabledClasses, userId, true);
5829        }
5830
5831    }
5832
5833    final boolean forceStopPackageLocked(String packageName, int appId,
5834            boolean callerWillRestart, boolean purgeCache, boolean doit,
5835            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5836        int i;
5837
5838        if (userId == UserHandle.USER_ALL && packageName == null) {
5839            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5840        }
5841
5842        if (appId < 0 && packageName != null) {
5843            try {
5844                appId = UserHandle.getAppId(
5845                        AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5846            } catch (RemoteException e) {
5847            }
5848        }
5849
5850        if (doit) {
5851            if (packageName != null) {
5852                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5853                        + " user=" + userId + ": " + reason);
5854            } else {
5855                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5856            }
5857
5858            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5859            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5860                SparseArray<Long> ba = pmap.valueAt(ip);
5861                for (i = ba.size() - 1; i >= 0; i--) {
5862                    boolean remove = false;
5863                    final int entUid = ba.keyAt(i);
5864                    if (packageName != null) {
5865                        if (userId == UserHandle.USER_ALL) {
5866                            if (UserHandle.getAppId(entUid) == appId) {
5867                                remove = true;
5868                            }
5869                        } else {
5870                            if (entUid == UserHandle.getUid(userId, appId)) {
5871                                remove = true;
5872                            }
5873                        }
5874                    } else if (UserHandle.getUserId(entUid) == userId) {
5875                        remove = true;
5876                    }
5877                    if (remove) {
5878                        ba.removeAt(i);
5879                    }
5880                }
5881                if (ba.size() == 0) {
5882                    pmap.removeAt(ip);
5883                }
5884            }
5885        }
5886
5887        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5888                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5889                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5890
5891        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5892                packageName, null, doit, evenPersistent, userId)) {
5893            if (!doit) {
5894                return true;
5895            }
5896            didSomething = true;
5897        }
5898
5899        if (mServices.bringDownDisabledPackageServicesLocked(
5900                packageName, null, userId, evenPersistent, true, doit)) {
5901            if (!doit) {
5902                return true;
5903            }
5904            didSomething = true;
5905        }
5906
5907        if (packageName == null) {
5908            // Remove all sticky broadcasts from this user.
5909            mStickyBroadcasts.remove(userId);
5910        }
5911
5912        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5913        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5914                userId, providers)) {
5915            if (!doit) {
5916                return true;
5917            }
5918            didSomething = true;
5919        }
5920        for (i = providers.size() - 1; i >= 0; i--) {
5921            removeDyingProviderLocked(null, providers.get(i), true);
5922        }
5923
5924        // Remove transient permissions granted from/to this package/user
5925        removeUriPermissionsForPackageLocked(packageName, userId, false);
5926
5927        if (doit) {
5928            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5929                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5930                        packageName, null, userId, doit);
5931            }
5932        }
5933
5934        if (packageName == null || uninstalling) {
5935            // Remove pending intents.  For now we only do this when force
5936            // stopping users, because we have some problems when doing this
5937            // for packages -- app widgets are not currently cleaned up for
5938            // such packages, so they can be left with bad pending intents.
5939            if (mIntentSenderRecords.size() > 0) {
5940                Iterator<WeakReference<PendingIntentRecord>> it
5941                        = mIntentSenderRecords.values().iterator();
5942                while (it.hasNext()) {
5943                    WeakReference<PendingIntentRecord> wpir = it.next();
5944                    if (wpir == null) {
5945                        it.remove();
5946                        continue;
5947                    }
5948                    PendingIntentRecord pir = wpir.get();
5949                    if (pir == null) {
5950                        it.remove();
5951                        continue;
5952                    }
5953                    if (packageName == null) {
5954                        // Stopping user, remove all objects for the user.
5955                        if (pir.key.userId != userId) {
5956                            // Not the same user, skip it.
5957                            continue;
5958                        }
5959                    } else {
5960                        if (UserHandle.getAppId(pir.uid) != appId) {
5961                            // Different app id, skip it.
5962                            continue;
5963                        }
5964                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5965                            // Different user, skip it.
5966                            continue;
5967                        }
5968                        if (!pir.key.packageName.equals(packageName)) {
5969                            // Different package, skip it.
5970                            continue;
5971                        }
5972                    }
5973                    if (!doit) {
5974                        return true;
5975                    }
5976                    didSomething = true;
5977                    it.remove();
5978                    pir.canceled = true;
5979                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5980                        pir.key.activity.pendingResults.remove(pir.ref);
5981                    }
5982                }
5983            }
5984        }
5985
5986        if (doit) {
5987            if (purgeCache && packageName != null) {
5988                AttributeCache ac = AttributeCache.instance();
5989                if (ac != null) {
5990                    ac.removePackage(packageName);
5991                }
5992            }
5993            if (mBooted) {
5994                mStackSupervisor.resumeTopActivitiesLocked();
5995                mStackSupervisor.scheduleIdleLocked();
5996            }
5997        }
5998
5999        return didSomething;
6000    }
6001
6002    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6003        ProcessRecord old = mProcessNames.remove(name, uid);
6004        if (old != null) {
6005            old.uidRecord.numProcs--;
6006            if (old.uidRecord.numProcs == 0) {
6007                // No more processes using this uid, tell clients it is gone.
6008                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6009                        "No more processes in " + old.uidRecord);
6010                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6011                mActiveUids.remove(uid);
6012            }
6013            old.uidRecord = null;
6014        }
6015        mIsolatedProcesses.remove(uid);
6016        return old;
6017    }
6018
6019    private final void addProcessNameLocked(ProcessRecord proc) {
6020        // We shouldn't already have a process under this name, but just in case we
6021        // need to clean up whatever may be there now.
6022        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6023        if (old == proc && proc.persistent) {
6024            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6025            Slog.w(TAG, "Re-adding persistent process " + proc);
6026        } else if (old != null) {
6027            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6028        }
6029        UidRecord uidRec = mActiveUids.get(proc.uid);
6030        if (uidRec == null) {
6031            uidRec = new UidRecord(proc.uid);
6032            // This is the first appearance of the uid, report it now!
6033            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6034                    "Creating new process uid: " + uidRec);
6035            mActiveUids.put(proc.uid, uidRec);
6036            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6037        }
6038        proc.uidRecord = uidRec;
6039        uidRec.numProcs++;
6040        mProcessNames.put(proc.processName, proc.uid, proc);
6041        if (proc.isolated) {
6042            mIsolatedProcesses.put(proc.uid, proc);
6043        }
6044    }
6045
6046    private final boolean removeProcessLocked(ProcessRecord app,
6047            boolean callerWillRestart, boolean allowRestart, String reason) {
6048        final String name = app.processName;
6049        final int uid = app.uid;
6050        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6051            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6052
6053        removeProcessNameLocked(name, uid);
6054        if (mHeavyWeightProcess == app) {
6055            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6056                    mHeavyWeightProcess.userId, 0));
6057            mHeavyWeightProcess = null;
6058        }
6059        boolean needRestart = false;
6060        if (app.pid > 0 && app.pid != MY_PID) {
6061            int pid = app.pid;
6062            synchronized (mPidsSelfLocked) {
6063                mPidsSelfLocked.remove(pid);
6064                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6065            }
6066            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6067            if (app.isolated) {
6068                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6069            }
6070            boolean willRestart = false;
6071            if (app.persistent && !app.isolated) {
6072                if (!callerWillRestart) {
6073                    willRestart = true;
6074                } else {
6075                    needRestart = true;
6076                }
6077            }
6078            app.kill(reason, true);
6079            handleAppDiedLocked(app, willRestart, allowRestart);
6080            if (willRestart) {
6081                removeLruProcessLocked(app);
6082                addAppLocked(app.info, false, null /* ABI override */);
6083            }
6084        } else {
6085            mRemovedProcesses.add(app);
6086        }
6087
6088        return needRestart;
6089    }
6090
6091    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6092        cleanupAppInLaunchingProvidersLocked(app, true);
6093        removeProcessLocked(app, false, true, "timeout publishing content providers");
6094    }
6095
6096    private final void processStartTimedOutLocked(ProcessRecord app) {
6097        final int pid = app.pid;
6098        boolean gone = false;
6099        synchronized (mPidsSelfLocked) {
6100            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6101            if (knownApp != null && knownApp.thread == null) {
6102                mPidsSelfLocked.remove(pid);
6103                gone = true;
6104            }
6105        }
6106
6107        if (gone) {
6108            Slog.w(TAG, "Process " + app + " failed to attach");
6109            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6110                    pid, app.uid, app.processName);
6111            removeProcessNameLocked(app.processName, app.uid);
6112            if (mHeavyWeightProcess == app) {
6113                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6114                        mHeavyWeightProcess.userId, 0));
6115                mHeavyWeightProcess = null;
6116            }
6117            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6118            if (app.isolated) {
6119                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6120            }
6121            // Take care of any launching providers waiting for this process.
6122            cleanupAppInLaunchingProvidersLocked(app, true);
6123            // Take care of any services that are waiting for the process.
6124            mServices.processStartTimedOutLocked(app);
6125            app.kill("start timeout", true);
6126            removeLruProcessLocked(app);
6127            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6128                Slog.w(TAG, "Unattached app died before backup, skipping");
6129                try {
6130                    IBackupManager bm = IBackupManager.Stub.asInterface(
6131                            ServiceManager.getService(Context.BACKUP_SERVICE));
6132                    bm.agentDisconnected(app.info.packageName);
6133                } catch (RemoteException e) {
6134                    // Can't happen; the backup manager is local
6135                }
6136            }
6137            if (isPendingBroadcastProcessLocked(pid)) {
6138                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6139                skipPendingBroadcastLocked(pid);
6140            }
6141        } else {
6142            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6143        }
6144    }
6145
6146    private final boolean attachApplicationLocked(IApplicationThread thread,
6147            int pid) {
6148
6149        // Find the application record that is being attached...  either via
6150        // the pid if we are running in multiple processes, or just pull the
6151        // next app record if we are emulating process with anonymous threads.
6152        ProcessRecord app;
6153        if (pid != MY_PID && pid >= 0) {
6154            synchronized (mPidsSelfLocked) {
6155                app = mPidsSelfLocked.get(pid);
6156            }
6157        } else {
6158            app = null;
6159        }
6160
6161        if (app == null) {
6162            Slog.w(TAG, "No pending application record for pid " + pid
6163                    + " (IApplicationThread " + thread + "); dropping process");
6164            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6165            if (pid > 0 && pid != MY_PID) {
6166                Process.killProcessQuiet(pid);
6167                //TODO: killProcessGroup(app.info.uid, pid);
6168            } else {
6169                try {
6170                    thread.scheduleExit();
6171                } catch (Exception e) {
6172                    // Ignore exceptions.
6173                }
6174            }
6175            return false;
6176        }
6177
6178        // If this application record is still attached to a previous
6179        // process, clean it up now.
6180        if (app.thread != null) {
6181            handleAppDiedLocked(app, true, true);
6182        }
6183
6184        // Tell the process all about itself.
6185
6186        if (DEBUG_ALL) Slog.v(
6187                TAG, "Binding process pid " + pid + " to record " + app);
6188
6189        final String processName = app.processName;
6190        try {
6191            AppDeathRecipient adr = new AppDeathRecipient(
6192                    app, pid, thread);
6193            thread.asBinder().linkToDeath(adr, 0);
6194            app.deathRecipient = adr;
6195        } catch (RemoteException e) {
6196            app.resetPackageList(mProcessStats);
6197            startProcessLocked(app, "link fail", processName);
6198            return false;
6199        }
6200
6201        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6202
6203        app.makeActive(thread, mProcessStats);
6204        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6205        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6206        app.forcingToForeground = null;
6207        updateProcessForegroundLocked(app, false, false);
6208        app.hasShownUi = false;
6209        app.debugging = false;
6210        app.cached = false;
6211        app.killedByAm = false;
6212
6213        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6214
6215        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6216        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6217
6218        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6219            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6220            msg.obj = app;
6221            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6222        }
6223
6224        if (!normalMode) {
6225            Slog.i(TAG, "Launching preboot mode app: " + app);
6226        }
6227
6228        if (DEBUG_ALL) Slog.v(
6229            TAG, "New app record " + app
6230            + " thread=" + thread.asBinder() + " pid=" + pid);
6231        try {
6232            int testMode = IApplicationThread.DEBUG_OFF;
6233            if (mDebugApp != null && mDebugApp.equals(processName)) {
6234                testMode = mWaitForDebugger
6235                    ? IApplicationThread.DEBUG_WAIT
6236                    : IApplicationThread.DEBUG_ON;
6237                app.debugging = true;
6238                if (mDebugTransient) {
6239                    mDebugApp = mOrigDebugApp;
6240                    mWaitForDebugger = mOrigWaitForDebugger;
6241                }
6242            }
6243            String profileFile = app.instrumentationProfileFile;
6244            ParcelFileDescriptor profileFd = null;
6245            int samplingInterval = 0;
6246            boolean profileAutoStop = false;
6247            if (mProfileApp != null && mProfileApp.equals(processName)) {
6248                mProfileProc = app;
6249                profileFile = mProfileFile;
6250                profileFd = mProfileFd;
6251                samplingInterval = mSamplingInterval;
6252                profileAutoStop = mAutoStopProfiler;
6253            }
6254            boolean enableTrackAllocation = false;
6255            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6256                enableTrackAllocation = true;
6257                mTrackAllocationApp = null;
6258            }
6259
6260            // If the app is being launched for restore or full backup, set it up specially
6261            boolean isRestrictedBackupMode = false;
6262            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6263                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6264                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6265                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6266            }
6267
6268            notifyPackageUse(app.instrumentationInfo != null
6269                    ? app.instrumentationInfo.packageName
6270                    : app.info.packageName);
6271            if (app.instrumentationClass != null) {
6272                notifyPackageUse(app.instrumentationClass.getPackageName());
6273            }
6274            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6275                    + processName + " with config " + mConfiguration);
6276            ApplicationInfo appInfo = app.instrumentationInfo != null
6277                    ? app.instrumentationInfo : app.info;
6278            app.compat = compatibilityInfoForPackageLocked(appInfo);
6279            if (profileFd != null) {
6280                profileFd = profileFd.dup();
6281            }
6282            ProfilerInfo profilerInfo = profileFile == null ? null
6283                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6284            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6285                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6286                    app.instrumentationUiAutomationConnection, testMode,
6287                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6288                    isRestrictedBackupMode || !normalMode, app.persistent,
6289                    new Configuration(mConfiguration), app.compat,
6290                    getCommonServicesLocked(app.isolated),
6291                    mCoreSettingsObserver.getCoreSettingsLocked());
6292            updateLruProcessLocked(app, false, null);
6293            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6294        } catch (Exception e) {
6295            // todo: Yikes!  What should we do?  For now we will try to
6296            // start another process, but that could easily get us in
6297            // an infinite loop of restarting processes...
6298            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6299
6300            app.resetPackageList(mProcessStats);
6301            app.unlinkDeathRecipient();
6302            startProcessLocked(app, "bind fail", processName);
6303            return false;
6304        }
6305
6306        // Remove this record from the list of starting applications.
6307        mPersistentStartingProcesses.remove(app);
6308        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6309                "Attach application locked removing on hold: " + app);
6310        mProcessesOnHold.remove(app);
6311
6312        boolean badApp = false;
6313        boolean didSomething = false;
6314
6315        // See if the top visible activity is waiting to run in this process...
6316        if (normalMode) {
6317            try {
6318                if (mStackSupervisor.attachApplicationLocked(app)) {
6319                    didSomething = true;
6320                }
6321            } catch (Exception e) {
6322                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6323                badApp = true;
6324            }
6325        }
6326
6327        // Find any services that should be running in this process...
6328        if (!badApp) {
6329            try {
6330                didSomething |= mServices.attachApplicationLocked(app, processName);
6331            } catch (Exception e) {
6332                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6333                badApp = true;
6334            }
6335        }
6336
6337        // Check if a next-broadcast receiver is in this process...
6338        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6339            try {
6340                didSomething |= sendPendingBroadcastsLocked(app);
6341            } catch (Exception e) {
6342                // If the app died trying to launch the receiver we declare it 'bad'
6343                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6344                badApp = true;
6345            }
6346        }
6347
6348        // Check whether the next backup agent is in this process...
6349        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6350            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6351                    "New app is backup target, launching agent for " + app);
6352            notifyPackageUse(mBackupTarget.appInfo.packageName);
6353            try {
6354                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6355                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6356                        mBackupTarget.backupMode);
6357            } catch (Exception e) {
6358                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6359                badApp = true;
6360            }
6361        }
6362
6363        if (badApp) {
6364            app.kill("error during init", true);
6365            handleAppDiedLocked(app, false, true);
6366            return false;
6367        }
6368
6369        if (!didSomething) {
6370            updateOomAdjLocked();
6371        }
6372
6373        return true;
6374    }
6375
6376    @Override
6377    public final void attachApplication(IApplicationThread thread) {
6378        synchronized (this) {
6379            int callingPid = Binder.getCallingPid();
6380            final long origId = Binder.clearCallingIdentity();
6381            attachApplicationLocked(thread, callingPid);
6382            Binder.restoreCallingIdentity(origId);
6383        }
6384    }
6385
6386    @Override
6387    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6388        final long origId = Binder.clearCallingIdentity();
6389        synchronized (this) {
6390            ActivityStack stack = ActivityRecord.getStackLocked(token);
6391            if (stack != null) {
6392                ActivityRecord r =
6393                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6394                if (stopProfiling) {
6395                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6396                        try {
6397                            mProfileFd.close();
6398                        } catch (IOException e) {
6399                        }
6400                        clearProfilerLocked();
6401                    }
6402                }
6403            }
6404        }
6405        Binder.restoreCallingIdentity(origId);
6406    }
6407
6408    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6409        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6410                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6411    }
6412
6413    void enableScreenAfterBoot() {
6414        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6415                SystemClock.uptimeMillis());
6416        mWindowManager.enableScreenAfterBoot();
6417
6418        synchronized (this) {
6419            updateEventDispatchingLocked();
6420        }
6421    }
6422
6423    @Override
6424    public void showBootMessage(final CharSequence msg, final boolean always) {
6425        if (Binder.getCallingUid() != Process.myUid()) {
6426            // These days only the core system can call this, so apps can't get in
6427            // the way of what we show about running them.
6428        }
6429        mWindowManager.showBootMessage(msg, always);
6430    }
6431
6432    @Override
6433    public void keyguardWaitingForActivityDrawn() {
6434        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6435        final long token = Binder.clearCallingIdentity();
6436        try {
6437            synchronized (this) {
6438                if (DEBUG_LOCKSCREEN) logLockScreen("");
6439                mWindowManager.keyguardWaitingForActivityDrawn();
6440                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6441                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6442                    updateSleepIfNeededLocked();
6443                }
6444            }
6445        } finally {
6446            Binder.restoreCallingIdentity(token);
6447        }
6448    }
6449
6450    @Override
6451    public void keyguardGoingAway(boolean disableWindowAnimations,
6452            boolean keyguardGoingToNotificationShade) {
6453        enforceNotIsolatedCaller("keyguardGoingAway");
6454        final long token = Binder.clearCallingIdentity();
6455        try {
6456            synchronized (this) {
6457                if (DEBUG_LOCKSCREEN) logLockScreen("");
6458                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6459                        keyguardGoingToNotificationShade);
6460                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6461                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6462                    updateSleepIfNeededLocked();
6463                }
6464            }
6465        } finally {
6466            Binder.restoreCallingIdentity(token);
6467        }
6468    }
6469
6470    final void finishBooting() {
6471        synchronized (this) {
6472            if (!mBootAnimationComplete) {
6473                mCallFinishBooting = true;
6474                return;
6475            }
6476            mCallFinishBooting = false;
6477        }
6478
6479        ArraySet<String> completedIsas = new ArraySet<String>();
6480        for (String abi : Build.SUPPORTED_ABIS) {
6481            Process.establishZygoteConnectionForAbi(abi);
6482            final String instructionSet = VMRuntime.getInstructionSet(abi);
6483            if (!completedIsas.contains(instructionSet)) {
6484                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6485                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6486                }
6487                completedIsas.add(instructionSet);
6488            }
6489        }
6490
6491        IntentFilter pkgFilter = new IntentFilter();
6492        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6493        pkgFilter.addDataScheme("package");
6494        mContext.registerReceiver(new BroadcastReceiver() {
6495            @Override
6496            public void onReceive(Context context, Intent intent) {
6497                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6498                if (pkgs != null) {
6499                    for (String pkg : pkgs) {
6500                        synchronized (ActivityManagerService.this) {
6501                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6502                                    0, "query restart")) {
6503                                setResultCode(Activity.RESULT_OK);
6504                                return;
6505                            }
6506                        }
6507                    }
6508                }
6509            }
6510        }, pkgFilter);
6511
6512        IntentFilter dumpheapFilter = new IntentFilter();
6513        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6514        mContext.registerReceiver(new BroadcastReceiver() {
6515            @Override
6516            public void onReceive(Context context, Intent intent) {
6517                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6518                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6519                } else {
6520                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6521                }
6522            }
6523        }, dumpheapFilter);
6524
6525        // Let system services know.
6526        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6527
6528        synchronized (this) {
6529            // Ensure that any processes we had put on hold are now started
6530            // up.
6531            final int NP = mProcessesOnHold.size();
6532            if (NP > 0) {
6533                ArrayList<ProcessRecord> procs =
6534                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6535                for (int ip=0; ip<NP; ip++) {
6536                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6537                            + procs.get(ip));
6538                    startProcessLocked(procs.get(ip), "on-hold", null);
6539                }
6540            }
6541
6542            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6543                // Start looking for apps that are abusing wake locks.
6544                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6545                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6546                // Tell anyone interested that we are done booting!
6547                SystemProperties.set("sys.boot_completed", "1");
6548
6549                // And trigger dev.bootcomplete if we are not showing encryption progress
6550                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6551                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6552                    SystemProperties.set("dev.bootcomplete", "1");
6553                }
6554                mUserController.sendBootCompletedLocked(
6555                        new IIntentReceiver.Stub() {
6556                            @Override
6557                            public void performReceive(Intent intent, int resultCode,
6558                                    String data, Bundle extras, boolean ordered,
6559                                    boolean sticky, int sendingUser) {
6560                                synchronized (ActivityManagerService.this) {
6561                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6562                                            true, false);
6563                                }
6564                            }
6565                        });
6566                scheduleStartProfilesLocked();
6567            }
6568        }
6569    }
6570
6571    @Override
6572    public void bootAnimationComplete() {
6573        final boolean callFinishBooting;
6574        synchronized (this) {
6575            callFinishBooting = mCallFinishBooting;
6576            mBootAnimationComplete = true;
6577        }
6578        if (callFinishBooting) {
6579            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6580            finishBooting();
6581            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6582        }
6583    }
6584
6585    final void ensureBootCompleted() {
6586        boolean booting;
6587        boolean enableScreen;
6588        synchronized (this) {
6589            booting = mBooting;
6590            mBooting = false;
6591            enableScreen = !mBooted;
6592            mBooted = true;
6593        }
6594
6595        if (booting) {
6596            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6597            finishBooting();
6598            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6599        }
6600
6601        if (enableScreen) {
6602            enableScreenAfterBoot();
6603        }
6604    }
6605
6606    @Override
6607    public final void activityResumed(IBinder token) {
6608        final long origId = Binder.clearCallingIdentity();
6609        synchronized(this) {
6610            ActivityStack stack = ActivityRecord.getStackLocked(token);
6611            if (stack != null) {
6612                ActivityRecord.activityResumedLocked(token);
6613            }
6614        }
6615        Binder.restoreCallingIdentity(origId);
6616    }
6617
6618    @Override
6619    public final void activityPaused(IBinder token) {
6620        final long origId = Binder.clearCallingIdentity();
6621        synchronized(this) {
6622            ActivityStack stack = ActivityRecord.getStackLocked(token);
6623            if (stack != null) {
6624                stack.activityPausedLocked(token, false);
6625            }
6626        }
6627        Binder.restoreCallingIdentity(origId);
6628    }
6629
6630    @Override
6631    public final void activityStopped(IBinder token, Bundle icicle,
6632            PersistableBundle persistentState, CharSequence description) {
6633        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6634
6635        // Refuse possible leaked file descriptors
6636        if (icicle != null && icicle.hasFileDescriptors()) {
6637            throw new IllegalArgumentException("File descriptors passed in Bundle");
6638        }
6639
6640        final long origId = Binder.clearCallingIdentity();
6641
6642        synchronized (this) {
6643            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6644            if (r != null) {
6645                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6646            }
6647        }
6648
6649        trimApplications();
6650
6651        Binder.restoreCallingIdentity(origId);
6652    }
6653
6654    @Override
6655    public final void activityDestroyed(IBinder token) {
6656        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6657        synchronized (this) {
6658            ActivityStack stack = ActivityRecord.getStackLocked(token);
6659            if (stack != null) {
6660                stack.activityDestroyedLocked(token, "activityDestroyed");
6661            }
6662        }
6663    }
6664
6665    @Override
6666    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6667            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6668        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6669                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6670        synchronized (this) {
6671            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6672            if (record == null) {
6673                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6674                        + "found for: " + token);
6675            }
6676            record.setSizeConfigurations(horizontalSizeConfiguration,
6677                    verticalSizeConfigurations, smallestSizeConfigurations);
6678        }
6679    }
6680
6681    @Override
6682    public final void backgroundResourcesReleased(IBinder token) {
6683        final long origId = Binder.clearCallingIdentity();
6684        try {
6685            synchronized (this) {
6686                ActivityStack stack = ActivityRecord.getStackLocked(token);
6687                if (stack != null) {
6688                    stack.backgroundResourcesReleased();
6689                }
6690            }
6691        } finally {
6692            Binder.restoreCallingIdentity(origId);
6693        }
6694    }
6695
6696    @Override
6697    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6698        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6699    }
6700
6701    @Override
6702    public final void notifyEnterAnimationComplete(IBinder token) {
6703        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6704    }
6705
6706    @Override
6707    public String getCallingPackage(IBinder token) {
6708        synchronized (this) {
6709            ActivityRecord r = getCallingRecordLocked(token);
6710            return r != null ? r.info.packageName : null;
6711        }
6712    }
6713
6714    @Override
6715    public ComponentName getCallingActivity(IBinder token) {
6716        synchronized (this) {
6717            ActivityRecord r = getCallingRecordLocked(token);
6718            return r != null ? r.intent.getComponent() : null;
6719        }
6720    }
6721
6722    private ActivityRecord getCallingRecordLocked(IBinder token) {
6723        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6724        if (r == null) {
6725            return null;
6726        }
6727        return r.resultTo;
6728    }
6729
6730    @Override
6731    public ComponentName getActivityClassForToken(IBinder token) {
6732        synchronized(this) {
6733            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6734            if (r == null) {
6735                return null;
6736            }
6737            return r.intent.getComponent();
6738        }
6739    }
6740
6741    @Override
6742    public String getPackageForToken(IBinder token) {
6743        synchronized(this) {
6744            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6745            if (r == null) {
6746                return null;
6747            }
6748            return r.packageName;
6749        }
6750    }
6751
6752    @Override
6753    public boolean isRootVoiceInteraction(IBinder token) {
6754        synchronized(this) {
6755            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6756            if (r == null) {
6757                return false;
6758            }
6759            return r.rootVoiceInteraction;
6760        }
6761    }
6762
6763    @Override
6764    public IIntentSender getIntentSender(int type,
6765            String packageName, IBinder token, String resultWho,
6766            int requestCode, Intent[] intents, String[] resolvedTypes,
6767            int flags, Bundle bOptions, int userId) {
6768        enforceNotIsolatedCaller("getIntentSender");
6769        // Refuse possible leaked file descriptors
6770        if (intents != null) {
6771            if (intents.length < 1) {
6772                throw new IllegalArgumentException("Intents array length must be >= 1");
6773            }
6774            for (int i=0; i<intents.length; i++) {
6775                Intent intent = intents[i];
6776                if (intent != null) {
6777                    if (intent.hasFileDescriptors()) {
6778                        throw new IllegalArgumentException("File descriptors passed in Intent");
6779                    }
6780                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6781                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6782                        throw new IllegalArgumentException(
6783                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6784                    }
6785                    intents[i] = new Intent(intent);
6786                }
6787            }
6788            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6789                throw new IllegalArgumentException(
6790                        "Intent array length does not match resolvedTypes length");
6791            }
6792        }
6793        if (bOptions != null) {
6794            if (bOptions.hasFileDescriptors()) {
6795                throw new IllegalArgumentException("File descriptors passed in options");
6796            }
6797        }
6798
6799        synchronized(this) {
6800            int callingUid = Binder.getCallingUid();
6801            int origUserId = userId;
6802            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6803                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6804                    ALLOW_NON_FULL, "getIntentSender", null);
6805            if (origUserId == UserHandle.USER_CURRENT) {
6806                // We don't want to evaluate this until the pending intent is
6807                // actually executed.  However, we do want to always do the
6808                // security checking for it above.
6809                userId = UserHandle.USER_CURRENT;
6810            }
6811            try {
6812                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6813                    int uid = AppGlobals.getPackageManager()
6814                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6815                    if (!UserHandle.isSameApp(callingUid, uid)) {
6816                        String msg = "Permission Denial: getIntentSender() from pid="
6817                            + Binder.getCallingPid()
6818                            + ", uid=" + Binder.getCallingUid()
6819                            + ", (need uid=" + uid + ")"
6820                            + " is not allowed to send as package " + packageName;
6821                        Slog.w(TAG, msg);
6822                        throw new SecurityException(msg);
6823                    }
6824                }
6825
6826                return getIntentSenderLocked(type, packageName, callingUid, userId,
6827                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6828
6829            } catch (RemoteException e) {
6830                throw new SecurityException(e);
6831            }
6832        }
6833    }
6834
6835    IIntentSender getIntentSenderLocked(int type, String packageName,
6836            int callingUid, int userId, IBinder token, String resultWho,
6837            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6838            Bundle bOptions) {
6839        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6840        ActivityRecord activity = null;
6841        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6842            activity = ActivityRecord.isInStackLocked(token);
6843            if (activity == null) {
6844                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6845                return null;
6846            }
6847            if (activity.finishing) {
6848                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6849                return null;
6850            }
6851        }
6852
6853        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6854        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6855        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6856        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6857                |PendingIntent.FLAG_UPDATE_CURRENT);
6858
6859        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6860                type, packageName, activity, resultWho,
6861                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6862        WeakReference<PendingIntentRecord> ref;
6863        ref = mIntentSenderRecords.get(key);
6864        PendingIntentRecord rec = ref != null ? ref.get() : null;
6865        if (rec != null) {
6866            if (!cancelCurrent) {
6867                if (updateCurrent) {
6868                    if (rec.key.requestIntent != null) {
6869                        rec.key.requestIntent.replaceExtras(intents != null ?
6870                                intents[intents.length - 1] : null);
6871                    }
6872                    if (intents != null) {
6873                        intents[intents.length-1] = rec.key.requestIntent;
6874                        rec.key.allIntents = intents;
6875                        rec.key.allResolvedTypes = resolvedTypes;
6876                    } else {
6877                        rec.key.allIntents = null;
6878                        rec.key.allResolvedTypes = null;
6879                    }
6880                }
6881                return rec;
6882            }
6883            rec.canceled = true;
6884            mIntentSenderRecords.remove(key);
6885        }
6886        if (noCreate) {
6887            return rec;
6888        }
6889        rec = new PendingIntentRecord(this, key, callingUid);
6890        mIntentSenderRecords.put(key, rec.ref);
6891        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6892            if (activity.pendingResults == null) {
6893                activity.pendingResults
6894                        = new HashSet<WeakReference<PendingIntentRecord>>();
6895            }
6896            activity.pendingResults.add(rec.ref);
6897        }
6898        return rec;
6899    }
6900
6901    @Override
6902    public void cancelIntentSender(IIntentSender sender) {
6903        if (!(sender instanceof PendingIntentRecord)) {
6904            return;
6905        }
6906        synchronized(this) {
6907            PendingIntentRecord rec = (PendingIntentRecord)sender;
6908            try {
6909                int uid = AppGlobals.getPackageManager()
6910                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6911                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6912                    String msg = "Permission Denial: cancelIntentSender() from pid="
6913                        + Binder.getCallingPid()
6914                        + ", uid=" + Binder.getCallingUid()
6915                        + " is not allowed to cancel packges "
6916                        + rec.key.packageName;
6917                    Slog.w(TAG, msg);
6918                    throw new SecurityException(msg);
6919                }
6920            } catch (RemoteException e) {
6921                throw new SecurityException(e);
6922            }
6923            cancelIntentSenderLocked(rec, true);
6924        }
6925    }
6926
6927    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6928        rec.canceled = true;
6929        mIntentSenderRecords.remove(rec.key);
6930        if (cleanActivity && rec.key.activity != null) {
6931            rec.key.activity.pendingResults.remove(rec.ref);
6932        }
6933    }
6934
6935    @Override
6936    public String getPackageForIntentSender(IIntentSender pendingResult) {
6937        if (!(pendingResult instanceof PendingIntentRecord)) {
6938            return null;
6939        }
6940        try {
6941            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6942            return res.key.packageName;
6943        } catch (ClassCastException e) {
6944        }
6945        return null;
6946    }
6947
6948    @Override
6949    public int getUidForIntentSender(IIntentSender sender) {
6950        if (sender instanceof PendingIntentRecord) {
6951            try {
6952                PendingIntentRecord res = (PendingIntentRecord)sender;
6953                return res.uid;
6954            } catch (ClassCastException e) {
6955            }
6956        }
6957        return -1;
6958    }
6959
6960    @Override
6961    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6962        if (!(pendingResult instanceof PendingIntentRecord)) {
6963            return false;
6964        }
6965        try {
6966            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6967            if (res.key.allIntents == null) {
6968                return false;
6969            }
6970            for (int i=0; i<res.key.allIntents.length; i++) {
6971                Intent intent = res.key.allIntents[i];
6972                if (intent.getPackage() != null && intent.getComponent() != null) {
6973                    return false;
6974                }
6975            }
6976            return true;
6977        } catch (ClassCastException e) {
6978        }
6979        return false;
6980    }
6981
6982    @Override
6983    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6984        if (!(pendingResult instanceof PendingIntentRecord)) {
6985            return false;
6986        }
6987        try {
6988            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6989            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6990                return true;
6991            }
6992            return false;
6993        } catch (ClassCastException e) {
6994        }
6995        return false;
6996    }
6997
6998    @Override
6999    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7000        if (!(pendingResult instanceof PendingIntentRecord)) {
7001            return null;
7002        }
7003        try {
7004            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7005            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7006        } catch (ClassCastException e) {
7007        }
7008        return null;
7009    }
7010
7011    @Override
7012    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7013        if (!(pendingResult instanceof PendingIntentRecord)) {
7014            return null;
7015        }
7016        try {
7017            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7018            synchronized (this) {
7019                return getTagForIntentSenderLocked(res, prefix);
7020            }
7021        } catch (ClassCastException e) {
7022        }
7023        return null;
7024    }
7025
7026    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7027        final Intent intent = res.key.requestIntent;
7028        if (intent != null) {
7029            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7030                    || res.lastTagPrefix.equals(prefix))) {
7031                return res.lastTag;
7032            }
7033            res.lastTagPrefix = prefix;
7034            final StringBuilder sb = new StringBuilder(128);
7035            if (prefix != null) {
7036                sb.append(prefix);
7037            }
7038            if (intent.getAction() != null) {
7039                sb.append(intent.getAction());
7040            } else if (intent.getComponent() != null) {
7041                intent.getComponent().appendShortString(sb);
7042            } else {
7043                sb.append("?");
7044            }
7045            return res.lastTag = sb.toString();
7046        }
7047        return null;
7048    }
7049
7050    @Override
7051    public void setProcessLimit(int max) {
7052        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7053                "setProcessLimit()");
7054        synchronized (this) {
7055            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7056            mProcessLimitOverride = max;
7057        }
7058        trimApplications();
7059    }
7060
7061    @Override
7062    public int getProcessLimit() {
7063        synchronized (this) {
7064            return mProcessLimitOverride;
7065        }
7066    }
7067
7068    void foregroundTokenDied(ForegroundToken token) {
7069        synchronized (ActivityManagerService.this) {
7070            synchronized (mPidsSelfLocked) {
7071                ForegroundToken cur
7072                    = mForegroundProcesses.get(token.pid);
7073                if (cur != token) {
7074                    return;
7075                }
7076                mForegroundProcesses.remove(token.pid);
7077                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7078                if (pr == null) {
7079                    return;
7080                }
7081                pr.forcingToForeground = null;
7082                updateProcessForegroundLocked(pr, false, false);
7083            }
7084            updateOomAdjLocked();
7085        }
7086    }
7087
7088    @Override
7089    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7090        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7091                "setProcessForeground()");
7092        synchronized(this) {
7093            boolean changed = false;
7094
7095            synchronized (mPidsSelfLocked) {
7096                ProcessRecord pr = mPidsSelfLocked.get(pid);
7097                if (pr == null && isForeground) {
7098                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7099                    return;
7100                }
7101                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7102                if (oldToken != null) {
7103                    oldToken.token.unlinkToDeath(oldToken, 0);
7104                    mForegroundProcesses.remove(pid);
7105                    if (pr != null) {
7106                        pr.forcingToForeground = null;
7107                    }
7108                    changed = true;
7109                }
7110                if (isForeground && token != null) {
7111                    ForegroundToken newToken = new ForegroundToken() {
7112                        @Override
7113                        public void binderDied() {
7114                            foregroundTokenDied(this);
7115                        }
7116                    };
7117                    newToken.pid = pid;
7118                    newToken.token = token;
7119                    try {
7120                        token.linkToDeath(newToken, 0);
7121                        mForegroundProcesses.put(pid, newToken);
7122                        pr.forcingToForeground = token;
7123                        changed = true;
7124                    } catch (RemoteException e) {
7125                        // If the process died while doing this, we will later
7126                        // do the cleanup with the process death link.
7127                    }
7128                }
7129            }
7130
7131            if (changed) {
7132                updateOomAdjLocked();
7133            }
7134        }
7135    }
7136
7137    // =========================================================
7138    // PROCESS INFO
7139    // =========================================================
7140
7141    static class ProcessInfoService extends IProcessInfoService.Stub {
7142        final ActivityManagerService mActivityManagerService;
7143        ProcessInfoService(ActivityManagerService activityManagerService) {
7144            mActivityManagerService = activityManagerService;
7145        }
7146
7147        @Override
7148        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7149            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
7150        }
7151    }
7152
7153    /**
7154     * For each PID in the given input array, write the current process state
7155     * for that process into the output array, or -1 to indicate that no
7156     * process with the given PID exists.
7157     */
7158    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
7159        if (pids == null) {
7160            throw new NullPointerException("pids");
7161        } else if (states == null) {
7162            throw new NullPointerException("states");
7163        } else if (pids.length != states.length) {
7164            throw new IllegalArgumentException("input and output arrays have different lengths!");
7165        }
7166
7167        synchronized (mPidsSelfLocked) {
7168            for (int i = 0; i < pids.length; i++) {
7169                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7170                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7171                        pr.curProcState;
7172            }
7173        }
7174    }
7175
7176    // =========================================================
7177    // PERMISSIONS
7178    // =========================================================
7179
7180    static class PermissionController extends IPermissionController.Stub {
7181        ActivityManagerService mActivityManagerService;
7182        PermissionController(ActivityManagerService activityManagerService) {
7183            mActivityManagerService = activityManagerService;
7184        }
7185
7186        @Override
7187        public boolean checkPermission(String permission, int pid, int uid) {
7188            return mActivityManagerService.checkPermission(permission, pid,
7189                    uid) == PackageManager.PERMISSION_GRANTED;
7190        }
7191
7192        @Override
7193        public String[] getPackagesForUid(int uid) {
7194            return mActivityManagerService.mContext.getPackageManager()
7195                    .getPackagesForUid(uid);
7196        }
7197
7198        @Override
7199        public boolean isRuntimePermission(String permission) {
7200            try {
7201                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7202                        .getPermissionInfo(permission, 0);
7203                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7204            } catch (NameNotFoundException nnfe) {
7205                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7206            }
7207            return false;
7208        }
7209    }
7210
7211    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7212        @Override
7213        public int checkComponentPermission(String permission, int pid, int uid,
7214                int owningUid, boolean exported) {
7215            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7216                    owningUid, exported);
7217        }
7218
7219        @Override
7220        public Object getAMSLock() {
7221            return ActivityManagerService.this;
7222        }
7223    }
7224
7225    /**
7226     * This can be called with or without the global lock held.
7227     */
7228    int checkComponentPermission(String permission, int pid, int uid,
7229            int owningUid, boolean exported) {
7230        if (pid == MY_PID) {
7231            return PackageManager.PERMISSION_GRANTED;
7232        }
7233        return ActivityManager.checkComponentPermission(permission, uid,
7234                owningUid, exported);
7235    }
7236
7237    /**
7238     * As the only public entry point for permissions checking, this method
7239     * can enforce the semantic that requesting a check on a null global
7240     * permission is automatically denied.  (Internally a null permission
7241     * string is used when calling {@link #checkComponentPermission} in cases
7242     * when only uid-based security is needed.)
7243     *
7244     * This can be called with or without the global lock held.
7245     */
7246    @Override
7247    public int checkPermission(String permission, int pid, int uid) {
7248        if (permission == null) {
7249            return PackageManager.PERMISSION_DENIED;
7250        }
7251        return checkComponentPermission(permission, pid, uid, -1, true);
7252    }
7253
7254    @Override
7255    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7256        if (permission == null) {
7257            return PackageManager.PERMISSION_DENIED;
7258        }
7259
7260        // We might be performing an operation on behalf of an indirect binder
7261        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7262        // client identity accordingly before proceeding.
7263        Identity tlsIdentity = sCallerIdentity.get();
7264        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7265            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7266                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7267            uid = tlsIdentity.uid;
7268            pid = tlsIdentity.pid;
7269        }
7270
7271        return checkComponentPermission(permission, pid, uid, -1, true);
7272    }
7273
7274    /**
7275     * Binder IPC calls go through the public entry point.
7276     * This can be called with or without the global lock held.
7277     */
7278    int checkCallingPermission(String permission) {
7279        return checkPermission(permission,
7280                Binder.getCallingPid(),
7281                UserHandle.getAppId(Binder.getCallingUid()));
7282    }
7283
7284    /**
7285     * This can be called with or without the global lock held.
7286     */
7287    void enforceCallingPermission(String permission, String func) {
7288        if (checkCallingPermission(permission)
7289                == PackageManager.PERMISSION_GRANTED) {
7290            return;
7291        }
7292
7293        String msg = "Permission Denial: " + func + " from pid="
7294                + Binder.getCallingPid()
7295                + ", uid=" + Binder.getCallingUid()
7296                + " requires " + permission;
7297        Slog.w(TAG, msg);
7298        throw new SecurityException(msg);
7299    }
7300
7301    /**
7302     * Determine if UID is holding permissions required to access {@link Uri} in
7303     * the given {@link ProviderInfo}. Final permission checking is always done
7304     * in {@link ContentProvider}.
7305     */
7306    private final boolean checkHoldingPermissionsLocked(
7307            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7308        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7309                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7310        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7311            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7312                    != PERMISSION_GRANTED) {
7313                return false;
7314            }
7315        }
7316        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7317    }
7318
7319    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7320            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7321        if (pi.applicationInfo.uid == uid) {
7322            return true;
7323        } else if (!pi.exported) {
7324            return false;
7325        }
7326
7327        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7328        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7329        try {
7330            // check if target holds top-level <provider> permissions
7331            if (!readMet && pi.readPermission != null && considerUidPermissions
7332                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7333                readMet = true;
7334            }
7335            if (!writeMet && pi.writePermission != null && considerUidPermissions
7336                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7337                writeMet = true;
7338            }
7339
7340            // track if unprotected read/write is allowed; any denied
7341            // <path-permission> below removes this ability
7342            boolean allowDefaultRead = pi.readPermission == null;
7343            boolean allowDefaultWrite = pi.writePermission == null;
7344
7345            // check if target holds any <path-permission> that match uri
7346            final PathPermission[] pps = pi.pathPermissions;
7347            if (pps != null) {
7348                final String path = grantUri.uri.getPath();
7349                int i = pps.length;
7350                while (i > 0 && (!readMet || !writeMet)) {
7351                    i--;
7352                    PathPermission pp = pps[i];
7353                    if (pp.match(path)) {
7354                        if (!readMet) {
7355                            final String pprperm = pp.getReadPermission();
7356                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7357                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7358                                    + ": match=" + pp.match(path)
7359                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7360                            if (pprperm != null) {
7361                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7362                                        == PERMISSION_GRANTED) {
7363                                    readMet = true;
7364                                } else {
7365                                    allowDefaultRead = false;
7366                                }
7367                            }
7368                        }
7369                        if (!writeMet) {
7370                            final String ppwperm = pp.getWritePermission();
7371                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7372                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7373                                    + ": match=" + pp.match(path)
7374                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7375                            if (ppwperm != null) {
7376                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7377                                        == PERMISSION_GRANTED) {
7378                                    writeMet = true;
7379                                } else {
7380                                    allowDefaultWrite = false;
7381                                }
7382                            }
7383                        }
7384                    }
7385                }
7386            }
7387
7388            // grant unprotected <provider> read/write, if not blocked by
7389            // <path-permission> above
7390            if (allowDefaultRead) readMet = true;
7391            if (allowDefaultWrite) writeMet = true;
7392
7393        } catch (RemoteException e) {
7394            return false;
7395        }
7396
7397        return readMet && writeMet;
7398    }
7399
7400    public int getAppStartMode(int uid, String packageName) {
7401        synchronized (this) {
7402            boolean bg = checkAllowBackgroundLocked(uid, packageName, -1);
7403            return bg ? ActivityManager.APP_START_MODE_NORMAL
7404                    : ActivityManager.APP_START_MODE_DISABLED;
7405        }
7406    }
7407
7408    boolean checkAllowBackgroundLocked(int uid, String packageName, int callingPid) {
7409        UidRecord uidRec = mActiveUids.get(uid);
7410        if (uidRec == null || uidRec.idle) {
7411            if (callingPid >= 0) {
7412                ProcessRecord proc;
7413                synchronized (mPidsSelfLocked) {
7414                    proc = mPidsSelfLocked.get(callingPid);
7415                }
7416                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7417                    // Whoever is instigating this is in the foreground, so we will allow it
7418                    // to go through.
7419                    return true;
7420                }
7421            }
7422            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7423                    != AppOpsManager.MODE_ALLOWED) {
7424                return false;
7425            }
7426        }
7427        return true;
7428    }
7429
7430    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7431        ProviderInfo pi = null;
7432        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7433        if (cpr != null) {
7434            pi = cpr.info;
7435        } else {
7436            try {
7437                pi = AppGlobals.getPackageManager().resolveContentProvider(
7438                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7439            } catch (RemoteException ex) {
7440            }
7441        }
7442        return pi;
7443    }
7444
7445    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7446        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7447        if (targetUris != null) {
7448            return targetUris.get(grantUri);
7449        }
7450        return null;
7451    }
7452
7453    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7454            String targetPkg, int targetUid, GrantUri grantUri) {
7455        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7456        if (targetUris == null) {
7457            targetUris = Maps.newArrayMap();
7458            mGrantedUriPermissions.put(targetUid, targetUris);
7459        }
7460
7461        UriPermission perm = targetUris.get(grantUri);
7462        if (perm == null) {
7463            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7464            targetUris.put(grantUri, perm);
7465        }
7466
7467        return perm;
7468    }
7469
7470    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7471            final int modeFlags) {
7472        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7473        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7474                : UriPermission.STRENGTH_OWNED;
7475
7476        // Root gets to do everything.
7477        if (uid == 0) {
7478            return true;
7479        }
7480
7481        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7482        if (perms == null) return false;
7483
7484        // First look for exact match
7485        final UriPermission exactPerm = perms.get(grantUri);
7486        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7487            return true;
7488        }
7489
7490        // No exact match, look for prefixes
7491        final int N = perms.size();
7492        for (int i = 0; i < N; i++) {
7493            final UriPermission perm = perms.valueAt(i);
7494            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7495                    && perm.getStrength(modeFlags) >= minStrength) {
7496                return true;
7497            }
7498        }
7499
7500        return false;
7501    }
7502
7503    /**
7504     * @param uri This uri must NOT contain an embedded userId.
7505     * @param userId The userId in which the uri is to be resolved.
7506     */
7507    @Override
7508    public int checkUriPermission(Uri uri, int pid, int uid,
7509            final int modeFlags, int userId, IBinder callerToken) {
7510        enforceNotIsolatedCaller("checkUriPermission");
7511
7512        // Another redirected-binder-call permissions check as in
7513        // {@link checkPermissionWithToken}.
7514        Identity tlsIdentity = sCallerIdentity.get();
7515        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7516            uid = tlsIdentity.uid;
7517            pid = tlsIdentity.pid;
7518        }
7519
7520        // Our own process gets to do everything.
7521        if (pid == MY_PID) {
7522            return PackageManager.PERMISSION_GRANTED;
7523        }
7524        synchronized (this) {
7525            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7526                    ? PackageManager.PERMISSION_GRANTED
7527                    : PackageManager.PERMISSION_DENIED;
7528        }
7529    }
7530
7531    /**
7532     * Check if the targetPkg can be granted permission to access uri by
7533     * the callingUid using the given modeFlags.  Throws a security exception
7534     * if callingUid is not allowed to do this.  Returns the uid of the target
7535     * if the URI permission grant should be performed; returns -1 if it is not
7536     * needed (for example targetPkg already has permission to access the URI).
7537     * If you already know the uid of the target, you can supply it in
7538     * lastTargetUid else set that to -1.
7539     */
7540    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7541            final int modeFlags, int lastTargetUid) {
7542        if (!Intent.isAccessUriMode(modeFlags)) {
7543            return -1;
7544        }
7545
7546        if (targetPkg != null) {
7547            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7548                    "Checking grant " + targetPkg + " permission to " + grantUri);
7549        }
7550
7551        final IPackageManager pm = AppGlobals.getPackageManager();
7552
7553        // If this is not a content: uri, we can't do anything with it.
7554        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7555            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7556                    "Can't grant URI permission for non-content URI: " + grantUri);
7557            return -1;
7558        }
7559
7560        final String authority = grantUri.uri.getAuthority();
7561        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7562        if (pi == null) {
7563            Slog.w(TAG, "No content provider found for permission check: " +
7564                    grantUri.uri.toSafeString());
7565            return -1;
7566        }
7567
7568        int targetUid = lastTargetUid;
7569        if (targetUid < 0 && targetPkg != null) {
7570            try {
7571                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7572                if (targetUid < 0) {
7573                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7574                            "Can't grant URI permission no uid for: " + targetPkg);
7575                    return -1;
7576                }
7577            } catch (RemoteException ex) {
7578                return -1;
7579            }
7580        }
7581
7582        if (targetUid >= 0) {
7583            // First...  does the target actually need this permission?
7584            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7585                // No need to grant the target this permission.
7586                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7587                        "Target " + targetPkg + " already has full permission to " + grantUri);
7588                return -1;
7589            }
7590        } else {
7591            // First...  there is no target package, so can anyone access it?
7592            boolean allowed = pi.exported;
7593            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7594                if (pi.readPermission != null) {
7595                    allowed = false;
7596                }
7597            }
7598            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7599                if (pi.writePermission != null) {
7600                    allowed = false;
7601                }
7602            }
7603            if (allowed) {
7604                return -1;
7605            }
7606        }
7607
7608        /* There is a special cross user grant if:
7609         * - The target is on another user.
7610         * - Apps on the current user can access the uri without any uid permissions.
7611         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7612         * grant uri permissions.
7613         */
7614        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7615                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7616                modeFlags, false /*without considering the uid permissions*/);
7617
7618        // Second...  is the provider allowing granting of URI permissions?
7619        if (!specialCrossUserGrant) {
7620            if (!pi.grantUriPermissions) {
7621                throw new SecurityException("Provider " + pi.packageName
7622                        + "/" + pi.name
7623                        + " does not allow granting of Uri permissions (uri "
7624                        + grantUri + ")");
7625            }
7626            if (pi.uriPermissionPatterns != null) {
7627                final int N = pi.uriPermissionPatterns.length;
7628                boolean allowed = false;
7629                for (int i=0; i<N; i++) {
7630                    if (pi.uriPermissionPatterns[i] != null
7631                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7632                        allowed = true;
7633                        break;
7634                    }
7635                }
7636                if (!allowed) {
7637                    throw new SecurityException("Provider " + pi.packageName
7638                            + "/" + pi.name
7639                            + " does not allow granting of permission to path of Uri "
7640                            + grantUri);
7641                }
7642            }
7643        }
7644
7645        // Third...  does the caller itself have permission to access
7646        // this uri?
7647        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7648            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7649                // Require they hold a strong enough Uri permission
7650                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7651                    throw new SecurityException("Uid " + callingUid
7652                            + " does not have permission to uri " + grantUri);
7653                }
7654            }
7655        }
7656        return targetUid;
7657    }
7658
7659    /**
7660     * @param uri This uri must NOT contain an embedded userId.
7661     * @param userId The userId in which the uri is to be resolved.
7662     */
7663    @Override
7664    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7665            final int modeFlags, int userId) {
7666        enforceNotIsolatedCaller("checkGrantUriPermission");
7667        synchronized(this) {
7668            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7669                    new GrantUri(userId, uri, false), modeFlags, -1);
7670        }
7671    }
7672
7673    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7674            final int modeFlags, UriPermissionOwner owner) {
7675        if (!Intent.isAccessUriMode(modeFlags)) {
7676            return;
7677        }
7678
7679        // So here we are: the caller has the assumed permission
7680        // to the uri, and the target doesn't.  Let's now give this to
7681        // the target.
7682
7683        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7684                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7685
7686        final String authority = grantUri.uri.getAuthority();
7687        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7688        if (pi == null) {
7689            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7690            return;
7691        }
7692
7693        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7694            grantUri.prefix = true;
7695        }
7696        final UriPermission perm = findOrCreateUriPermissionLocked(
7697                pi.packageName, targetPkg, targetUid, grantUri);
7698        perm.grantModes(modeFlags, owner);
7699    }
7700
7701    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7702            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7703        if (targetPkg == null) {
7704            throw new NullPointerException("targetPkg");
7705        }
7706        int targetUid;
7707        final IPackageManager pm = AppGlobals.getPackageManager();
7708        try {
7709            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7710        } catch (RemoteException ex) {
7711            return;
7712        }
7713
7714        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7715                targetUid);
7716        if (targetUid < 0) {
7717            return;
7718        }
7719
7720        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7721                owner);
7722    }
7723
7724    static class NeededUriGrants extends ArrayList<GrantUri> {
7725        final String targetPkg;
7726        final int targetUid;
7727        final int flags;
7728
7729        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7730            this.targetPkg = targetPkg;
7731            this.targetUid = targetUid;
7732            this.flags = flags;
7733        }
7734    }
7735
7736    /**
7737     * Like checkGrantUriPermissionLocked, but takes an Intent.
7738     */
7739    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7740            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7741        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7742                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7743                + " clip=" + (intent != null ? intent.getClipData() : null)
7744                + " from " + intent + "; flags=0x"
7745                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7746
7747        if (targetPkg == null) {
7748            throw new NullPointerException("targetPkg");
7749        }
7750
7751        if (intent == null) {
7752            return null;
7753        }
7754        Uri data = intent.getData();
7755        ClipData clip = intent.getClipData();
7756        if (data == null && clip == null) {
7757            return null;
7758        }
7759        // Default userId for uris in the intent (if they don't specify it themselves)
7760        int contentUserHint = intent.getContentUserHint();
7761        if (contentUserHint == UserHandle.USER_CURRENT) {
7762            contentUserHint = UserHandle.getUserId(callingUid);
7763        }
7764        final IPackageManager pm = AppGlobals.getPackageManager();
7765        int targetUid;
7766        if (needed != null) {
7767            targetUid = needed.targetUid;
7768        } else {
7769            try {
7770                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7771            } catch (RemoteException ex) {
7772                return null;
7773            }
7774            if (targetUid < 0) {
7775                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7776                        "Can't grant URI permission no uid for: " + targetPkg
7777                        + " on user " + targetUserId);
7778                return null;
7779            }
7780        }
7781        if (data != null) {
7782            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7783            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7784                    targetUid);
7785            if (targetUid > 0) {
7786                if (needed == null) {
7787                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7788                }
7789                needed.add(grantUri);
7790            }
7791        }
7792        if (clip != null) {
7793            for (int i=0; i<clip.getItemCount(); i++) {
7794                Uri uri = clip.getItemAt(i).getUri();
7795                if (uri != null) {
7796                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7797                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7798                            targetUid);
7799                    if (targetUid > 0) {
7800                        if (needed == null) {
7801                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7802                        }
7803                        needed.add(grantUri);
7804                    }
7805                } else {
7806                    Intent clipIntent = clip.getItemAt(i).getIntent();
7807                    if (clipIntent != null) {
7808                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7809                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7810                        if (newNeeded != null) {
7811                            needed = newNeeded;
7812                        }
7813                    }
7814                }
7815            }
7816        }
7817
7818        return needed;
7819    }
7820
7821    /**
7822     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7823     */
7824    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7825            UriPermissionOwner owner) {
7826        if (needed != null) {
7827            for (int i=0; i<needed.size(); i++) {
7828                GrantUri grantUri = needed.get(i);
7829                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7830                        grantUri, needed.flags, owner);
7831            }
7832        }
7833    }
7834
7835    void grantUriPermissionFromIntentLocked(int callingUid,
7836            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7837        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7838                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7839        if (needed == null) {
7840            return;
7841        }
7842
7843        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7844    }
7845
7846    /**
7847     * @param uri This uri must NOT contain an embedded userId.
7848     * @param userId The userId in which the uri is to be resolved.
7849     */
7850    @Override
7851    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7852            final int modeFlags, int userId) {
7853        enforceNotIsolatedCaller("grantUriPermission");
7854        GrantUri grantUri = new GrantUri(userId, uri, false);
7855        synchronized(this) {
7856            final ProcessRecord r = getRecordForAppLocked(caller);
7857            if (r == null) {
7858                throw new SecurityException("Unable to find app for caller "
7859                        + caller
7860                        + " when granting permission to uri " + grantUri);
7861            }
7862            if (targetPkg == null) {
7863                throw new IllegalArgumentException("null target");
7864            }
7865            if (grantUri == null) {
7866                throw new IllegalArgumentException("null uri");
7867            }
7868
7869            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7870                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7871                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7872                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7873
7874            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7875                    UserHandle.getUserId(r.uid));
7876        }
7877    }
7878
7879    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7880        if (perm.modeFlags == 0) {
7881            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7882                    perm.targetUid);
7883            if (perms != null) {
7884                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7885                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7886
7887                perms.remove(perm.uri);
7888                if (perms.isEmpty()) {
7889                    mGrantedUriPermissions.remove(perm.targetUid);
7890                }
7891            }
7892        }
7893    }
7894
7895    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7896        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7897                "Revoking all granted permissions to " + grantUri);
7898
7899        final IPackageManager pm = AppGlobals.getPackageManager();
7900        final String authority = grantUri.uri.getAuthority();
7901        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7902        if (pi == null) {
7903            Slog.w(TAG, "No content provider found for permission revoke: "
7904                    + grantUri.toSafeString());
7905            return;
7906        }
7907
7908        // Does the caller have this permission on the URI?
7909        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7910            // If they don't have direct access to the URI, then revoke any
7911            // ownerless URI permissions that have been granted to them.
7912            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7913            if (perms != null) {
7914                boolean persistChanged = false;
7915                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7916                    final UriPermission perm = it.next();
7917                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7918                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7919                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7920                                "Revoking non-owned " + perm.targetUid
7921                                + " permission to " + perm.uri);
7922                        persistChanged |= perm.revokeModes(
7923                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7924                        if (perm.modeFlags == 0) {
7925                            it.remove();
7926                        }
7927                    }
7928                }
7929                if (perms.isEmpty()) {
7930                    mGrantedUriPermissions.remove(callingUid);
7931                }
7932                if (persistChanged) {
7933                    schedulePersistUriGrants();
7934                }
7935            }
7936            return;
7937        }
7938
7939        boolean persistChanged = false;
7940
7941        // Go through all of the permissions and remove any that match.
7942        int N = mGrantedUriPermissions.size();
7943        for (int i = 0; i < N; i++) {
7944            final int targetUid = mGrantedUriPermissions.keyAt(i);
7945            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7946
7947            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7948                final UriPermission perm = it.next();
7949                if (perm.uri.sourceUserId == grantUri.sourceUserId
7950                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7951                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7952                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7953                    persistChanged |= perm.revokeModes(
7954                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7955                    if (perm.modeFlags == 0) {
7956                        it.remove();
7957                    }
7958                }
7959            }
7960
7961            if (perms.isEmpty()) {
7962                mGrantedUriPermissions.remove(targetUid);
7963                N--;
7964                i--;
7965            }
7966        }
7967
7968        if (persistChanged) {
7969            schedulePersistUriGrants();
7970        }
7971    }
7972
7973    /**
7974     * @param uri This uri must NOT contain an embedded userId.
7975     * @param userId The userId in which the uri is to be resolved.
7976     */
7977    @Override
7978    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7979            int userId) {
7980        enforceNotIsolatedCaller("revokeUriPermission");
7981        synchronized(this) {
7982            final ProcessRecord r = getRecordForAppLocked(caller);
7983            if (r == null) {
7984                throw new SecurityException("Unable to find app for caller "
7985                        + caller
7986                        + " when revoking permission to uri " + uri);
7987            }
7988            if (uri == null) {
7989                Slog.w(TAG, "revokeUriPermission: null uri");
7990                return;
7991            }
7992
7993            if (!Intent.isAccessUriMode(modeFlags)) {
7994                return;
7995            }
7996
7997            final String authority = uri.getAuthority();
7998            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7999            if (pi == null) {
8000                Slog.w(TAG, "No content provider found for permission revoke: "
8001                        + uri.toSafeString());
8002                return;
8003            }
8004
8005            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8006        }
8007    }
8008
8009    /**
8010     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8011     * given package.
8012     *
8013     * @param packageName Package name to match, or {@code null} to apply to all
8014     *            packages.
8015     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8016     *            to all users.
8017     * @param persistable If persistable grants should be removed.
8018     */
8019    private void removeUriPermissionsForPackageLocked(
8020            String packageName, int userHandle, boolean persistable) {
8021        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8022            throw new IllegalArgumentException("Must narrow by either package or user");
8023        }
8024
8025        boolean persistChanged = false;
8026
8027        int N = mGrantedUriPermissions.size();
8028        for (int i = 0; i < N; i++) {
8029            final int targetUid = mGrantedUriPermissions.keyAt(i);
8030            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8031
8032            // Only inspect grants matching user
8033            if (userHandle == UserHandle.USER_ALL
8034                    || userHandle == UserHandle.getUserId(targetUid)) {
8035                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8036                    final UriPermission perm = it.next();
8037
8038                    // Only inspect grants matching package
8039                    if (packageName == null || perm.sourcePkg.equals(packageName)
8040                            || perm.targetPkg.equals(packageName)) {
8041                        persistChanged |= perm.revokeModes(persistable
8042                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8043
8044                        // Only remove when no modes remain; any persisted grants
8045                        // will keep this alive.
8046                        if (perm.modeFlags == 0) {
8047                            it.remove();
8048                        }
8049                    }
8050                }
8051
8052                if (perms.isEmpty()) {
8053                    mGrantedUriPermissions.remove(targetUid);
8054                    N--;
8055                    i--;
8056                }
8057            }
8058        }
8059
8060        if (persistChanged) {
8061            schedulePersistUriGrants();
8062        }
8063    }
8064
8065    @Override
8066    public IBinder newUriPermissionOwner(String name) {
8067        enforceNotIsolatedCaller("newUriPermissionOwner");
8068        synchronized(this) {
8069            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8070            return owner.getExternalTokenLocked();
8071        }
8072    }
8073
8074    /**
8075     * @param uri This uri must NOT contain an embedded userId.
8076     * @param sourceUserId The userId in which the uri is to be resolved.
8077     * @param targetUserId The userId of the app that receives the grant.
8078     */
8079    @Override
8080    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8081            final int modeFlags, int sourceUserId, int targetUserId) {
8082        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8083                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8084                "grantUriPermissionFromOwner", null);
8085        synchronized(this) {
8086            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8087            if (owner == null) {
8088                throw new IllegalArgumentException("Unknown owner: " + token);
8089            }
8090            if (fromUid != Binder.getCallingUid()) {
8091                if (Binder.getCallingUid() != Process.myUid()) {
8092                    // Only system code can grant URI permissions on behalf
8093                    // of other users.
8094                    throw new SecurityException("nice try");
8095                }
8096            }
8097            if (targetPkg == null) {
8098                throw new IllegalArgumentException("null target");
8099            }
8100            if (uri == null) {
8101                throw new IllegalArgumentException("null uri");
8102            }
8103
8104            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8105                    modeFlags, owner, targetUserId);
8106        }
8107    }
8108
8109    /**
8110     * @param uri This uri must NOT contain an embedded userId.
8111     * @param userId The userId in which the uri is to be resolved.
8112     */
8113    @Override
8114    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8115        synchronized(this) {
8116            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8117            if (owner == null) {
8118                throw new IllegalArgumentException("Unknown owner: " + token);
8119            }
8120
8121            if (uri == null) {
8122                owner.removeUriPermissionsLocked(mode);
8123            } else {
8124                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8125            }
8126        }
8127    }
8128
8129    private void schedulePersistUriGrants() {
8130        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8131            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8132                    10 * DateUtils.SECOND_IN_MILLIS);
8133        }
8134    }
8135
8136    private void writeGrantedUriPermissions() {
8137        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8138
8139        // Snapshot permissions so we can persist without lock
8140        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8141        synchronized (this) {
8142            final int size = mGrantedUriPermissions.size();
8143            for (int i = 0; i < size; i++) {
8144                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8145                for (UriPermission perm : perms.values()) {
8146                    if (perm.persistedModeFlags != 0) {
8147                        persist.add(perm.snapshot());
8148                    }
8149                }
8150            }
8151        }
8152
8153        FileOutputStream fos = null;
8154        try {
8155            fos = mGrantFile.startWrite();
8156
8157            XmlSerializer out = new FastXmlSerializer();
8158            out.setOutput(fos, StandardCharsets.UTF_8.name());
8159            out.startDocument(null, true);
8160            out.startTag(null, TAG_URI_GRANTS);
8161            for (UriPermission.Snapshot perm : persist) {
8162                out.startTag(null, TAG_URI_GRANT);
8163                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8164                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8165                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8166                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8167                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8168                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8169                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8170                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8171                out.endTag(null, TAG_URI_GRANT);
8172            }
8173            out.endTag(null, TAG_URI_GRANTS);
8174            out.endDocument();
8175
8176            mGrantFile.finishWrite(fos);
8177        } catch (IOException e) {
8178            if (fos != null) {
8179                mGrantFile.failWrite(fos);
8180            }
8181        }
8182    }
8183
8184    private void readGrantedUriPermissionsLocked() {
8185        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8186
8187        final long now = System.currentTimeMillis();
8188
8189        FileInputStream fis = null;
8190        try {
8191            fis = mGrantFile.openRead();
8192            final XmlPullParser in = Xml.newPullParser();
8193            in.setInput(fis, StandardCharsets.UTF_8.name());
8194
8195            int type;
8196            while ((type = in.next()) != END_DOCUMENT) {
8197                final String tag = in.getName();
8198                if (type == START_TAG) {
8199                    if (TAG_URI_GRANT.equals(tag)) {
8200                        final int sourceUserId;
8201                        final int targetUserId;
8202                        final int userHandle = readIntAttribute(in,
8203                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8204                        if (userHandle != UserHandle.USER_NULL) {
8205                            // For backwards compatibility.
8206                            sourceUserId = userHandle;
8207                            targetUserId = userHandle;
8208                        } else {
8209                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8210                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8211                        }
8212                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8213                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8214                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8215                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8216                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8217                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8218
8219                        // Sanity check that provider still belongs to source package
8220                        final ProviderInfo pi = getProviderInfoLocked(
8221                                uri.getAuthority(), sourceUserId);
8222                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8223                            int targetUid = -1;
8224                            try {
8225                                targetUid = AppGlobals.getPackageManager()
8226                                        .getPackageUid(targetPkg, targetUserId);
8227                            } catch (RemoteException e) {
8228                            }
8229                            if (targetUid != -1) {
8230                                final UriPermission perm = findOrCreateUriPermissionLocked(
8231                                        sourcePkg, targetPkg, targetUid,
8232                                        new GrantUri(sourceUserId, uri, prefix));
8233                                perm.initPersistedModes(modeFlags, createdTime);
8234                            }
8235                        } else {
8236                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8237                                    + " but instead found " + pi);
8238                        }
8239                    }
8240                }
8241            }
8242        } catch (FileNotFoundException e) {
8243            // Missing grants is okay
8244        } catch (IOException e) {
8245            Slog.wtf(TAG, "Failed reading Uri grants", e);
8246        } catch (XmlPullParserException e) {
8247            Slog.wtf(TAG, "Failed reading Uri grants", e);
8248        } finally {
8249            IoUtils.closeQuietly(fis);
8250        }
8251    }
8252
8253    /**
8254     * @param uri This uri must NOT contain an embedded userId.
8255     * @param userId The userId in which the uri is to be resolved.
8256     */
8257    @Override
8258    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8259        enforceNotIsolatedCaller("takePersistableUriPermission");
8260
8261        Preconditions.checkFlagsArgument(modeFlags,
8262                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8263
8264        synchronized (this) {
8265            final int callingUid = Binder.getCallingUid();
8266            boolean persistChanged = false;
8267            GrantUri grantUri = new GrantUri(userId, uri, false);
8268
8269            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8270                    new GrantUri(userId, uri, false));
8271            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8272                    new GrantUri(userId, uri, true));
8273
8274            final boolean exactValid = (exactPerm != null)
8275                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8276            final boolean prefixValid = (prefixPerm != null)
8277                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8278
8279            if (!(exactValid || prefixValid)) {
8280                throw new SecurityException("No persistable permission grants found for UID "
8281                        + callingUid + " and Uri " + grantUri.toSafeString());
8282            }
8283
8284            if (exactValid) {
8285                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8286            }
8287            if (prefixValid) {
8288                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8289            }
8290
8291            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8292
8293            if (persistChanged) {
8294                schedulePersistUriGrants();
8295            }
8296        }
8297    }
8298
8299    /**
8300     * @param uri This uri must NOT contain an embedded userId.
8301     * @param userId The userId in which the uri is to be resolved.
8302     */
8303    @Override
8304    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8305        enforceNotIsolatedCaller("releasePersistableUriPermission");
8306
8307        Preconditions.checkFlagsArgument(modeFlags,
8308                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8309
8310        synchronized (this) {
8311            final int callingUid = Binder.getCallingUid();
8312            boolean persistChanged = false;
8313
8314            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8315                    new GrantUri(userId, uri, false));
8316            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8317                    new GrantUri(userId, uri, true));
8318            if (exactPerm == null && prefixPerm == null) {
8319                throw new SecurityException("No permission grants found for UID " + callingUid
8320                        + " and Uri " + uri.toSafeString());
8321            }
8322
8323            if (exactPerm != null) {
8324                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8325                removeUriPermissionIfNeededLocked(exactPerm);
8326            }
8327            if (prefixPerm != null) {
8328                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8329                removeUriPermissionIfNeededLocked(prefixPerm);
8330            }
8331
8332            if (persistChanged) {
8333                schedulePersistUriGrants();
8334            }
8335        }
8336    }
8337
8338    /**
8339     * Prune any older {@link UriPermission} for the given UID until outstanding
8340     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8341     *
8342     * @return if any mutations occured that require persisting.
8343     */
8344    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8345        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8346        if (perms == null) return false;
8347        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8348
8349        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8350        for (UriPermission perm : perms.values()) {
8351            if (perm.persistedModeFlags != 0) {
8352                persisted.add(perm);
8353            }
8354        }
8355
8356        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8357        if (trimCount <= 0) return false;
8358
8359        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8360        for (int i = 0; i < trimCount; i++) {
8361            final UriPermission perm = persisted.get(i);
8362
8363            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8364                    "Trimming grant created at " + perm.persistedCreateTime);
8365
8366            perm.releasePersistableModes(~0);
8367            removeUriPermissionIfNeededLocked(perm);
8368        }
8369
8370        return true;
8371    }
8372
8373    @Override
8374    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8375            String packageName, boolean incoming) {
8376        enforceNotIsolatedCaller("getPersistedUriPermissions");
8377        Preconditions.checkNotNull(packageName, "packageName");
8378
8379        final int callingUid = Binder.getCallingUid();
8380        final IPackageManager pm = AppGlobals.getPackageManager();
8381        try {
8382            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8383            if (packageUid != callingUid) {
8384                throw new SecurityException(
8385                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8386            }
8387        } catch (RemoteException e) {
8388            throw new SecurityException("Failed to verify package name ownership");
8389        }
8390
8391        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8392        synchronized (this) {
8393            if (incoming) {
8394                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8395                        callingUid);
8396                if (perms == null) {
8397                    Slog.w(TAG, "No permission grants found for " + packageName);
8398                } else {
8399                    for (UriPermission perm : perms.values()) {
8400                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8401                            result.add(perm.buildPersistedPublicApiObject());
8402                        }
8403                    }
8404                }
8405            } else {
8406                final int size = mGrantedUriPermissions.size();
8407                for (int i = 0; i < size; i++) {
8408                    final ArrayMap<GrantUri, UriPermission> perms =
8409                            mGrantedUriPermissions.valueAt(i);
8410                    for (UriPermission perm : perms.values()) {
8411                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8412                            result.add(perm.buildPersistedPublicApiObject());
8413                        }
8414                    }
8415                }
8416            }
8417        }
8418        return new ParceledListSlice<android.content.UriPermission>(result);
8419    }
8420
8421    @Override
8422    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8423        synchronized (this) {
8424            ProcessRecord app =
8425                who != null ? getRecordForAppLocked(who) : null;
8426            if (app == null) return;
8427
8428            Message msg = Message.obtain();
8429            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8430            msg.obj = app;
8431            msg.arg1 = waiting ? 1 : 0;
8432            mUiHandler.sendMessage(msg);
8433        }
8434    }
8435
8436    @Override
8437    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8438        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8439        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8440        outInfo.availMem = Process.getFreeMemory();
8441        outInfo.totalMem = Process.getTotalMemory();
8442        outInfo.threshold = homeAppMem;
8443        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8444        outInfo.hiddenAppThreshold = cachedAppMem;
8445        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8446                ProcessList.SERVICE_ADJ);
8447        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8448                ProcessList.VISIBLE_APP_ADJ);
8449        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8450                ProcessList.FOREGROUND_APP_ADJ);
8451    }
8452
8453    // =========================================================
8454    // TASK MANAGEMENT
8455    // =========================================================
8456
8457    @Override
8458    public List<IAppTask> getAppTasks(String callingPackage) {
8459        int callingUid = Binder.getCallingUid();
8460        long ident = Binder.clearCallingIdentity();
8461
8462        synchronized(this) {
8463            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8464            try {
8465                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8466
8467                final int N = mRecentTasks.size();
8468                for (int i = 0; i < N; i++) {
8469                    TaskRecord tr = mRecentTasks.get(i);
8470                    // Skip tasks that do not match the caller.  We don't need to verify
8471                    // callingPackage, because we are also limiting to callingUid and know
8472                    // that will limit to the correct security sandbox.
8473                    if (tr.effectiveUid != callingUid) {
8474                        continue;
8475                    }
8476                    Intent intent = tr.getBaseIntent();
8477                    if (intent == null ||
8478                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8479                        continue;
8480                    }
8481                    ActivityManager.RecentTaskInfo taskInfo =
8482                            createRecentTaskInfoFromTaskRecord(tr);
8483                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8484                    list.add(taskImpl);
8485                }
8486            } finally {
8487                Binder.restoreCallingIdentity(ident);
8488            }
8489            return list;
8490        }
8491    }
8492
8493    @Override
8494    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8495        final int callingUid = Binder.getCallingUid();
8496        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8497
8498        synchronized(this) {
8499            if (DEBUG_ALL) Slog.v(
8500                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8501
8502            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8503                    callingUid);
8504
8505            // TODO: Improve with MRU list from all ActivityStacks.
8506            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8507        }
8508
8509        return list;
8510    }
8511
8512    /**
8513     * Creates a new RecentTaskInfo from a TaskRecord.
8514     */
8515    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8516        // Update the task description to reflect any changes in the task stack
8517        tr.updateTaskDescription();
8518
8519        // Compose the recent task info
8520        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8521        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8522        rti.persistentId = tr.taskId;
8523        rti.baseIntent = new Intent(tr.getBaseIntent());
8524        rti.origActivity = tr.origActivity;
8525        rti.realActivity = tr.realActivity;
8526        rti.description = tr.lastDescription;
8527        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8528        rti.userId = tr.userId;
8529        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8530        rti.firstActiveTime = tr.firstActiveTime;
8531        rti.lastActiveTime = tr.lastActiveTime;
8532        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8533        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8534        rti.numActivities = 0;
8535        if (tr.mBounds != null) {
8536            rti.bounds = new Rect(tr.mBounds);
8537        }
8538
8539        ActivityRecord base = null;
8540        ActivityRecord top = null;
8541        ActivityRecord tmp;
8542
8543        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8544            tmp = tr.mActivities.get(i);
8545            if (tmp.finishing) {
8546                continue;
8547            }
8548            base = tmp;
8549            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8550                top = base;
8551            }
8552            rti.numActivities++;
8553        }
8554
8555        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8556        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8557
8558        return rti;
8559    }
8560
8561    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8562        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8563                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8564        if (!allowed) {
8565            if (checkPermission(android.Manifest.permission.GET_TASKS,
8566                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8567                // Temporary compatibility: some existing apps on the system image may
8568                // still be requesting the old permission and not switched to the new
8569                // one; if so, we'll still allow them full access.  This means we need
8570                // to see if they are holding the old permission and are a system app.
8571                try {
8572                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8573                        allowed = true;
8574                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8575                                + " is using old GET_TASKS but privileged; allowing");
8576                    }
8577                } catch (RemoteException e) {
8578                }
8579            }
8580        }
8581        if (!allowed) {
8582            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8583                    + " does not hold REAL_GET_TASKS; limiting output");
8584        }
8585        return allowed;
8586    }
8587
8588    @Override
8589    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8590        final int callingUid = Binder.getCallingUid();
8591        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8592                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8593
8594        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8595        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8596        synchronized (this) {
8597            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8598                    callingUid);
8599            final boolean detailed = checkCallingPermission(
8600                    android.Manifest.permission.GET_DETAILED_TASKS)
8601                    == PackageManager.PERMISSION_GRANTED;
8602
8603            final int recentsCount = mRecentTasks.size();
8604            ArrayList<ActivityManager.RecentTaskInfo> res =
8605                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8606
8607            final Set<Integer> includedUsers;
8608            if (includeProfiles) {
8609                includedUsers = mUserController.getProfileIds(userId);
8610            } else {
8611                includedUsers = new HashSet<>();
8612            }
8613            includedUsers.add(Integer.valueOf(userId));
8614
8615            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8616                TaskRecord tr = mRecentTasks.get(i);
8617                // Only add calling user or related users recent tasks
8618                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8619                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8620                    continue;
8621                }
8622
8623                // Return the entry if desired by the caller.  We always return
8624                // the first entry, because callers always expect this to be the
8625                // foreground app.  We may filter others if the caller has
8626                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8627                // we should exclude the entry.
8628
8629                if (i == 0
8630                        || withExcluded
8631                        || (tr.intent == null)
8632                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8633                                == 0)) {
8634                    if (!allowed) {
8635                        // If the caller doesn't have the GET_TASKS permission, then only
8636                        // allow them to see a small subset of tasks -- their own and home.
8637                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8638                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8639                            continue;
8640                        }
8641                    }
8642                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8643                        if (tr.stack != null && tr.stack.isHomeStack()) {
8644                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8645                                    "Skipping, home stack task: " + tr);
8646                            continue;
8647                        }
8648                    }
8649                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8650                        // Don't include auto remove tasks that are finished or finishing.
8651                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8652                                "Skipping, auto-remove without activity: " + tr);
8653                        continue;
8654                    }
8655                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8656                            && !tr.isAvailable) {
8657                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8658                                "Skipping, unavail real act: " + tr);
8659                        continue;
8660                    }
8661
8662                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8663                    if (!detailed) {
8664                        rti.baseIntent.replaceExtras((Bundle)null);
8665                    }
8666
8667                    res.add(rti);
8668                    maxNum--;
8669                }
8670            }
8671            return res;
8672        }
8673    }
8674
8675    @Override
8676    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8677        synchronized (this) {
8678            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8679                    "getTaskThumbnail()");
8680            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8681                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8682            if (tr != null) {
8683                return tr.getTaskThumbnailLocked();
8684            }
8685        }
8686        return null;
8687    }
8688
8689    @Override
8690    public int addAppTask(IBinder activityToken, Intent intent,
8691            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8692        final int callingUid = Binder.getCallingUid();
8693        final long callingIdent = Binder.clearCallingIdentity();
8694
8695        try {
8696            synchronized (this) {
8697                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8698                if (r == null) {
8699                    throw new IllegalArgumentException("Activity does not exist; token="
8700                            + activityToken);
8701                }
8702                ComponentName comp = intent.getComponent();
8703                if (comp == null) {
8704                    throw new IllegalArgumentException("Intent " + intent
8705                            + " must specify explicit component");
8706                }
8707                if (thumbnail.getWidth() != mThumbnailWidth
8708                        || thumbnail.getHeight() != mThumbnailHeight) {
8709                    throw new IllegalArgumentException("Bad thumbnail size: got "
8710                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8711                            + mThumbnailWidth + "x" + mThumbnailHeight);
8712                }
8713                if (intent.getSelector() != null) {
8714                    intent.setSelector(null);
8715                }
8716                if (intent.getSourceBounds() != null) {
8717                    intent.setSourceBounds(null);
8718                }
8719                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8720                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8721                        // The caller has added this as an auto-remove task...  that makes no
8722                        // sense, so turn off auto-remove.
8723                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8724                    }
8725                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8726                    // Must be a new task.
8727                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8728                }
8729                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8730                    mLastAddedTaskActivity = null;
8731                }
8732                ActivityInfo ainfo = mLastAddedTaskActivity;
8733                if (ainfo == null) {
8734                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8735                            comp, 0, UserHandle.getUserId(callingUid));
8736                    if (ainfo.applicationInfo.uid != callingUid) {
8737                        throw new SecurityException(
8738                                "Can't add task for another application: target uid="
8739                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8740                    }
8741                }
8742
8743                // Use the full screen as the context for the task thumbnail
8744                final Point displaySize = new Point();
8745                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
8746                r.task.stack.getDisplaySize(displaySize);
8747                thumbnailInfo.taskWidth = displaySize.x;
8748                thumbnailInfo.taskHeight = displaySize.y;
8749                thumbnailInfo.screenOrientation = mConfiguration.orientation;
8750
8751                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8752                        intent, description, thumbnailInfo);
8753
8754                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8755                if (trimIdx >= 0) {
8756                    // If this would have caused a trim, then we'll abort because that
8757                    // means it would be added at the end of the list but then just removed.
8758                    return INVALID_TASK_ID;
8759                }
8760
8761                final int N = mRecentTasks.size();
8762                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8763                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8764                    tr.removedFromRecents();
8765                }
8766
8767                task.inRecents = true;
8768                mRecentTasks.add(task);
8769                r.task.stack.addTask(task, false, false);
8770
8771                task.setLastThumbnailLocked(thumbnail);
8772                task.freeLastThumbnail();
8773
8774                return task.taskId;
8775            }
8776        } finally {
8777            Binder.restoreCallingIdentity(callingIdent);
8778        }
8779    }
8780
8781    @Override
8782    public Point getAppTaskThumbnailSize() {
8783        synchronized (this) {
8784            return new Point(mThumbnailWidth,  mThumbnailHeight);
8785        }
8786    }
8787
8788    @Override
8789    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8790        synchronized (this) {
8791            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8792            if (r != null) {
8793                r.setTaskDescription(td);
8794                r.task.updateTaskDescription();
8795            }
8796        }
8797    }
8798
8799    @Override
8800    public void setTaskResizeable(int taskId, boolean resizeable) {
8801        synchronized (this) {
8802            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
8803                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8804            if (task == null) {
8805                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8806                return;
8807            }
8808            if (task.mResizeable != resizeable) {
8809                task.mResizeable = resizeable;
8810                mWindowManager.setTaskResizeable(taskId, resizeable);
8811                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
8812                mStackSupervisor.resumeTopActivitiesLocked();
8813            }
8814        }
8815    }
8816
8817    @Override
8818    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
8819        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8820                "resizeTask()");
8821        long ident = Binder.clearCallingIdentity();
8822        try {
8823            synchronized (this) {
8824                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8825                if (task == null) {
8826                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8827                    return;
8828                }
8829                int stackId = task.stack.mStackId;
8830                // First, check if this is a non-resizeble task in docked stack or if the task size
8831                // is affected by the docked stack changing size. If so, instead of resizing, we
8832                // can only scroll the task. No need to update configuration.
8833                if (bounds != null && !task.mResizeable
8834                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
8835                    mWindowManager.scrollTask(task.taskId, bounds);
8836                    return;
8837                }
8838
8839                // Place the task in the right stack if it isn't there already based on
8840                // the requested bounds.
8841                // The stack transition logic is:
8842                // - a null bounds on a freeform task moves that task to fullscreen
8843                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
8844                //   that task to freeform
8845                // - otherwise the task is not moved
8846                if (!StackId.isTaskResizeAllowed(stackId)) {
8847                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
8848                }
8849                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
8850                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
8851                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
8852                    stackId = FREEFORM_WORKSPACE_STACK_ID;
8853                }
8854                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
8855                if (stackId != task.stack.mStackId) {
8856                    mStackSupervisor.moveTaskToStackUncheckedLocked(
8857                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
8858                    preserveWindow = false;
8859                }
8860
8861                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow);
8862            }
8863        } finally {
8864            Binder.restoreCallingIdentity(ident);
8865        }
8866    }
8867
8868    @Override
8869    public Rect getTaskBounds(int taskId) {
8870        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8871                "getTaskBounds()");
8872        long ident = Binder.clearCallingIdentity();
8873        Rect rect = new Rect();
8874        try {
8875            synchronized (this) {
8876                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
8877                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8878                if (task == null) {
8879                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
8880                    return rect;
8881                }
8882                if (task.stack != null) {
8883                    // Return the bounds from window manager since it will be adjusted for various
8884                    // things like the presense of a docked stack for tasks that aren't resizeable.
8885                    mWindowManager.getTaskBounds(task.taskId, rect);
8886                } else {
8887                    // Task isn't in window manager yet since it isn't associated with a stack.
8888                    // Return the persist value from activity manager
8889                    if (task.mBounds != null) {
8890                        rect.set(task.mBounds);
8891                    } else if (task.mLastNonFullscreenBounds != null) {
8892                        rect.set(task.mLastNonFullscreenBounds);
8893                    }
8894                }
8895            }
8896        } finally {
8897            Binder.restoreCallingIdentity(ident);
8898        }
8899        return rect;
8900    }
8901
8902    @Override
8903    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
8904        if (userId != UserHandle.getCallingUserId()) {
8905            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8906                    "getTaskDescriptionIcon");
8907        }
8908        final File passedIconFile = new File(filePath);
8909        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
8910                passedIconFile.getName());
8911        if (!legitIconFile.getPath().equals(filePath)
8912                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8913            throw new IllegalArgumentException("Bad file path: " + filePath);
8914        }
8915        return mTaskPersister.getTaskDescriptionIcon(filePath);
8916    }
8917
8918    @Override
8919    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8920            throws RemoteException {
8921        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8922                opts.getCustomInPlaceResId() == 0) {
8923            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8924                    "with valid animation");
8925        }
8926        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8927        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8928                opts.getCustomInPlaceResId());
8929        mWindowManager.executeAppTransition();
8930    }
8931
8932    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
8933            boolean removeFromRecents) {
8934        if (removeFromRecents) {
8935            mRecentTasks.remove(tr);
8936            tr.removedFromRecents();
8937        }
8938        ComponentName component = tr.getBaseIntent().getComponent();
8939        if (component == null) {
8940            Slog.w(TAG, "No component for base intent of task: " + tr);
8941            return;
8942        }
8943
8944        // Find any running services associated with this app and stop if needed.
8945        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8946
8947        if (!killProcess) {
8948            return;
8949        }
8950
8951        // Determine if the process(es) for this task should be killed.
8952        final String pkg = component.getPackageName();
8953        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8954        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8955        for (int i = 0; i < pmap.size(); i++) {
8956
8957            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8958            for (int j = 0; j < uids.size(); j++) {
8959                ProcessRecord proc = uids.valueAt(j);
8960                if (proc.userId != tr.userId) {
8961                    // Don't kill process for a different user.
8962                    continue;
8963                }
8964                if (proc == mHomeProcess) {
8965                    // Don't kill the home process along with tasks from the same package.
8966                    continue;
8967                }
8968                if (!proc.pkgList.containsKey(pkg)) {
8969                    // Don't kill process that is not associated with this task.
8970                    continue;
8971                }
8972
8973                for (int k = 0; k < proc.activities.size(); k++) {
8974                    TaskRecord otherTask = proc.activities.get(k).task;
8975                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8976                        // Don't kill process(es) that has an activity in a different task that is
8977                        // also in recents.
8978                        return;
8979                    }
8980                }
8981
8982                if (proc.foregroundServices) {
8983                    // Don't kill process(es) with foreground service.
8984                    return;
8985                }
8986
8987                // Add process to kill list.
8988                procsToKill.add(proc);
8989            }
8990        }
8991
8992        // Kill the running processes.
8993        for (int i = 0; i < procsToKill.size(); i++) {
8994            ProcessRecord pr = procsToKill.get(i);
8995            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8996                    && pr.curReceiver == null) {
8997                pr.kill("remove task", true);
8998            } else {
8999                // We delay killing processes that are not in the background or running a receiver.
9000                pr.waitingToKill = "remove task";
9001            }
9002        }
9003    }
9004
9005    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9006        // Remove all tasks with activities in the specified package from the list of recent tasks
9007        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9008            TaskRecord tr = mRecentTasks.get(i);
9009            if (tr.userId != userId) continue;
9010
9011            ComponentName cn = tr.intent.getComponent();
9012            if (cn != null && cn.getPackageName().equals(packageName)) {
9013                // If the package name matches, remove the task.
9014                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9015            }
9016        }
9017    }
9018
9019    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9020            int userId) {
9021
9022        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9023            TaskRecord tr = mRecentTasks.get(i);
9024            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9025                continue;
9026            }
9027
9028            ComponentName cn = tr.intent.getComponent();
9029            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9030                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9031            if (sameComponent) {
9032                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9033            }
9034        }
9035    }
9036
9037    /**
9038     * Removes the task with the specified task id.
9039     *
9040     * @param taskId Identifier of the task to be removed.
9041     * @param killProcess Kill any process associated with the task if possible.
9042     * @param removeFromRecents Whether to also remove the task from recents.
9043     * @return Returns true if the given task was found and removed.
9044     */
9045    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9046            boolean removeFromRecents) {
9047        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9048                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9049        if (tr != null) {
9050            tr.removeTaskActivitiesLocked();
9051            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9052            if (tr.isPersistable) {
9053                notifyTaskPersisterLocked(null, true);
9054            }
9055            return true;
9056        }
9057        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9058        return false;
9059    }
9060
9061    @Override
9062    public boolean removeTask(int taskId) {
9063        synchronized (this) {
9064            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
9065                    "removeTask()");
9066            long ident = Binder.clearCallingIdentity();
9067            try {
9068                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9069            } finally {
9070                Binder.restoreCallingIdentity(ident);
9071            }
9072        }
9073    }
9074
9075    /**
9076     * TODO: Add mController hook
9077     */
9078    @Override
9079    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9080        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9081
9082        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9083        synchronized(this) {
9084            moveTaskToFrontLocked(taskId, flags, bOptions);
9085        }
9086    }
9087
9088    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9089        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9090
9091        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9092                Binder.getCallingUid(), -1, -1, "Task to front")) {
9093            ActivityOptions.abort(options);
9094            return;
9095        }
9096        final long origId = Binder.clearCallingIdentity();
9097        try {
9098            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9099            if (task == null) {
9100                Slog.d(TAG, "Could not find task for id: "+ taskId);
9101                return;
9102            }
9103            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9104                mStackSupervisor.showLockTaskToast();
9105                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9106                return;
9107            }
9108            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9109            if (prev != null && prev.isRecentsActivity()) {
9110                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9111            }
9112            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
9113        } finally {
9114            Binder.restoreCallingIdentity(origId);
9115        }
9116        ActivityOptions.abort(options);
9117    }
9118
9119    /**
9120     * Moves an activity, and all of the other activities within the same task, to the bottom
9121     * of the history stack.  The activity's order within the task is unchanged.
9122     *
9123     * @param token A reference to the activity we wish to move
9124     * @param nonRoot If false then this only works if the activity is the root
9125     *                of a task; if true it will work for any activity in a task.
9126     * @return Returns true if the move completed, false if not.
9127     */
9128    @Override
9129    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9130        enforceNotIsolatedCaller("moveActivityTaskToBack");
9131        synchronized(this) {
9132            final long origId = Binder.clearCallingIdentity();
9133            try {
9134                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9135                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9136                if (task != null) {
9137                    if (mStackSupervisor.isLockedTask(task)) {
9138                        mStackSupervisor.showLockTaskToast();
9139                        return false;
9140                    }
9141                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9142                }
9143            } finally {
9144                Binder.restoreCallingIdentity(origId);
9145            }
9146        }
9147        return false;
9148    }
9149
9150    @Override
9151    public void moveTaskBackwards(int task) {
9152        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9153                "moveTaskBackwards()");
9154
9155        synchronized(this) {
9156            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9157                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9158                return;
9159            }
9160            final long origId = Binder.clearCallingIdentity();
9161            moveTaskBackwardsLocked(task);
9162            Binder.restoreCallingIdentity(origId);
9163        }
9164    }
9165
9166    private final void moveTaskBackwardsLocked(int task) {
9167        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9168    }
9169
9170    @Override
9171    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9172            IActivityContainerCallback callback) throws RemoteException {
9173        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9174                "createActivityContainer()");
9175        synchronized (this) {
9176            if (parentActivityToken == null) {
9177                throw new IllegalArgumentException("parent token must not be null");
9178            }
9179            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9180            if (r == null) {
9181                return null;
9182            }
9183            if (callback == null) {
9184                throw new IllegalArgumentException("callback must not be null");
9185            }
9186            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9187        }
9188    }
9189
9190    @Override
9191    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9192        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9193                "deleteActivityContainer()");
9194        synchronized (this) {
9195            mStackSupervisor.deleteActivityContainer(container);
9196        }
9197    }
9198
9199    @Override
9200    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9201        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9202                "createStackOnDisplay()");
9203        synchronized (this) {
9204            final int stackId = mStackSupervisor.getNextStackId();
9205            final ActivityStack stack =
9206                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9207            if (stack == null) {
9208                return null;
9209            }
9210            return stack.mActivityContainer;
9211        }
9212    }
9213
9214    @Override
9215    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9216        synchronized (this) {
9217            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9218            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9219                return stack.mActivityContainer.getDisplayId();
9220            }
9221            return Display.DEFAULT_DISPLAY;
9222        }
9223    }
9224
9225    @Override
9226    public int getActivityStackId(IBinder token) throws RemoteException {
9227        synchronized (this) {
9228            ActivityStack stack = ActivityRecord.getStackLocked(token);
9229            if (stack == null) {
9230                return INVALID_STACK_ID;
9231            }
9232            return stack.mStackId;
9233        }
9234    }
9235
9236    @Override
9237    public void moveActivityToStack(IBinder token, int stackId) throws RemoteException {
9238        if (stackId == HOME_STACK_ID) {
9239            throw new IllegalArgumentException(
9240                    "moveActivityToStack: Attempt to move token " + token + " to home stack");
9241        }
9242        synchronized (this) {
9243            long ident = Binder.clearCallingIdentity();
9244            try {
9245                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9246                if (r == null) {
9247                    throw new IllegalArgumentException(
9248                            "moveActivityToStack: No activity record matching token=" + token);
9249                }
9250                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveActivityToStack: moving r=" + r
9251                        + " to stackId=" + stackId);
9252                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, stackId, ON_TOP, !FORCE_FOCUS,
9253                        "moveActivityToStack", true /* animate */);
9254            } finally {
9255                Binder.restoreCallingIdentity(ident);
9256            }
9257        }
9258    }
9259
9260    @Override
9261    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9262        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9263                "moveTaskToStack()");
9264        if (stackId == HOME_STACK_ID) {
9265            throw new IllegalArgumentException(
9266                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9267        }
9268        synchronized (this) {
9269            long ident = Binder.clearCallingIdentity();
9270            try {
9271                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9272                        + " to stackId=" + stackId + " toTop=" + toTop);
9273                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9274                        "moveTaskToStack", true /* animate */);
9275            } finally {
9276                Binder.restoreCallingIdentity(ident);
9277            }
9278        }
9279    }
9280
9281    /**
9282     * Moves the input task to the docked stack.
9283     *
9284     * @param taskId Id of task to move.
9285     * @param createMode The mode the docked stack should be created in if it doesn't exist
9286     *                   already. See
9287     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9288     *                   and
9289     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9290     * @param toTop If the task and stack should be moved to the top.
9291     * @param animate Whether we should play an animation for the moving the task
9292     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9293     *                      docked stack. Pass {@code null} to use default bounds.
9294     */
9295    @Override
9296    public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9297            Rect initialBounds) {
9298        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9299                "moveTaskToDockedStack()");
9300        synchronized (this) {
9301            long ident = Binder.clearCallingIdentity();
9302            try {
9303                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9304                        + " to createMode=" + createMode + " toTop=" + toTop);
9305                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9306                mStackSupervisor.moveTaskToStackLocked(taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9307                        "moveTaskToDockedStack", animate);
9308            } finally {
9309                Binder.restoreCallingIdentity(ident);
9310            }
9311        }
9312    }
9313
9314    /**
9315     * Moves the top activity in the input stackId to the pinned stack.
9316     *
9317     * @param stackId Id of stack to move the top activity to pinned stack.
9318     * @param bounds Bounds to use for pinned stack.
9319     *
9320     * @return True if the top activity of the input stack was successfully moved to the pinned
9321     *          stack.
9322     */
9323    @Override
9324    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9325        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9326                "moveTopActivityToPinnedStack()");
9327        synchronized (this) {
9328            long ident = Binder.clearCallingIdentity();
9329            try {
9330                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9331            } finally {
9332                Binder.restoreCallingIdentity(ident);
9333            }
9334        }
9335    }
9336
9337    @Override
9338    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode) {
9339        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9340                "resizeStack()");
9341        long ident = Binder.clearCallingIdentity();
9342        try {
9343            synchronized (this) {
9344                mStackSupervisor.resizeStackLocked(
9345                        stackId, bounds, !PRESERVE_WINDOWS, allowResizeInDockedMode);
9346            }
9347        } finally {
9348            Binder.restoreCallingIdentity(ident);
9349        }
9350    }
9351
9352    @Override
9353    public void positionTaskInStack(int taskId, int stackId, int position) {
9354        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9355                "positionTaskInStack()");
9356        if (stackId == HOME_STACK_ID) {
9357            throw new IllegalArgumentException(
9358                    "positionTaskInStack: Attempt to change the position of task "
9359                    + taskId + " in/to home stack");
9360        }
9361        synchronized (this) {
9362            long ident = Binder.clearCallingIdentity();
9363            try {
9364                if (DEBUG_STACK) Slog.d(TAG_STACK,
9365                        "positionTaskInStack: positioning task=" + taskId
9366                        + " in stackId=" + stackId + " at position=" + position);
9367                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9368            } finally {
9369                Binder.restoreCallingIdentity(ident);
9370            }
9371        }
9372    }
9373
9374    @Override
9375    public List<StackInfo> getAllStackInfos() {
9376        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9377                "getAllStackInfos()");
9378        long ident = Binder.clearCallingIdentity();
9379        try {
9380            synchronized (this) {
9381                return mStackSupervisor.getAllStackInfosLocked();
9382            }
9383        } finally {
9384            Binder.restoreCallingIdentity(ident);
9385        }
9386    }
9387
9388    @Override
9389    public StackInfo getStackInfo(int stackId) {
9390        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9391                "getStackInfo()");
9392        long ident = Binder.clearCallingIdentity();
9393        try {
9394            synchronized (this) {
9395                return mStackSupervisor.getStackInfoLocked(stackId);
9396            }
9397        } finally {
9398            Binder.restoreCallingIdentity(ident);
9399        }
9400    }
9401
9402    @Override
9403    public boolean isInHomeStack(int taskId) {
9404        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9405                "getStackInfo()");
9406        long ident = Binder.clearCallingIdentity();
9407        try {
9408            synchronized (this) {
9409                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9410                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9411                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9412            }
9413        } finally {
9414            Binder.restoreCallingIdentity(ident);
9415        }
9416    }
9417
9418    @Override
9419    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9420        synchronized(this) {
9421            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9422        }
9423    }
9424
9425    @Override
9426    public void updateDeviceOwner(String packageName) {
9427        final int callingUid = Binder.getCallingUid();
9428        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9429            throw new SecurityException("updateDeviceOwner called from non-system process");
9430        }
9431        synchronized (this) {
9432            mDeviceOwnerName = packageName;
9433        }
9434    }
9435
9436    @Override
9437    public void updateLockTaskPackages(int userId, String[] packages) {
9438        final int callingUid = Binder.getCallingUid();
9439        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9440            throw new SecurityException("updateLockTaskPackage called from non-system process");
9441        }
9442        synchronized (this) {
9443            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9444                    Arrays.toString(packages));
9445            mLockTaskPackages.put(userId, packages);
9446            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9447        }
9448    }
9449
9450
9451    void startLockTaskModeLocked(TaskRecord task) {
9452        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9453        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9454            return;
9455        }
9456
9457        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9458        // is initiated by system after the pinning request was shown and locked mode is initiated
9459        // by an authorized app directly
9460        final int callingUid = Binder.getCallingUid();
9461        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9462        long ident = Binder.clearCallingIdentity();
9463        try {
9464            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9465            if (!isSystemInitiated) {
9466                task.mLockTaskUid = callingUid;
9467                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9468                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9469                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9470                    StatusBarManagerInternal statusBarManager =
9471                            LocalServices.getService(StatusBarManagerInternal.class);
9472                    if (statusBarManager != null) {
9473                        statusBarManager.showScreenPinningRequest();
9474                    }
9475                    return;
9476                }
9477
9478                if (stack == null || task != stack.topTask()) {
9479                    throw new IllegalArgumentException("Invalid task, not in foreground");
9480                }
9481            }
9482            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9483                    "Locking fully");
9484            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9485                    ActivityManager.LOCK_TASK_MODE_PINNED :
9486                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9487                    "startLockTask", true);
9488        } finally {
9489            Binder.restoreCallingIdentity(ident);
9490        }
9491    }
9492
9493    @Override
9494    public void startLockTaskMode(int taskId) {
9495        synchronized (this) {
9496            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9497            if (task != null) {
9498                startLockTaskModeLocked(task);
9499            }
9500        }
9501    }
9502
9503    @Override
9504    public void startLockTaskMode(IBinder token) {
9505        synchronized (this) {
9506            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9507            if (r == null) {
9508                return;
9509            }
9510            final TaskRecord task = r.task;
9511            if (task != null) {
9512                startLockTaskModeLocked(task);
9513            }
9514        }
9515    }
9516
9517    @Override
9518    public void startLockTaskModeOnCurrent() throws RemoteException {
9519        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9520                "startLockTaskModeOnCurrent");
9521        long ident = Binder.clearCallingIdentity();
9522        try {
9523            synchronized (this) {
9524                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9525                if (r != null) {
9526                    startLockTaskModeLocked(r.task);
9527                }
9528            }
9529        } finally {
9530            Binder.restoreCallingIdentity(ident);
9531        }
9532    }
9533
9534    @Override
9535    public void stopLockTaskMode() {
9536        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9537        if (lockTask == null) {
9538            // Our work here is done.
9539            return;
9540        }
9541
9542        final int callingUid = Binder.getCallingUid();
9543        final int lockTaskUid = lockTask.mLockTaskUid;
9544        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9545        // It is possible lockTaskMode was started by the system process because
9546        // android:lockTaskMode is set to a locking value in the application manifest instead of
9547        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9548        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9549        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9550                callingUid != lockTaskUid
9551                && (lockTaskUid != 0
9552                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9553            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9554                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9555        }
9556
9557        long ident = Binder.clearCallingIdentity();
9558        try {
9559            Log.d(TAG, "stopLockTaskMode");
9560            // Stop lock task
9561            synchronized (this) {
9562                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9563                        "stopLockTask", true);
9564            }
9565        } finally {
9566            Binder.restoreCallingIdentity(ident);
9567        }
9568    }
9569
9570    @Override
9571    public void stopLockTaskModeOnCurrent() throws RemoteException {
9572        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9573                "stopLockTaskModeOnCurrent");
9574        long ident = Binder.clearCallingIdentity();
9575        try {
9576            stopLockTaskMode();
9577        } finally {
9578            Binder.restoreCallingIdentity(ident);
9579        }
9580    }
9581
9582    @Override
9583    public boolean isInLockTaskMode() {
9584        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9585    }
9586
9587    @Override
9588    public int getLockTaskModeState() {
9589        synchronized (this) {
9590            return mStackSupervisor.getLockTaskModeState();
9591        }
9592    }
9593
9594    @Override
9595    public void showLockTaskEscapeMessage(IBinder token) {
9596        synchronized (this) {
9597            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9598            if (r == null) {
9599                return;
9600            }
9601            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9602        }
9603    }
9604
9605    // =========================================================
9606    // CONTENT PROVIDERS
9607    // =========================================================
9608
9609    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9610        List<ProviderInfo> providers = null;
9611        try {
9612            ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
9613                queryContentProviders(app.processName, app.uid,
9614                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9615            providers = slice != null ? slice.getList() : null;
9616        } catch (RemoteException ex) {
9617        }
9618        if (DEBUG_MU) Slog.v(TAG_MU,
9619                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9620        int userId = app.userId;
9621        if (providers != null) {
9622            int N = providers.size();
9623            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9624            for (int i=0; i<N; i++) {
9625                ProviderInfo cpi =
9626                    (ProviderInfo)providers.get(i);
9627                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9628                        cpi.name, cpi.flags);
9629                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
9630                    // This is a singleton provider, but a user besides the
9631                    // default user is asking to initialize a process it runs
9632                    // in...  well, no, it doesn't actually run in this process,
9633                    // it runs in the process of the default user.  Get rid of it.
9634                    providers.remove(i);
9635                    N--;
9636                    i--;
9637                    continue;
9638                }
9639
9640                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9641                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9642                if (cpr == null) {
9643                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9644                    mProviderMap.putProviderByClass(comp, cpr);
9645                }
9646                if (DEBUG_MU) Slog.v(TAG_MU,
9647                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9648                app.pubProviders.put(cpi.name, cpr);
9649                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9650                    // Don't add this if it is a platform component that is marked
9651                    // to run in multiple processes, because this is actually
9652                    // part of the framework so doesn't make sense to track as a
9653                    // separate apk in the process.
9654                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9655                            mProcessStats);
9656                }
9657                notifyPackageUse(cpi.applicationInfo.packageName);
9658            }
9659        }
9660        return providers;
9661    }
9662
9663    /**
9664     * Check if {@link ProcessRecord} has a possible chance at accessing the
9665     * given {@link ProviderInfo}. Final permission checking is always done
9666     * in {@link ContentProvider}.
9667     */
9668    private final String checkContentProviderPermissionLocked(
9669            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9670        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9671        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9672        boolean checkedGrants = false;
9673        if (checkUser) {
9674            // Looking for cross-user grants before enforcing the typical cross-users permissions
9675            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
9676            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9677                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9678                    return null;
9679                }
9680                checkedGrants = true;
9681            }
9682            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
9683                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
9684            if (userId != tmpTargetUserId) {
9685                // When we actually went to determine the final targer user ID, this ended
9686                // up different than our initial check for the authority.  This is because
9687                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9688                // SELF.  So we need to re-check the grants again.
9689                checkedGrants = false;
9690            }
9691        }
9692        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9693                cpi.applicationInfo.uid, cpi.exported)
9694                == PackageManager.PERMISSION_GRANTED) {
9695            return null;
9696        }
9697        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9698                cpi.applicationInfo.uid, cpi.exported)
9699                == PackageManager.PERMISSION_GRANTED) {
9700            return null;
9701        }
9702
9703        PathPermission[] pps = cpi.pathPermissions;
9704        if (pps != null) {
9705            int i = pps.length;
9706            while (i > 0) {
9707                i--;
9708                PathPermission pp = pps[i];
9709                String pprperm = pp.getReadPermission();
9710                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9711                        cpi.applicationInfo.uid, cpi.exported)
9712                        == PackageManager.PERMISSION_GRANTED) {
9713                    return null;
9714                }
9715                String ppwperm = pp.getWritePermission();
9716                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9717                        cpi.applicationInfo.uid, cpi.exported)
9718                        == PackageManager.PERMISSION_GRANTED) {
9719                    return null;
9720                }
9721            }
9722        }
9723        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9724            return null;
9725        }
9726
9727        String msg;
9728        if (!cpi.exported) {
9729            msg = "Permission Denial: opening provider " + cpi.name
9730                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9731                    + ", uid=" + callingUid + ") that is not exported from uid "
9732                    + cpi.applicationInfo.uid;
9733        } else {
9734            msg = "Permission Denial: opening provider " + cpi.name
9735                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9736                    + ", uid=" + callingUid + ") requires "
9737                    + cpi.readPermission + " or " + cpi.writePermission;
9738        }
9739        Slog.w(TAG, msg);
9740        return msg;
9741    }
9742
9743    /**
9744     * Returns if the ContentProvider has granted a uri to callingUid
9745     */
9746    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9747        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9748        if (perms != null) {
9749            for (int i=perms.size()-1; i>=0; i--) {
9750                GrantUri grantUri = perms.keyAt(i);
9751                if (grantUri.sourceUserId == userId || !checkUser) {
9752                    if (matchesProvider(grantUri.uri, cpi)) {
9753                        return true;
9754                    }
9755                }
9756            }
9757        }
9758        return false;
9759    }
9760
9761    /**
9762     * Returns true if the uri authority is one of the authorities specified in the provider.
9763     */
9764    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9765        String uriAuth = uri.getAuthority();
9766        String cpiAuth = cpi.authority;
9767        if (cpiAuth.indexOf(';') == -1) {
9768            return cpiAuth.equals(uriAuth);
9769        }
9770        String[] cpiAuths = cpiAuth.split(";");
9771        int length = cpiAuths.length;
9772        for (int i = 0; i < length; i++) {
9773            if (cpiAuths[i].equals(uriAuth)) return true;
9774        }
9775        return false;
9776    }
9777
9778    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9779            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9780        if (r != null) {
9781            for (int i=0; i<r.conProviders.size(); i++) {
9782                ContentProviderConnection conn = r.conProviders.get(i);
9783                if (conn.provider == cpr) {
9784                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9785                            "Adding provider requested by "
9786                            + r.processName + " from process "
9787                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9788                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9789                    if (stable) {
9790                        conn.stableCount++;
9791                        conn.numStableIncs++;
9792                    } else {
9793                        conn.unstableCount++;
9794                        conn.numUnstableIncs++;
9795                    }
9796                    return conn;
9797                }
9798            }
9799            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9800            if (stable) {
9801                conn.stableCount = 1;
9802                conn.numStableIncs = 1;
9803            } else {
9804                conn.unstableCount = 1;
9805                conn.numUnstableIncs = 1;
9806            }
9807            cpr.connections.add(conn);
9808            r.conProviders.add(conn);
9809            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9810            return conn;
9811        }
9812        cpr.addExternalProcessHandleLocked(externalProcessToken);
9813        return null;
9814    }
9815
9816    boolean decProviderCountLocked(ContentProviderConnection conn,
9817            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9818        if (conn != null) {
9819            cpr = conn.provider;
9820            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9821                    "Removing provider requested by "
9822                    + conn.client.processName + " from process "
9823                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9824                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9825            if (stable) {
9826                conn.stableCount--;
9827            } else {
9828                conn.unstableCount--;
9829            }
9830            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9831                cpr.connections.remove(conn);
9832                conn.client.conProviders.remove(conn);
9833                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
9834                    // The client is more important than last activity -- note the time this
9835                    // is happening, so we keep the old provider process around a bit as last
9836                    // activity to avoid thrashing it.
9837                    if (cpr.proc != null) {
9838                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
9839                    }
9840                }
9841                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9842                return true;
9843            }
9844            return false;
9845        }
9846        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9847        return false;
9848    }
9849
9850    private void checkTime(long startTime, String where) {
9851        long now = SystemClock.elapsedRealtime();
9852        if ((now-startTime) > 1000) {
9853            // If we are taking more than a second, log about it.
9854            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9855        }
9856    }
9857
9858    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9859            String name, IBinder token, boolean stable, int userId) {
9860        ContentProviderRecord cpr;
9861        ContentProviderConnection conn = null;
9862        ProviderInfo cpi = null;
9863
9864        synchronized(this) {
9865            long startTime = SystemClock.elapsedRealtime();
9866
9867            ProcessRecord r = null;
9868            if (caller != null) {
9869                r = getRecordForAppLocked(caller);
9870                if (r == null) {
9871                    throw new SecurityException(
9872                            "Unable to find app for caller " + caller
9873                          + " (pid=" + Binder.getCallingPid()
9874                          + ") when getting content provider " + name);
9875                }
9876            }
9877
9878            boolean checkCrossUser = true;
9879
9880            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9881
9882            // First check if this content provider has been published...
9883            cpr = mProviderMap.getProviderByName(name, userId);
9884            // If that didn't work, check if it exists for user 0 and then
9885            // verify that it's a singleton provider before using it.
9886            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
9887                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
9888                if (cpr != null) {
9889                    cpi = cpr.info;
9890                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9891                            cpi.name, cpi.flags)
9892                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9893                        userId = UserHandle.USER_SYSTEM;
9894                        checkCrossUser = false;
9895                    } else {
9896                        cpr = null;
9897                        cpi = null;
9898                    }
9899                }
9900            }
9901
9902            boolean providerRunning = cpr != null;
9903            if (providerRunning) {
9904                cpi = cpr.info;
9905                String msg;
9906                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9907                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9908                        != null) {
9909                    throw new SecurityException(msg);
9910                }
9911                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9912
9913                if (r != null && cpr.canRunHere(r)) {
9914                    // This provider has been published or is in the process
9915                    // of being published...  but it is also allowed to run
9916                    // in the caller's process, so don't make a connection
9917                    // and just let the caller instantiate its own instance.
9918                    ContentProviderHolder holder = cpr.newHolder(null);
9919                    // don't give caller the provider object, it needs
9920                    // to make its own.
9921                    holder.provider = null;
9922                    return holder;
9923                }
9924
9925                final long origId = Binder.clearCallingIdentity();
9926
9927                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9928
9929                // In this case the provider instance already exists, so we can
9930                // return it right away.
9931                conn = incProviderCountLocked(r, cpr, token, stable);
9932                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9933                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9934                        // If this is a perceptible app accessing the provider,
9935                        // make sure to count it as being accessed and thus
9936                        // back up on the LRU list.  This is good because
9937                        // content providers are often expensive to start.
9938                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9939                        updateLruProcessLocked(cpr.proc, false, null);
9940                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9941                    }
9942                }
9943
9944                if (cpr.proc != null) {
9945                    if (false) {
9946                        if (cpr.name.flattenToShortString().equals(
9947                                "com.android.providers.calendar/.CalendarProvider2")) {
9948                            Slog.v(TAG, "****************** KILLING "
9949                                + cpr.name.flattenToShortString());
9950                            Process.killProcess(cpr.proc.pid);
9951                        }
9952                    }
9953                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9954                    boolean success = updateOomAdjLocked(cpr.proc);
9955                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9956                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9957                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9958                    // NOTE: there is still a race here where a signal could be
9959                    // pending on the process even though we managed to update its
9960                    // adj level.  Not sure what to do about this, but at least
9961                    // the race is now smaller.
9962                    if (!success) {
9963                        // Uh oh...  it looks like the provider's process
9964                        // has been killed on us.  We need to wait for a new
9965                        // process to be started, and make sure its death
9966                        // doesn't kill our process.
9967                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9968                                + " is crashing; detaching " + r);
9969                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9970                        checkTime(startTime, "getContentProviderImpl: before appDied");
9971                        appDiedLocked(cpr.proc);
9972                        checkTime(startTime, "getContentProviderImpl: after appDied");
9973                        if (!lastRef) {
9974                            // This wasn't the last ref our process had on
9975                            // the provider...  we have now been killed, bail.
9976                            return null;
9977                        }
9978                        providerRunning = false;
9979                        conn = null;
9980                    }
9981                }
9982
9983                Binder.restoreCallingIdentity(origId);
9984            }
9985
9986            if (!providerRunning) {
9987                try {
9988                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9989                    cpi = AppGlobals.getPackageManager().
9990                        resolveContentProvider(name,
9991                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9992                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9993                } catch (RemoteException ex) {
9994                }
9995                if (cpi == null) {
9996                    return null;
9997                }
9998                // If the provider is a singleton AND
9999                // (it's a call within the same user || the provider is a
10000                // privileged app)
10001                // Then allow connecting to the singleton provider
10002                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10003                        cpi.name, cpi.flags)
10004                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10005                if (singleton) {
10006                    userId = UserHandle.USER_SYSTEM;
10007                }
10008                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10009                checkTime(startTime, "getContentProviderImpl: got app info for user");
10010
10011                String msg;
10012                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10013                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10014                        != null) {
10015                    throw new SecurityException(msg);
10016                }
10017                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10018
10019                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
10020                        && !cpi.processName.equals("system")) {
10021                    // If this content provider does not run in the system
10022                    // process, and the system is not yet ready to run other
10023                    // processes, then fail fast instead of hanging.
10024                    throw new IllegalArgumentException(
10025                            "Attempt to launch content provider before system ready");
10026                }
10027
10028                // Make sure that the user who owns this provider is running.  If not,
10029                // we don't want to allow it to run.
10030                if (!mUserController.isUserRunningLocked(userId, 0)) {
10031                    Slog.w(TAG, "Unable to launch app "
10032                            + cpi.applicationInfo.packageName + "/"
10033                            + cpi.applicationInfo.uid + " for provider "
10034                            + name + ": user " + userId + " is stopped");
10035                    return null;
10036                }
10037
10038                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10039                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10040                cpr = mProviderMap.getProviderByClass(comp, userId);
10041                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10042                final boolean firstClass = cpr == null;
10043                if (firstClass) {
10044                    final long ident = Binder.clearCallingIdentity();
10045                    try {
10046                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10047                        ApplicationInfo ai =
10048                            AppGlobals.getPackageManager().
10049                                getApplicationInfo(
10050                                        cpi.applicationInfo.packageName,
10051                                        STOCK_PM_FLAGS, userId);
10052                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10053                        if (ai == null) {
10054                            Slog.w(TAG, "No package info for content provider "
10055                                    + cpi.name);
10056                            return null;
10057                        }
10058                        ai = getAppInfoForUser(ai, userId);
10059                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10060                    } catch (RemoteException ex) {
10061                        // pm is in same process, this will never happen.
10062                    } finally {
10063                        Binder.restoreCallingIdentity(ident);
10064                    }
10065                }
10066
10067                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10068
10069                if (r != null && cpr.canRunHere(r)) {
10070                    // If this is a multiprocess provider, then just return its
10071                    // info and allow the caller to instantiate it.  Only do
10072                    // this if the provider is the same user as the caller's
10073                    // process, or can run as root (so can be in any process).
10074                    return cpr.newHolder(null);
10075                }
10076
10077                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10078                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10079                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10080
10081                // This is single process, and our app is now connecting to it.
10082                // See if we are already in the process of launching this
10083                // provider.
10084                final int N = mLaunchingProviders.size();
10085                int i;
10086                for (i = 0; i < N; i++) {
10087                    if (mLaunchingProviders.get(i) == cpr) {
10088                        break;
10089                    }
10090                }
10091
10092                // If the provider is not already being launched, then get it
10093                // started.
10094                if (i >= N) {
10095                    final long origId = Binder.clearCallingIdentity();
10096
10097                    try {
10098                        // Content provider is now in use, its package can't be stopped.
10099                        try {
10100                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10101                            AppGlobals.getPackageManager().setPackageStoppedState(
10102                                    cpr.appInfo.packageName, false, userId);
10103                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10104                        } catch (RemoteException e) {
10105                        } catch (IllegalArgumentException e) {
10106                            Slog.w(TAG, "Failed trying to unstop package "
10107                                    + cpr.appInfo.packageName + ": " + e);
10108                        }
10109
10110                        // Use existing process if already started
10111                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10112                        ProcessRecord proc = getProcessRecordLocked(
10113                                cpi.processName, cpr.appInfo.uid, false);
10114                        if (proc != null && proc.thread != null) {
10115                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10116                                    "Installing in existing process " + proc);
10117                            if (!proc.pubProviders.containsKey(cpi.name)) {
10118                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10119                                proc.pubProviders.put(cpi.name, cpr);
10120                                try {
10121                                    proc.thread.scheduleInstallProvider(cpi);
10122                                } catch (RemoteException e) {
10123                                }
10124                            }
10125                        } else {
10126                            checkTime(startTime, "getContentProviderImpl: before start process");
10127                            proc = startProcessLocked(cpi.processName,
10128                                    cpr.appInfo, false, 0, "content provider",
10129                                    new ComponentName(cpi.applicationInfo.packageName,
10130                                            cpi.name), false, false, false);
10131                            checkTime(startTime, "getContentProviderImpl: after start process");
10132                            if (proc == null) {
10133                                Slog.w(TAG, "Unable to launch app "
10134                                        + cpi.applicationInfo.packageName + "/"
10135                                        + cpi.applicationInfo.uid + " for provider "
10136                                        + name + ": process is bad");
10137                                return null;
10138                            }
10139                        }
10140                        cpr.launchingApp = proc;
10141                        mLaunchingProviders.add(cpr);
10142                    } finally {
10143                        Binder.restoreCallingIdentity(origId);
10144                    }
10145                }
10146
10147                checkTime(startTime, "getContentProviderImpl: updating data structures");
10148
10149                // Make sure the provider is published (the same provider class
10150                // may be published under multiple names).
10151                if (firstClass) {
10152                    mProviderMap.putProviderByClass(comp, cpr);
10153                }
10154
10155                mProviderMap.putProviderByName(name, cpr);
10156                conn = incProviderCountLocked(r, cpr, token, stable);
10157                if (conn != null) {
10158                    conn.waiting = true;
10159                }
10160            }
10161            checkTime(startTime, "getContentProviderImpl: done!");
10162        }
10163
10164        // Wait for the provider to be published...
10165        synchronized (cpr) {
10166            while (cpr.provider == null) {
10167                if (cpr.launchingApp == null) {
10168                    Slog.w(TAG, "Unable to launch app "
10169                            + cpi.applicationInfo.packageName + "/"
10170                            + cpi.applicationInfo.uid + " for provider "
10171                            + name + ": launching app became null");
10172                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10173                            UserHandle.getUserId(cpi.applicationInfo.uid),
10174                            cpi.applicationInfo.packageName,
10175                            cpi.applicationInfo.uid, name);
10176                    return null;
10177                }
10178                try {
10179                    if (DEBUG_MU) Slog.v(TAG_MU,
10180                            "Waiting to start provider " + cpr
10181                            + " launchingApp=" + cpr.launchingApp);
10182                    if (conn != null) {
10183                        conn.waiting = true;
10184                    }
10185                    cpr.wait();
10186                } catch (InterruptedException ex) {
10187                } finally {
10188                    if (conn != null) {
10189                        conn.waiting = false;
10190                    }
10191                }
10192            }
10193        }
10194        return cpr != null ? cpr.newHolder(conn) : null;
10195    }
10196
10197    @Override
10198    public final ContentProviderHolder getContentProvider(
10199            IApplicationThread caller, String name, int userId, boolean stable) {
10200        enforceNotIsolatedCaller("getContentProvider");
10201        if (caller == null) {
10202            String msg = "null IApplicationThread when getting content provider "
10203                    + name;
10204            Slog.w(TAG, msg);
10205            throw new SecurityException(msg);
10206        }
10207        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10208        // with cross-user grant.
10209        return getContentProviderImpl(caller, name, null, stable, userId);
10210    }
10211
10212    public ContentProviderHolder getContentProviderExternal(
10213            String name, int userId, IBinder token) {
10214        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10215            "Do not have permission in call getContentProviderExternal()");
10216        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10217                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10218        return getContentProviderExternalUnchecked(name, token, userId);
10219    }
10220
10221    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10222            IBinder token, int userId) {
10223        return getContentProviderImpl(null, name, token, true, userId);
10224    }
10225
10226    /**
10227     * Drop a content provider from a ProcessRecord's bookkeeping
10228     */
10229    public void removeContentProvider(IBinder connection, boolean stable) {
10230        enforceNotIsolatedCaller("removeContentProvider");
10231        long ident = Binder.clearCallingIdentity();
10232        try {
10233            synchronized (this) {
10234                ContentProviderConnection conn;
10235                try {
10236                    conn = (ContentProviderConnection)connection;
10237                } catch (ClassCastException e) {
10238                    String msg ="removeContentProvider: " + connection
10239                            + " not a ContentProviderConnection";
10240                    Slog.w(TAG, msg);
10241                    throw new IllegalArgumentException(msg);
10242                }
10243                if (conn == null) {
10244                    throw new NullPointerException("connection is null");
10245                }
10246                if (decProviderCountLocked(conn, null, null, stable)) {
10247                    updateOomAdjLocked();
10248                }
10249            }
10250        } finally {
10251            Binder.restoreCallingIdentity(ident);
10252        }
10253    }
10254
10255    public void removeContentProviderExternal(String name, IBinder token) {
10256        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10257            "Do not have permission in call removeContentProviderExternal()");
10258        int userId = UserHandle.getCallingUserId();
10259        long ident = Binder.clearCallingIdentity();
10260        try {
10261            removeContentProviderExternalUnchecked(name, token, userId);
10262        } finally {
10263            Binder.restoreCallingIdentity(ident);
10264        }
10265    }
10266
10267    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10268        synchronized (this) {
10269            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10270            if(cpr == null) {
10271                //remove from mProvidersByClass
10272                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10273                return;
10274            }
10275
10276            //update content provider record entry info
10277            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10278            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10279            if (localCpr.hasExternalProcessHandles()) {
10280                if (localCpr.removeExternalProcessHandleLocked(token)) {
10281                    updateOomAdjLocked();
10282                } else {
10283                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10284                            + " with no external reference for token: "
10285                            + token + ".");
10286                }
10287            } else {
10288                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10289                        + " with no external references.");
10290            }
10291        }
10292    }
10293
10294    public final void publishContentProviders(IApplicationThread caller,
10295            List<ContentProviderHolder> providers) {
10296        if (providers == null) {
10297            return;
10298        }
10299
10300        enforceNotIsolatedCaller("publishContentProviders");
10301        synchronized (this) {
10302            final ProcessRecord r = getRecordForAppLocked(caller);
10303            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10304            if (r == null) {
10305                throw new SecurityException(
10306                        "Unable to find app for caller " + caller
10307                      + " (pid=" + Binder.getCallingPid()
10308                      + ") when publishing content providers");
10309            }
10310
10311            final long origId = Binder.clearCallingIdentity();
10312
10313            final int N = providers.size();
10314            for (int i = 0; i < N; i++) {
10315                ContentProviderHolder src = providers.get(i);
10316                if (src == null || src.info == null || src.provider == null) {
10317                    continue;
10318                }
10319                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10320                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10321                if (dst != null) {
10322                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10323                    mProviderMap.putProviderByClass(comp, dst);
10324                    String names[] = dst.info.authority.split(";");
10325                    for (int j = 0; j < names.length; j++) {
10326                        mProviderMap.putProviderByName(names[j], dst);
10327                    }
10328
10329                    int launchingCount = mLaunchingProviders.size();
10330                    int j;
10331                    boolean wasInLaunchingProviders = false;
10332                    for (j = 0; j < launchingCount; j++) {
10333                        if (mLaunchingProviders.get(j) == dst) {
10334                            mLaunchingProviders.remove(j);
10335                            wasInLaunchingProviders = true;
10336                            j--;
10337                            launchingCount--;
10338                        }
10339                    }
10340                    if (wasInLaunchingProviders) {
10341                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10342                    }
10343                    synchronized (dst) {
10344                        dst.provider = src.provider;
10345                        dst.proc = r;
10346                        dst.notifyAll();
10347                    }
10348                    updateOomAdjLocked(r);
10349                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10350                            src.info.authority);
10351                }
10352            }
10353
10354            Binder.restoreCallingIdentity(origId);
10355        }
10356    }
10357
10358    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10359        ContentProviderConnection conn;
10360        try {
10361            conn = (ContentProviderConnection)connection;
10362        } catch (ClassCastException e) {
10363            String msg ="refContentProvider: " + connection
10364                    + " not a ContentProviderConnection";
10365            Slog.w(TAG, msg);
10366            throw new IllegalArgumentException(msg);
10367        }
10368        if (conn == null) {
10369            throw new NullPointerException("connection is null");
10370        }
10371
10372        synchronized (this) {
10373            if (stable > 0) {
10374                conn.numStableIncs += stable;
10375            }
10376            stable = conn.stableCount + stable;
10377            if (stable < 0) {
10378                throw new IllegalStateException("stableCount < 0: " + stable);
10379            }
10380
10381            if (unstable > 0) {
10382                conn.numUnstableIncs += unstable;
10383            }
10384            unstable = conn.unstableCount + unstable;
10385            if (unstable < 0) {
10386                throw new IllegalStateException("unstableCount < 0: " + unstable);
10387            }
10388
10389            if ((stable+unstable) <= 0) {
10390                throw new IllegalStateException("ref counts can't go to zero here: stable="
10391                        + stable + " unstable=" + unstable);
10392            }
10393            conn.stableCount = stable;
10394            conn.unstableCount = unstable;
10395            return !conn.dead;
10396        }
10397    }
10398
10399    public void unstableProviderDied(IBinder connection) {
10400        ContentProviderConnection conn;
10401        try {
10402            conn = (ContentProviderConnection)connection;
10403        } catch (ClassCastException e) {
10404            String msg ="refContentProvider: " + connection
10405                    + " not a ContentProviderConnection";
10406            Slog.w(TAG, msg);
10407            throw new IllegalArgumentException(msg);
10408        }
10409        if (conn == null) {
10410            throw new NullPointerException("connection is null");
10411        }
10412
10413        // Safely retrieve the content provider associated with the connection.
10414        IContentProvider provider;
10415        synchronized (this) {
10416            provider = conn.provider.provider;
10417        }
10418
10419        if (provider == null) {
10420            // Um, yeah, we're way ahead of you.
10421            return;
10422        }
10423
10424        // Make sure the caller is being honest with us.
10425        if (provider.asBinder().pingBinder()) {
10426            // Er, no, still looks good to us.
10427            synchronized (this) {
10428                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10429                        + " says " + conn + " died, but we don't agree");
10430                return;
10431            }
10432        }
10433
10434        // Well look at that!  It's dead!
10435        synchronized (this) {
10436            if (conn.provider.provider != provider) {
10437                // But something changed...  good enough.
10438                return;
10439            }
10440
10441            ProcessRecord proc = conn.provider.proc;
10442            if (proc == null || proc.thread == null) {
10443                // Seems like the process is already cleaned up.
10444                return;
10445            }
10446
10447            // As far as we're concerned, this is just like receiving a
10448            // death notification...  just a bit prematurely.
10449            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10450                    + ") early provider death");
10451            final long ident = Binder.clearCallingIdentity();
10452            try {
10453                appDiedLocked(proc);
10454            } finally {
10455                Binder.restoreCallingIdentity(ident);
10456            }
10457        }
10458    }
10459
10460    @Override
10461    public void appNotRespondingViaProvider(IBinder connection) {
10462        enforceCallingPermission(
10463                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10464
10465        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10466        if (conn == null) {
10467            Slog.w(TAG, "ContentProviderConnection is null");
10468            return;
10469        }
10470
10471        final ProcessRecord host = conn.provider.proc;
10472        if (host == null) {
10473            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10474            return;
10475        }
10476
10477        final long token = Binder.clearCallingIdentity();
10478        try {
10479            appNotResponding(host, null, null, false, "ContentProvider not responding");
10480        } finally {
10481            Binder.restoreCallingIdentity(token);
10482        }
10483    }
10484
10485    public final void installSystemProviders() {
10486        List<ProviderInfo> providers;
10487        synchronized (this) {
10488            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10489            providers = generateApplicationProvidersLocked(app);
10490            if (providers != null) {
10491                for (int i=providers.size()-1; i>=0; i--) {
10492                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10493                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10494                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10495                                + ": not system .apk");
10496                        providers.remove(i);
10497                    }
10498                }
10499            }
10500        }
10501        if (providers != null) {
10502            mSystemThread.installSystemProviders(providers);
10503        }
10504
10505        mCoreSettingsObserver = new CoreSettingsObserver(this);
10506
10507        //mUsageStatsService.monitorPackages();
10508    }
10509
10510    /**
10511     * Allows apps to retrieve the MIME type of a URI.
10512     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10513     * users, then it does not need permission to access the ContentProvider.
10514     * Either, it needs cross-user uri grants.
10515     *
10516     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10517     *
10518     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10519     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10520     */
10521    public String getProviderMimeType(Uri uri, int userId) {
10522        enforceNotIsolatedCaller("getProviderMimeType");
10523        final String name = uri.getAuthority();
10524        int callingUid = Binder.getCallingUid();
10525        int callingPid = Binder.getCallingPid();
10526        long ident = 0;
10527        boolean clearedIdentity = false;
10528        synchronized (this) {
10529            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
10530        }
10531        if (canClearIdentity(callingPid, callingUid, userId)) {
10532            clearedIdentity = true;
10533            ident = Binder.clearCallingIdentity();
10534        }
10535        ContentProviderHolder holder = null;
10536        try {
10537            holder = getContentProviderExternalUnchecked(name, null, userId);
10538            if (holder != null) {
10539                return holder.provider.getType(uri);
10540            }
10541        } catch (RemoteException e) {
10542            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10543            return null;
10544        } finally {
10545            // We need to clear the identity to call removeContentProviderExternalUnchecked
10546            if (!clearedIdentity) {
10547                ident = Binder.clearCallingIdentity();
10548            }
10549            try {
10550                if (holder != null) {
10551                    removeContentProviderExternalUnchecked(name, null, userId);
10552                }
10553            } finally {
10554                Binder.restoreCallingIdentity(ident);
10555            }
10556        }
10557
10558        return null;
10559    }
10560
10561    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10562        if (UserHandle.getUserId(callingUid) == userId) {
10563            return true;
10564        }
10565        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10566                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10567                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10568                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10569                return true;
10570        }
10571        return false;
10572    }
10573
10574    // =========================================================
10575    // GLOBAL MANAGEMENT
10576    // =========================================================
10577
10578    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10579            boolean isolated, int isolatedUid) {
10580        String proc = customProcess != null ? customProcess : info.processName;
10581        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10582        final int userId = UserHandle.getUserId(info.uid);
10583        int uid = info.uid;
10584        if (isolated) {
10585            if (isolatedUid == 0) {
10586                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10587                while (true) {
10588                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10589                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10590                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10591                    }
10592                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10593                    mNextIsolatedProcessUid++;
10594                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10595                        // No process for this uid, use it.
10596                        break;
10597                    }
10598                    stepsLeft--;
10599                    if (stepsLeft <= 0) {
10600                        return null;
10601                    }
10602                }
10603            } else {
10604                // Special case for startIsolatedProcess (internal only), where
10605                // the uid of the isolated process is specified by the caller.
10606                uid = isolatedUid;
10607            }
10608        }
10609        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10610        if (!mBooted && !mBooting
10611                && userId == UserHandle.USER_SYSTEM
10612                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10613            r.persistent = true;
10614        }
10615        addProcessNameLocked(r);
10616        return r;
10617    }
10618
10619    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10620            String abiOverride) {
10621        ProcessRecord app;
10622        if (!isolated) {
10623            app = getProcessRecordLocked(info.processName, info.uid, true);
10624        } else {
10625            app = null;
10626        }
10627
10628        if (app == null) {
10629            app = newProcessRecordLocked(info, null, isolated, 0);
10630            updateLruProcessLocked(app, false, null);
10631            updateOomAdjLocked();
10632        }
10633
10634        // This package really, really can not be stopped.
10635        try {
10636            AppGlobals.getPackageManager().setPackageStoppedState(
10637                    info.packageName, false, UserHandle.getUserId(app.uid));
10638        } catch (RemoteException e) {
10639        } catch (IllegalArgumentException e) {
10640            Slog.w(TAG, "Failed trying to unstop package "
10641                    + info.packageName + ": " + e);
10642        }
10643
10644        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10645            app.persistent = true;
10646            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10647        }
10648        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10649            mPersistentStartingProcesses.add(app);
10650            startProcessLocked(app, "added application", app.processName, abiOverride,
10651                    null /* entryPoint */, null /* entryPointArgs */);
10652        }
10653
10654        return app;
10655    }
10656
10657    public void unhandledBack() {
10658        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10659                "unhandledBack()");
10660
10661        synchronized(this) {
10662            final long origId = Binder.clearCallingIdentity();
10663            try {
10664                getFocusedStack().unhandledBackLocked();
10665            } finally {
10666                Binder.restoreCallingIdentity(origId);
10667            }
10668        }
10669    }
10670
10671    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10672        enforceNotIsolatedCaller("openContentUri");
10673        final int userId = UserHandle.getCallingUserId();
10674        String name = uri.getAuthority();
10675        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10676        ParcelFileDescriptor pfd = null;
10677        if (cph != null) {
10678            // We record the binder invoker's uid in thread-local storage before
10679            // going to the content provider to open the file.  Later, in the code
10680            // that handles all permissions checks, we look for this uid and use
10681            // that rather than the Activity Manager's own uid.  The effect is that
10682            // we do the check against the caller's permissions even though it looks
10683            // to the content provider like the Activity Manager itself is making
10684            // the request.
10685            Binder token = new Binder();
10686            sCallerIdentity.set(new Identity(
10687                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10688            try {
10689                pfd = cph.provider.openFile(null, uri, "r", null, token);
10690            } catch (FileNotFoundException e) {
10691                // do nothing; pfd will be returned null
10692            } finally {
10693                // Ensure that whatever happens, we clean up the identity state
10694                sCallerIdentity.remove();
10695                // Ensure we're done with the provider.
10696                removeContentProviderExternalUnchecked(name, null, userId);
10697            }
10698        } else {
10699            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10700        }
10701        return pfd;
10702    }
10703
10704    // Actually is sleeping or shutting down or whatever else in the future
10705    // is an inactive state.
10706    public boolean isSleepingOrShuttingDown() {
10707        return isSleeping() || mShuttingDown;
10708    }
10709
10710    public boolean isSleeping() {
10711        return mSleeping;
10712    }
10713
10714    void onWakefulnessChanged(int wakefulness) {
10715        synchronized(this) {
10716            mWakefulness = wakefulness;
10717            updateSleepIfNeededLocked();
10718        }
10719    }
10720
10721    void finishRunningVoiceLocked() {
10722        if (mRunningVoice != null) {
10723            mRunningVoice = null;
10724            mVoiceWakeLock.release();
10725            updateSleepIfNeededLocked();
10726        }
10727    }
10728
10729    void startTimeTrackingFocusedActivityLocked() {
10730        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10731            mCurAppTimeTracker.start(mFocusedActivity.packageName);
10732        }
10733    }
10734
10735    void updateSleepIfNeededLocked() {
10736        if (mSleeping && !shouldSleepLocked()) {
10737            mSleeping = false;
10738            startTimeTrackingFocusedActivityLocked();
10739            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10740            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10741            updateOomAdjLocked();
10742        } else if (!mSleeping && shouldSleepLocked()) {
10743            mSleeping = true;
10744            if (mCurAppTimeTracker != null) {
10745                mCurAppTimeTracker.stop();
10746            }
10747            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10748            mStackSupervisor.goingToSleepLocked();
10749            updateOomAdjLocked();
10750
10751            // Initialize the wake times of all processes.
10752            checkExcessivePowerUsageLocked(false);
10753            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10754            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10755            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10756        }
10757    }
10758
10759    private boolean shouldSleepLocked() {
10760        // Resume applications while running a voice interactor.
10761        if (mRunningVoice != null) {
10762            return false;
10763        }
10764
10765        // TODO: Transform the lock screen state into a sleep token instead.
10766        switch (mWakefulness) {
10767            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10768            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10769            case PowerManagerInternal.WAKEFULNESS_DOZING:
10770                // Pause applications whenever the lock screen is shown or any sleep
10771                // tokens have been acquired.
10772                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10773            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10774            default:
10775                // If we're asleep then pause applications unconditionally.
10776                return true;
10777        }
10778    }
10779
10780    /** Pokes the task persister. */
10781    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10782        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10783            // Never persist the home stack.
10784            return;
10785        }
10786        mTaskPersister.wakeup(task, flush);
10787    }
10788
10789    /** Notifies all listeners when the task stack has changed. */
10790    void notifyTaskStackChangedLocked() {
10791        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10792        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10793        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10794    }
10795
10796    @Override
10797    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10798        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10799    }
10800
10801    @Override
10802    public boolean shutdown(int timeout) {
10803        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10804                != PackageManager.PERMISSION_GRANTED) {
10805            throw new SecurityException("Requires permission "
10806                    + android.Manifest.permission.SHUTDOWN);
10807        }
10808
10809        boolean timedout = false;
10810
10811        synchronized(this) {
10812            mShuttingDown = true;
10813            updateEventDispatchingLocked();
10814            timedout = mStackSupervisor.shutdownLocked(timeout);
10815        }
10816
10817        mAppOpsService.shutdown();
10818        if (mUsageStatsService != null) {
10819            mUsageStatsService.prepareShutdown();
10820        }
10821        mBatteryStatsService.shutdown();
10822        synchronized (this) {
10823            mProcessStats.shutdownLocked();
10824            notifyTaskPersisterLocked(null, true);
10825        }
10826
10827        return timedout;
10828    }
10829
10830    public final void activitySlept(IBinder token) {
10831        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10832
10833        final long origId = Binder.clearCallingIdentity();
10834
10835        synchronized (this) {
10836            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10837            if (r != null) {
10838                mStackSupervisor.activitySleptLocked(r);
10839            }
10840        }
10841
10842        Binder.restoreCallingIdentity(origId);
10843    }
10844
10845    private String lockScreenShownToString() {
10846        switch (mLockScreenShown) {
10847            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10848            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10849            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10850            default: return "Unknown=" + mLockScreenShown;
10851        }
10852    }
10853
10854    void logLockScreen(String msg) {
10855        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10856                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10857                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10858                + " mSleeping=" + mSleeping);
10859    }
10860
10861    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10862        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10863        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10864            boolean wasRunningVoice = mRunningVoice != null;
10865            mRunningVoice = session;
10866            if (!wasRunningVoice) {
10867                mVoiceWakeLock.acquire();
10868                updateSleepIfNeededLocked();
10869            }
10870        }
10871    }
10872
10873    private void updateEventDispatchingLocked() {
10874        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10875    }
10876
10877    public void setLockScreenShown(boolean shown) {
10878        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10879                != PackageManager.PERMISSION_GRANTED) {
10880            throw new SecurityException("Requires permission "
10881                    + android.Manifest.permission.DEVICE_POWER);
10882        }
10883
10884        synchronized(this) {
10885            long ident = Binder.clearCallingIdentity();
10886            try {
10887                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10888                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10889                updateSleepIfNeededLocked();
10890            } finally {
10891                Binder.restoreCallingIdentity(ident);
10892            }
10893        }
10894    }
10895
10896    @Override
10897    public void stopAppSwitches() {
10898        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10899                != PackageManager.PERMISSION_GRANTED) {
10900            throw new SecurityException("Requires permission "
10901                    + android.Manifest.permission.STOP_APP_SWITCHES);
10902        }
10903
10904        synchronized(this) {
10905            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10906                    + APP_SWITCH_DELAY_TIME;
10907            mDidAppSwitch = false;
10908            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10909            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10910            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10911        }
10912    }
10913
10914    public void resumeAppSwitches() {
10915        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10916                != PackageManager.PERMISSION_GRANTED) {
10917            throw new SecurityException("Requires permission "
10918                    + android.Manifest.permission.STOP_APP_SWITCHES);
10919        }
10920
10921        synchronized(this) {
10922            // Note that we don't execute any pending app switches... we will
10923            // let those wait until either the timeout, or the next start
10924            // activity request.
10925            mAppSwitchesAllowedTime = 0;
10926        }
10927    }
10928
10929    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10930            int callingPid, int callingUid, String name) {
10931        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10932            return true;
10933        }
10934
10935        int perm = checkComponentPermission(
10936                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10937                sourceUid, -1, true);
10938        if (perm == PackageManager.PERMISSION_GRANTED) {
10939            return true;
10940        }
10941
10942        // If the actual IPC caller is different from the logical source, then
10943        // also see if they are allowed to control app switches.
10944        if (callingUid != -1 && callingUid != sourceUid) {
10945            perm = checkComponentPermission(
10946                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10947                    callingUid, -1, true);
10948            if (perm == PackageManager.PERMISSION_GRANTED) {
10949                return true;
10950            }
10951        }
10952
10953        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10954        return false;
10955    }
10956
10957    public void setDebugApp(String packageName, boolean waitForDebugger,
10958            boolean persistent) {
10959        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10960                "setDebugApp()");
10961
10962        long ident = Binder.clearCallingIdentity();
10963        try {
10964            // Note that this is not really thread safe if there are multiple
10965            // callers into it at the same time, but that's not a situation we
10966            // care about.
10967            if (persistent) {
10968                final ContentResolver resolver = mContext.getContentResolver();
10969                Settings.Global.putString(
10970                    resolver, Settings.Global.DEBUG_APP,
10971                    packageName);
10972                Settings.Global.putInt(
10973                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10974                    waitForDebugger ? 1 : 0);
10975            }
10976
10977            synchronized (this) {
10978                if (!persistent) {
10979                    mOrigDebugApp = mDebugApp;
10980                    mOrigWaitForDebugger = mWaitForDebugger;
10981                }
10982                mDebugApp = packageName;
10983                mWaitForDebugger = waitForDebugger;
10984                mDebugTransient = !persistent;
10985                if (packageName != null) {
10986                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10987                            false, UserHandle.USER_ALL, "set debug app");
10988                }
10989            }
10990        } finally {
10991            Binder.restoreCallingIdentity(ident);
10992        }
10993    }
10994
10995    void setTrackAllocationApp(ApplicationInfo app, String processName) {
10996        synchronized (this) {
10997            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10998            if (!isDebuggable) {
10999                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11000                    throw new SecurityException("Process not debuggable: " + app.packageName);
11001                }
11002            }
11003
11004            mTrackAllocationApp = processName;
11005        }
11006    }
11007
11008    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11009        synchronized (this) {
11010            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11011            if (!isDebuggable) {
11012                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11013                    throw new SecurityException("Process not debuggable: " + app.packageName);
11014                }
11015            }
11016            mProfileApp = processName;
11017            mProfileFile = profilerInfo.profileFile;
11018            if (mProfileFd != null) {
11019                try {
11020                    mProfileFd.close();
11021                } catch (IOException e) {
11022                }
11023                mProfileFd = null;
11024            }
11025            mProfileFd = profilerInfo.profileFd;
11026            mSamplingInterval = profilerInfo.samplingInterval;
11027            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11028            mProfileType = 0;
11029        }
11030    }
11031
11032    @Override
11033    public void setAlwaysFinish(boolean enabled) {
11034        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11035                "setAlwaysFinish()");
11036
11037        Settings.Global.putInt(
11038                mContext.getContentResolver(),
11039                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11040
11041        synchronized (this) {
11042            mAlwaysFinishActivities = enabled;
11043        }
11044    }
11045
11046    @Override
11047    public void setActivityController(IActivityController controller) {
11048        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11049                "setActivityController()");
11050        synchronized (this) {
11051            mController = controller;
11052            Watchdog.getInstance().setActivityController(controller);
11053        }
11054    }
11055
11056    @Override
11057    public void setUserIsMonkey(boolean userIsMonkey) {
11058        synchronized (this) {
11059            synchronized (mPidsSelfLocked) {
11060                final int callingPid = Binder.getCallingPid();
11061                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11062                if (precessRecord == null) {
11063                    throw new SecurityException("Unknown process: " + callingPid);
11064                }
11065                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11066                    throw new SecurityException("Only an instrumentation process "
11067                            + "with a UiAutomation can call setUserIsMonkey");
11068                }
11069            }
11070            mUserIsMonkey = userIsMonkey;
11071        }
11072    }
11073
11074    @Override
11075    public boolean isUserAMonkey() {
11076        synchronized (this) {
11077            // If there is a controller also implies the user is a monkey.
11078            return (mUserIsMonkey || mController != null);
11079        }
11080    }
11081
11082    public void requestBugReport() {
11083        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11084        SystemProperties.set("ctl.start", "bugreport");
11085    }
11086
11087    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11088        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11089    }
11090
11091    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11092        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11093            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11094        }
11095        return KEY_DISPATCHING_TIMEOUT;
11096    }
11097
11098    @Override
11099    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11100        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11101                != PackageManager.PERMISSION_GRANTED) {
11102            throw new SecurityException("Requires permission "
11103                    + android.Manifest.permission.FILTER_EVENTS);
11104        }
11105        ProcessRecord proc;
11106        long timeout;
11107        synchronized (this) {
11108            synchronized (mPidsSelfLocked) {
11109                proc = mPidsSelfLocked.get(pid);
11110            }
11111            timeout = getInputDispatchingTimeoutLocked(proc);
11112        }
11113
11114        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11115            return -1;
11116        }
11117
11118        return timeout;
11119    }
11120
11121    /**
11122     * Handle input dispatching timeouts.
11123     * Returns whether input dispatching should be aborted or not.
11124     */
11125    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11126            final ActivityRecord activity, final ActivityRecord parent,
11127            final boolean aboveSystem, String reason) {
11128        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11129                != PackageManager.PERMISSION_GRANTED) {
11130            throw new SecurityException("Requires permission "
11131                    + android.Manifest.permission.FILTER_EVENTS);
11132        }
11133
11134        final String annotation;
11135        if (reason == null) {
11136            annotation = "Input dispatching timed out";
11137        } else {
11138            annotation = "Input dispatching timed out (" + reason + ")";
11139        }
11140
11141        if (proc != null) {
11142            synchronized (this) {
11143                if (proc.debugging) {
11144                    return false;
11145                }
11146
11147                if (mDidDexOpt) {
11148                    // Give more time since we were dexopting.
11149                    mDidDexOpt = false;
11150                    return false;
11151                }
11152
11153                if (proc.instrumentationClass != null) {
11154                    Bundle info = new Bundle();
11155                    info.putString("shortMsg", "keyDispatchingTimedOut");
11156                    info.putString("longMsg", annotation);
11157                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11158                    return true;
11159                }
11160            }
11161            mHandler.post(new Runnable() {
11162                @Override
11163                public void run() {
11164                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
11165                }
11166            });
11167        }
11168
11169        return true;
11170    }
11171
11172    @Override
11173    public Bundle getAssistContextExtras(int requestType) {
11174        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11175                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11176        if (pae == null) {
11177            return null;
11178        }
11179        synchronized (pae) {
11180            while (!pae.haveResult) {
11181                try {
11182                    pae.wait();
11183                } catch (InterruptedException e) {
11184                }
11185            }
11186        }
11187        synchronized (this) {
11188            buildAssistBundleLocked(pae, pae.result);
11189            mPendingAssistExtras.remove(pae);
11190            mUiHandler.removeCallbacks(pae);
11191        }
11192        return pae.extras;
11193    }
11194
11195    @Override
11196    public boolean isAssistDataAllowedOnCurrentActivity() {
11197        int userId;
11198        synchronized (this) {
11199            userId = mUserController.getCurrentUserIdLocked();
11200            ActivityRecord activity = getFocusedStack().topActivity();
11201            if (activity == null) {
11202                return false;
11203            }
11204            userId = activity.userId;
11205        }
11206        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11207                Context.DEVICE_POLICY_SERVICE);
11208        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11209    }
11210
11211    @Override
11212    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11213        long ident = Binder.clearCallingIdentity();
11214        try {
11215            synchronized (this) {
11216                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11217                ActivityRecord top = getFocusedStack().topActivity();
11218                if (top != caller) {
11219                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11220                            + " is not current top " + top);
11221                    return false;
11222                }
11223                if (!top.nowVisible) {
11224                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11225                            + " is not visible");
11226                    return false;
11227                }
11228            }
11229            AssistUtils utils = new AssistUtils(mContext);
11230            return utils.showSessionForActiveService(args,
11231                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11232        } finally {
11233            Binder.restoreCallingIdentity(ident);
11234        }
11235    }
11236
11237    @Override
11238    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11239            IBinder activityToken) {
11240        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11241                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11242    }
11243
11244    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11245            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11246            long timeout) {
11247        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11248                "enqueueAssistContext()");
11249        synchronized (this) {
11250            ActivityRecord activity = getFocusedStack().topActivity();
11251            if (activity == null) {
11252                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11253                return null;
11254            }
11255            if (activity.app == null || activity.app.thread == null) {
11256                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11257                return null;
11258            }
11259            if (activityToken != null) {
11260                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11261                if (activity != caller) {
11262                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11263                            + " is not current top " + activity);
11264                    return null;
11265                }
11266            }
11267            PendingAssistExtras pae;
11268            Bundle extras = new Bundle();
11269            if (args != null) {
11270                extras.putAll(args);
11271            }
11272            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11273            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11274            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11275            try {
11276                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11277                        requestType);
11278                mPendingAssistExtras.add(pae);
11279                mUiHandler.postDelayed(pae, timeout);
11280            } catch (RemoteException e) {
11281                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11282                return null;
11283            }
11284            return pae;
11285        }
11286    }
11287
11288    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11289        IResultReceiver receiver;
11290        synchronized (this) {
11291            mPendingAssistExtras.remove(pae);
11292            receiver = pae.receiver;
11293        }
11294        if (receiver != null) {
11295            // Caller wants result sent back to them.
11296            try {
11297                pae.receiver.send(0, null);
11298            } catch (RemoteException e) {
11299            }
11300        }
11301    }
11302
11303    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11304        if (result != null) {
11305            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11306        }
11307        if (pae.hint != null) {
11308            pae.extras.putBoolean(pae.hint, true);
11309        }
11310    }
11311
11312    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11313            AssistContent content, Uri referrer) {
11314        PendingAssistExtras pae = (PendingAssistExtras)token;
11315        synchronized (pae) {
11316            pae.result = extras;
11317            pae.structure = structure;
11318            pae.content = content;
11319            if (referrer != null) {
11320                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11321            }
11322            pae.haveResult = true;
11323            pae.notifyAll();
11324            if (pae.intent == null && pae.receiver == null) {
11325                // Caller is just waiting for the result.
11326                return;
11327            }
11328        }
11329
11330        // We are now ready to launch the assist activity.
11331        IResultReceiver sendReceiver = null;
11332        Bundle sendBundle = null;
11333        synchronized (this) {
11334            buildAssistBundleLocked(pae, extras);
11335            boolean exists = mPendingAssistExtras.remove(pae);
11336            mUiHandler.removeCallbacks(pae);
11337            if (!exists) {
11338                // Timed out.
11339                return;
11340            }
11341            if ((sendReceiver=pae.receiver) != null) {
11342                // Caller wants result sent back to them.
11343                sendBundle = new Bundle();
11344                sendBundle.putBundle("data", pae.extras);
11345                sendBundle.putParcelable("structure", pae.structure);
11346                sendBundle.putParcelable("content", pae.content);
11347            }
11348        }
11349        if (sendReceiver != null) {
11350            try {
11351                sendReceiver.send(0, sendBundle);
11352            } catch (RemoteException e) {
11353            }
11354            return;
11355        }
11356
11357        long ident = Binder.clearCallingIdentity();
11358        try {
11359            pae.intent.replaceExtras(pae.extras);
11360            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11361                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
11362                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11363            closeSystemDialogs("assist");
11364            try {
11365                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11366            } catch (ActivityNotFoundException e) {
11367                Slog.w(TAG, "No activity to handle assist action.", e);
11368            }
11369        } finally {
11370            Binder.restoreCallingIdentity(ident);
11371        }
11372    }
11373
11374    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
11375            Bundle args) {
11376        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
11377                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
11378    }
11379
11380    public void registerProcessObserver(IProcessObserver observer) {
11381        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11382                "registerProcessObserver()");
11383        synchronized (this) {
11384            mProcessObservers.register(observer);
11385        }
11386    }
11387
11388    @Override
11389    public void unregisterProcessObserver(IProcessObserver observer) {
11390        synchronized (this) {
11391            mProcessObservers.unregister(observer);
11392        }
11393    }
11394
11395    @Override
11396    public void registerUidObserver(IUidObserver observer, int which) {
11397        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11398                "registerUidObserver()");
11399        synchronized (this) {
11400            mUidObservers.register(observer, which);
11401        }
11402    }
11403
11404    @Override
11405    public void unregisterUidObserver(IUidObserver observer) {
11406        synchronized (this) {
11407            mUidObservers.unregister(observer);
11408        }
11409    }
11410
11411    @Override
11412    public boolean convertFromTranslucent(IBinder token) {
11413        final long origId = Binder.clearCallingIdentity();
11414        try {
11415            synchronized (this) {
11416                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11417                if (r == null) {
11418                    return false;
11419                }
11420                final boolean translucentChanged = r.changeWindowTranslucency(true);
11421                if (translucentChanged) {
11422                    r.task.stack.releaseBackgroundResources(r);
11423                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11424                }
11425                mWindowManager.setAppFullscreen(token, true);
11426                return translucentChanged;
11427            }
11428        } finally {
11429            Binder.restoreCallingIdentity(origId);
11430        }
11431    }
11432
11433    @Override
11434    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11435        final long origId = Binder.clearCallingIdentity();
11436        try {
11437            synchronized (this) {
11438                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11439                if (r == null) {
11440                    return false;
11441                }
11442                int index = r.task.mActivities.lastIndexOf(r);
11443                if (index > 0) {
11444                    ActivityRecord under = r.task.mActivities.get(index - 1);
11445                    under.returningOptions = options;
11446                }
11447                final boolean translucentChanged = r.changeWindowTranslucency(false);
11448                if (translucentChanged) {
11449                    r.task.stack.convertActivityToTranslucent(r);
11450                }
11451                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11452                mWindowManager.setAppFullscreen(token, false);
11453                return translucentChanged;
11454            }
11455        } finally {
11456            Binder.restoreCallingIdentity(origId);
11457        }
11458    }
11459
11460    @Override
11461    public boolean requestVisibleBehind(IBinder token, boolean visible) {
11462        final long origId = Binder.clearCallingIdentity();
11463        try {
11464            synchronized (this) {
11465                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11466                if (r != null) {
11467                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11468                }
11469            }
11470            return false;
11471        } finally {
11472            Binder.restoreCallingIdentity(origId);
11473        }
11474    }
11475
11476    @Override
11477    public boolean isBackgroundVisibleBehind(IBinder token) {
11478        final long origId = Binder.clearCallingIdentity();
11479        try {
11480            synchronized (this) {
11481                final ActivityStack stack = ActivityRecord.getStackLocked(token);
11482                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11483                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11484                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11485                return visible;
11486            }
11487        } finally {
11488            Binder.restoreCallingIdentity(origId);
11489        }
11490    }
11491
11492    @Override
11493    public ActivityOptions getActivityOptions(IBinder token) {
11494        final long origId = Binder.clearCallingIdentity();
11495        try {
11496            synchronized (this) {
11497                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11498                if (r != null) {
11499                    final ActivityOptions activityOptions = r.pendingOptions;
11500                    r.pendingOptions = null;
11501                    return activityOptions;
11502                }
11503                return null;
11504            }
11505        } finally {
11506            Binder.restoreCallingIdentity(origId);
11507        }
11508    }
11509
11510    @Override
11511    public void setImmersive(IBinder token, boolean immersive) {
11512        synchronized(this) {
11513            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11514            if (r == null) {
11515                throw new IllegalArgumentException();
11516            }
11517            r.immersive = immersive;
11518
11519            // update associated state if we're frontmost
11520            if (r == mFocusedActivity) {
11521                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11522                applyUpdateLockStateLocked(r);
11523            }
11524        }
11525    }
11526
11527    @Override
11528    public boolean isImmersive(IBinder token) {
11529        synchronized (this) {
11530            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11531            if (r == null) {
11532                throw new IllegalArgumentException();
11533            }
11534            return r.immersive;
11535        }
11536    }
11537
11538    public boolean isTopActivityImmersive() {
11539        enforceNotIsolatedCaller("startActivity");
11540        synchronized (this) {
11541            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
11542            return (r != null) ? r.immersive : false;
11543        }
11544    }
11545
11546    @Override
11547    public boolean isTopOfTask(IBinder token) {
11548        synchronized (this) {
11549            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11550            if (r == null) {
11551                throw new IllegalArgumentException();
11552            }
11553            return r.task.getTopActivity() == r;
11554        }
11555    }
11556
11557    public final void enterSafeMode() {
11558        synchronized(this) {
11559            // It only makes sense to do this before the system is ready
11560            // and started launching other packages.
11561            if (!mSystemReady) {
11562                try {
11563                    AppGlobals.getPackageManager().enterSafeMode();
11564                } catch (RemoteException e) {
11565                }
11566            }
11567
11568            mSafeMode = true;
11569        }
11570    }
11571
11572    public final void showSafeModeOverlay() {
11573        View v = LayoutInflater.from(mContext).inflate(
11574                com.android.internal.R.layout.safe_mode, null);
11575        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11576        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11577        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11578        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11579        lp.gravity = Gravity.BOTTOM | Gravity.START;
11580        lp.format = v.getBackground().getOpacity();
11581        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11582                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11583        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11584        ((WindowManager)mContext.getSystemService(
11585                Context.WINDOW_SERVICE)).addView(v, lp);
11586    }
11587
11588    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11589        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11590            return;
11591        }
11592        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11593        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11594        synchronized (stats) {
11595            if (mBatteryStatsService.isOnBattery()) {
11596                mBatteryStatsService.enforceCallingPermission();
11597                int MY_UID = Binder.getCallingUid();
11598                final int uid;
11599                if (sender == null) {
11600                    uid = sourceUid;
11601                } else {
11602                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11603                }
11604                BatteryStatsImpl.Uid.Pkg pkg =
11605                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11606                            sourcePkg != null ? sourcePkg : rec.key.packageName);
11607                pkg.noteWakeupAlarmLocked(tag);
11608            }
11609        }
11610    }
11611
11612    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11613        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11614            return;
11615        }
11616        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11617        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11618        synchronized (stats) {
11619            mBatteryStatsService.enforceCallingPermission();
11620            int MY_UID = Binder.getCallingUid();
11621            final int uid;
11622            if (sender == null) {
11623                uid = sourceUid;
11624            } else {
11625                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11626            }
11627            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11628        }
11629    }
11630
11631    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11632        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11633            return;
11634        }
11635        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11636        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11637        synchronized (stats) {
11638            mBatteryStatsService.enforceCallingPermission();
11639            int MY_UID = Binder.getCallingUid();
11640            final int uid;
11641            if (sender == null) {
11642                uid = sourceUid;
11643            } else {
11644                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11645            }
11646            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11647        }
11648    }
11649
11650    public boolean killPids(int[] pids, String pReason, boolean secure) {
11651        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11652            throw new SecurityException("killPids only available to the system");
11653        }
11654        String reason = (pReason == null) ? "Unknown" : pReason;
11655        // XXX Note: don't acquire main activity lock here, because the window
11656        // manager calls in with its locks held.
11657
11658        boolean killed = false;
11659        synchronized (mPidsSelfLocked) {
11660            int[] types = new int[pids.length];
11661            int worstType = 0;
11662            for (int i=0; i<pids.length; i++) {
11663                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11664                if (proc != null) {
11665                    int type = proc.setAdj;
11666                    types[i] = type;
11667                    if (type > worstType) {
11668                        worstType = type;
11669                    }
11670                }
11671            }
11672
11673            // If the worst oom_adj is somewhere in the cached proc LRU range,
11674            // then constrain it so we will kill all cached procs.
11675            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11676                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11677                worstType = ProcessList.CACHED_APP_MIN_ADJ;
11678            }
11679
11680            // If this is not a secure call, don't let it kill processes that
11681            // are important.
11682            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11683                worstType = ProcessList.SERVICE_ADJ;
11684            }
11685
11686            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11687            for (int i=0; i<pids.length; i++) {
11688                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11689                if (proc == null) {
11690                    continue;
11691                }
11692                int adj = proc.setAdj;
11693                if (adj >= worstType && !proc.killedByAm) {
11694                    proc.kill(reason, true);
11695                    killed = true;
11696                }
11697            }
11698        }
11699        return killed;
11700    }
11701
11702    @Override
11703    public void killUid(int appId, int userId, String reason) {
11704        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11705        synchronized (this) {
11706            final long identity = Binder.clearCallingIdentity();
11707            try {
11708                killPackageProcessesLocked(null, appId, userId,
11709                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11710                        reason != null ? reason : "kill uid");
11711            } finally {
11712                Binder.restoreCallingIdentity(identity);
11713            }
11714        }
11715    }
11716
11717    @Override
11718    public boolean killProcessesBelowForeground(String reason) {
11719        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11720            throw new SecurityException("killProcessesBelowForeground() only available to system");
11721        }
11722
11723        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11724    }
11725
11726    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11727        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11728            throw new SecurityException("killProcessesBelowAdj() only available to system");
11729        }
11730
11731        boolean killed = false;
11732        synchronized (mPidsSelfLocked) {
11733            final int size = mPidsSelfLocked.size();
11734            for (int i = 0; i < size; i++) {
11735                final int pid = mPidsSelfLocked.keyAt(i);
11736                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11737                if (proc == null) continue;
11738
11739                final int adj = proc.setAdj;
11740                if (adj > belowAdj && !proc.killedByAm) {
11741                    proc.kill(reason, true);
11742                    killed = true;
11743                }
11744            }
11745        }
11746        return killed;
11747    }
11748
11749    @Override
11750    public void hang(final IBinder who, boolean allowRestart) {
11751        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11752                != PackageManager.PERMISSION_GRANTED) {
11753            throw new SecurityException("Requires permission "
11754                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11755        }
11756
11757        final IBinder.DeathRecipient death = new DeathRecipient() {
11758            @Override
11759            public void binderDied() {
11760                synchronized (this) {
11761                    notifyAll();
11762                }
11763            }
11764        };
11765
11766        try {
11767            who.linkToDeath(death, 0);
11768        } catch (RemoteException e) {
11769            Slog.w(TAG, "hang: given caller IBinder is already dead.");
11770            return;
11771        }
11772
11773        synchronized (this) {
11774            Watchdog.getInstance().setAllowRestart(allowRestart);
11775            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11776            synchronized (death) {
11777                while (who.isBinderAlive()) {
11778                    try {
11779                        death.wait();
11780                    } catch (InterruptedException e) {
11781                    }
11782                }
11783            }
11784            Watchdog.getInstance().setAllowRestart(true);
11785        }
11786    }
11787
11788    @Override
11789    public void restart() {
11790        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11791                != PackageManager.PERMISSION_GRANTED) {
11792            throw new SecurityException("Requires permission "
11793                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11794        }
11795
11796        Log.i(TAG, "Sending shutdown broadcast...");
11797
11798        BroadcastReceiver br = new BroadcastReceiver() {
11799            @Override public void onReceive(Context context, Intent intent) {
11800                // Now the broadcast is done, finish up the low-level shutdown.
11801                Log.i(TAG, "Shutting down activity manager...");
11802                shutdown(10000);
11803                Log.i(TAG, "Shutdown complete, restarting!");
11804                Process.killProcess(Process.myPid());
11805                System.exit(10);
11806            }
11807        };
11808
11809        // First send the high-level shut down broadcast.
11810        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11811        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11812        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11813        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11814        mContext.sendOrderedBroadcastAsUser(intent,
11815                UserHandle.ALL, null, br, mHandler, 0, null, null);
11816        */
11817        br.onReceive(mContext, intent);
11818    }
11819
11820    private long getLowRamTimeSinceIdle(long now) {
11821        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11822    }
11823
11824    @Override
11825    public void performIdleMaintenance() {
11826        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11827                != PackageManager.PERMISSION_GRANTED) {
11828            throw new SecurityException("Requires permission "
11829                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11830        }
11831
11832        synchronized (this) {
11833            final long now = SystemClock.uptimeMillis();
11834            final long timeSinceLastIdle = now - mLastIdleTime;
11835            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11836            mLastIdleTime = now;
11837            mLowRamTimeSinceLastIdle = 0;
11838            if (mLowRamStartTime != 0) {
11839                mLowRamStartTime = now;
11840            }
11841
11842            StringBuilder sb = new StringBuilder(128);
11843            sb.append("Idle maintenance over ");
11844            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11845            sb.append(" low RAM for ");
11846            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11847            Slog.i(TAG, sb.toString());
11848
11849            // If at least 1/3 of our time since the last idle period has been spent
11850            // with RAM low, then we want to kill processes.
11851            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11852
11853            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11854                ProcessRecord proc = mLruProcesses.get(i);
11855                if (proc.notCachedSinceIdle) {
11856                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11857                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11858                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11859                        if (doKilling && proc.initialIdlePss != 0
11860                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11861                            sb = new StringBuilder(128);
11862                            sb.append("Kill");
11863                            sb.append(proc.processName);
11864                            sb.append(" in idle maint: pss=");
11865                            sb.append(proc.lastPss);
11866                            sb.append(", initialPss=");
11867                            sb.append(proc.initialIdlePss);
11868                            sb.append(", period=");
11869                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11870                            sb.append(", lowRamPeriod=");
11871                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11872                            Slog.wtfQuiet(TAG, sb.toString());
11873                            proc.kill("idle maint (pss " + proc.lastPss
11874                                    + " from " + proc.initialIdlePss + ")", true);
11875                        }
11876                    }
11877                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11878                    proc.notCachedSinceIdle = true;
11879                    proc.initialIdlePss = 0;
11880                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11881                            mTestPssMode, isSleeping(), now);
11882                }
11883            }
11884
11885            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11886            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11887        }
11888    }
11889
11890    private void retrieveSettings() {
11891        final ContentResolver resolver = mContext.getContentResolver();
11892        final boolean freeformWindowManagement =
11893                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT);
11894
11895        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
11896        final String fsScreenshots = Settings.Secure.getString(resolver,
11897                "overview_fullscreen_thumbnails");
11898        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
11899        final boolean alwaysFinishActivities =
11900                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11901        final boolean takeFullscreenScreenshots = fsScreenshots != null &&
11902                Integer.parseInt(fsScreenshots) != 0;
11903        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
11904        final int defaultForceResizable = Build.IS_DEBUGGABLE ? 1 : 0;
11905        final boolean forceResizable = Settings.Global.getInt(
11906                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, defaultForceResizable) != 0;
11907        // Transfer any global setting for forcing RTL layout, into a System Property
11908        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11909
11910        final Configuration configuration = new Configuration();
11911        Settings.System.getConfiguration(resolver, configuration);
11912        if (forceRtl) {
11913            // This will take care of setting the correct layout direction flags
11914            configuration.setLayoutDirection(configuration.locale);
11915        }
11916
11917        synchronized (this) {
11918            mDebugApp = mOrigDebugApp = debugApp;
11919            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11920            mAlwaysFinishActivities = alwaysFinishActivities;
11921            mForceResizableActivities = forceResizable;
11922            mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
11923            mTakeFullscreenScreenshots = takeFullscreenScreenshots;
11924            // This happens before any activities are started, so we can
11925            // change mConfiguration in-place.
11926            updateConfigurationLocked(configuration, null, true);
11927            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11928                    "Initial config: " + mConfiguration);
11929        }
11930    }
11931
11932    /** Loads resources after the current configuration has been set. */
11933    private void loadResourcesOnSystemReady() {
11934        final Resources res = mContext.getResources();
11935        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11936        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11937        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11938    }
11939
11940    public boolean testIsSystemReady() {
11941        // no need to synchronize(this) just to read & return the value
11942        return mSystemReady;
11943    }
11944
11945    private static File getCalledPreBootReceiversFile() {
11946        File dataDir = Environment.getDataDirectory();
11947        File systemDir = new File(dataDir, "system");
11948        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11949        return fname;
11950    }
11951
11952    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11953        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11954        File file = getCalledPreBootReceiversFile();
11955        FileInputStream fis = null;
11956        try {
11957            fis = new FileInputStream(file);
11958            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11959            int fvers = dis.readInt();
11960            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11961                String vers = dis.readUTF();
11962                String codename = dis.readUTF();
11963                String build = dis.readUTF();
11964                if (android.os.Build.VERSION.RELEASE.equals(vers)
11965                        && android.os.Build.VERSION.CODENAME.equals(codename)
11966                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11967                    int num = dis.readInt();
11968                    while (num > 0) {
11969                        num--;
11970                        String pkg = dis.readUTF();
11971                        String cls = dis.readUTF();
11972                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11973                    }
11974                }
11975            }
11976        } catch (FileNotFoundException e) {
11977        } catch (IOException e) {
11978            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11979        } finally {
11980            if (fis != null) {
11981                try {
11982                    fis.close();
11983                } catch (IOException e) {
11984                }
11985            }
11986        }
11987        return lastDoneReceivers;
11988    }
11989
11990    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11991        File file = getCalledPreBootReceiversFile();
11992        FileOutputStream fos = null;
11993        DataOutputStream dos = null;
11994        try {
11995            fos = new FileOutputStream(file);
11996            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11997            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11998            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11999            dos.writeUTF(android.os.Build.VERSION.CODENAME);
12000            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
12001            dos.writeInt(list.size());
12002            for (int i=0; i<list.size(); i++) {
12003                dos.writeUTF(list.get(i).getPackageName());
12004                dos.writeUTF(list.get(i).getClassName());
12005            }
12006        } catch (IOException e) {
12007            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
12008            file.delete();
12009        } finally {
12010            FileUtils.sync(fos);
12011            if (dos != null) {
12012                try {
12013                    dos.close();
12014                } catch (IOException e) {
12015                    // TODO Auto-generated catch block
12016                    e.printStackTrace();
12017                }
12018            }
12019        }
12020    }
12021
12022    final class PreBootContinuation extends IIntentReceiver.Stub {
12023        final Intent intent;
12024        final Runnable onFinishCallback;
12025        final ArrayList<ComponentName> doneReceivers;
12026        final List<ResolveInfo> ris;
12027        final int[] users;
12028        int lastRi = -1;
12029        int curRi = 0;
12030        int curUser = 0;
12031
12032        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
12033                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
12034            intent = _intent;
12035            onFinishCallback = _onFinishCallback;
12036            doneReceivers = _doneReceivers;
12037            ris = _ris;
12038            users = _users;
12039        }
12040
12041        void go() {
12042            if (lastRi != curRi) {
12043                ActivityInfo ai = ris.get(curRi).activityInfo;
12044                ComponentName comp = new ComponentName(ai.packageName, ai.name);
12045                intent.setComponent(comp);
12046                doneReceivers.add(comp);
12047                lastRi = curRi;
12048                CharSequence label = ai.loadLabel(mContext.getPackageManager());
12049                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
12050            }
12051            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
12052                    + " for user " + users[curUser]);
12053            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
12054            broadcastIntentLocked(null, null, intent, null, this,
12055                    0, null, null, null, AppOpsManager.OP_NONE,
12056                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
12057        }
12058
12059        public void performReceive(Intent intent, int resultCode,
12060                String data, Bundle extras, boolean ordered,
12061                boolean sticky, int sendingUser) {
12062            curUser++;
12063            if (curUser >= users.length) {
12064                curUser = 0;
12065                curRi++;
12066                if (curRi >= ris.size()) {
12067                    // All done sending broadcasts!
12068                    if (onFinishCallback != null) {
12069                        // The raw IIntentReceiver interface is called
12070                        // with the AM lock held, so redispatch to
12071                        // execute our code without the lock.
12072                        mHandler.post(onFinishCallback);
12073                    }
12074                    return;
12075                }
12076            }
12077            go();
12078        }
12079    }
12080
12081    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
12082            ArrayList<ComponentName> doneReceivers) {
12083        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
12084        List<ResolveInfo> ris = null;
12085        try {
12086            ris = AppGlobals.getPackageManager().queryIntentReceivers(
12087                    intent, null, 0, UserHandle.USER_SYSTEM);
12088        } catch (RemoteException e) {
12089        }
12090        if (ris == null) {
12091            return false;
12092        }
12093        for (int i=ris.size()-1; i>=0; i--) {
12094            if ((ris.get(i).activityInfo.applicationInfo.flags
12095                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
12096                ris.remove(i);
12097            }
12098        }
12099        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
12100
12101        ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
12102        for (int i=0; i<ris.size(); i++) {
12103            ActivityInfo ai = ris.get(i).activityInfo;
12104            ComponentName comp = new ComponentName(ai.packageName, ai.name);
12105            if (lastDoneReceivers.contains(comp)) {
12106                // We already did the pre boot receiver for this app with the current
12107                // platform version, so don't do it again...
12108                ris.remove(i);
12109                i--;
12110                // ...however, do keep it as one that has been done, so we don't
12111                // forget about it when rewriting the file of last done receivers.
12112                doneReceivers.add(comp);
12113            }
12114        }
12115
12116        if (ris.size() <= 0) {
12117            return false;
12118        }
12119
12120        // TODO: can we still do this with per user encryption?
12121        final int[] users = mUserController.getUsers();
12122        if (users.length <= 0) {
12123            return false;
12124        }
12125
12126        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
12127                ris, users);
12128        cont.go();
12129        return true;
12130    }
12131
12132    public void systemReady(final Runnable goingCallback) {
12133        synchronized(this) {
12134            if (mSystemReady) {
12135                // If we're done calling all the receivers, run the next "boot phase" passed in
12136                // by the SystemServer
12137                if (goingCallback != null) {
12138                    goingCallback.run();
12139                }
12140                return;
12141            }
12142
12143            mLocalDeviceIdleController
12144                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12145
12146            // Make sure we have the current profile info, since it is needed for
12147            // security checks.
12148            mUserController.updateCurrentProfileIdsLocked();
12149
12150            mRecentTasks.clear();
12151            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked(mUserController.getUserIds()));
12152            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
12153            mTaskPersister.startPersisting();
12154
12155            // Check to see if there are any update receivers to run.
12156            if (!mDidUpdate) {
12157                if (mWaitingUpdate) {
12158                    return;
12159                }
12160                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
12161                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
12162                    public void run() {
12163                        synchronized (ActivityManagerService.this) {
12164                            mDidUpdate = true;
12165                        }
12166                        showBootMessage(mContext.getText(
12167                                R.string.android_upgrading_complete),
12168                                false);
12169                        writeLastDonePreBootReceivers(doneReceivers);
12170                        systemReady(goingCallback);
12171                    }
12172                }, doneReceivers);
12173
12174                if (mWaitingUpdate) {
12175                    return;
12176                }
12177                mDidUpdate = true;
12178            }
12179
12180            mAppOpsService.systemReady();
12181            mSystemReady = true;
12182        }
12183
12184        ArrayList<ProcessRecord> procsToKill = null;
12185        synchronized(mPidsSelfLocked) {
12186            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12187                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12188                if (!isAllowedWhileBooting(proc.info)){
12189                    if (procsToKill == null) {
12190                        procsToKill = new ArrayList<ProcessRecord>();
12191                    }
12192                    procsToKill.add(proc);
12193                }
12194            }
12195        }
12196
12197        synchronized(this) {
12198            if (procsToKill != null) {
12199                for (int i=procsToKill.size()-1; i>=0; i--) {
12200                    ProcessRecord proc = procsToKill.get(i);
12201                    Slog.i(TAG, "Removing system update proc: " + proc);
12202                    removeProcessLocked(proc, true, false, "system update done");
12203                }
12204            }
12205
12206            // Now that we have cleaned up any update processes, we
12207            // are ready to start launching real processes and know that
12208            // we won't trample on them any more.
12209            mProcessesReady = true;
12210        }
12211
12212        Slog.i(TAG, "System now ready");
12213        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12214            SystemClock.uptimeMillis());
12215
12216        synchronized(this) {
12217            // Make sure we have no pre-ready processes sitting around.
12218
12219            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12220                ResolveInfo ri = mContext.getPackageManager()
12221                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12222                                STOCK_PM_FLAGS);
12223                CharSequence errorMsg = null;
12224                if (ri != null) {
12225                    ActivityInfo ai = ri.activityInfo;
12226                    ApplicationInfo app = ai.applicationInfo;
12227                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12228                        mTopAction = Intent.ACTION_FACTORY_TEST;
12229                        mTopData = null;
12230                        mTopComponent = new ComponentName(app.packageName,
12231                                ai.name);
12232                    } else {
12233                        errorMsg = mContext.getResources().getText(
12234                                com.android.internal.R.string.factorytest_not_system);
12235                    }
12236                } else {
12237                    errorMsg = mContext.getResources().getText(
12238                            com.android.internal.R.string.factorytest_no_action);
12239                }
12240                if (errorMsg != null) {
12241                    mTopAction = null;
12242                    mTopData = null;
12243                    mTopComponent = null;
12244                    Message msg = Message.obtain();
12245                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12246                    msg.getData().putCharSequence("msg", errorMsg);
12247                    mUiHandler.sendMessage(msg);
12248                }
12249            }
12250        }
12251
12252        retrieveSettings();
12253        loadResourcesOnSystemReady();
12254        final int currentUserId;
12255        synchronized (this) {
12256            currentUserId = mUserController.getCurrentUserIdLocked();
12257            readGrantedUriPermissionsLocked();
12258        }
12259
12260        if (goingCallback != null) goingCallback.run();
12261
12262
12263        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12264                Integer.toString(currentUserId), currentUserId);
12265        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12266                Integer.toString(currentUserId), currentUserId);
12267        mSystemServiceManager.startUser(currentUserId);
12268
12269        synchronized (this) {
12270            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12271                try {
12272                    List apps = AppGlobals.getPackageManager().
12273                        getPersistentApplications(STOCK_PM_FLAGS);
12274                    if (apps != null) {
12275                        int N = apps.size();
12276                        int i;
12277                        for (i=0; i<N; i++) {
12278                            ApplicationInfo info
12279                                = (ApplicationInfo)apps.get(i);
12280                            if (info != null &&
12281                                    !info.packageName.equals("android")) {
12282                                addAppLocked(info, false, null /* ABI override */);
12283                            }
12284                        }
12285                    }
12286                } catch (RemoteException ex) {
12287                    // pm is in same process, this will never happen.
12288                }
12289            }
12290
12291            // Start up initial activity.
12292            mBooting = true;
12293            // Enable home activity for system user, so that the system can always boot
12294            if (UserManager.isSplitSystemUser()) {
12295                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12296                try {
12297                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12298                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12299                            UserHandle.USER_SYSTEM);
12300                } catch (RemoteException e) {
12301                    e.rethrowAsRuntimeException();
12302                }
12303            }
12304            startHomeActivityLocked(currentUserId, "systemReady");
12305
12306            try {
12307                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12308                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12309                            + " data partition or your device will be unstable.");
12310                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12311                }
12312            } catch (RemoteException e) {
12313            }
12314
12315            if (!Build.isBuildConsistent()) {
12316                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12317                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12318            }
12319
12320            long ident = Binder.clearCallingIdentity();
12321            try {
12322                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12323                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12324                        | Intent.FLAG_RECEIVER_FOREGROUND);
12325                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12326                broadcastIntentLocked(null, null, intent,
12327                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12328                        null, false, false, MY_PID, Process.SYSTEM_UID,
12329                        currentUserId);
12330                intent = new Intent(Intent.ACTION_USER_STARTING);
12331                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12332                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12333                broadcastIntentLocked(null, null, intent,
12334                        null, new IIntentReceiver.Stub() {
12335                            @Override
12336                            public void performReceive(Intent intent, int resultCode, String data,
12337                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12338                                    throws RemoteException {
12339                            }
12340                        }, 0, null, null,
12341                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12342                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12343            } catch (Throwable t) {
12344                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12345            } finally {
12346                Binder.restoreCallingIdentity(ident);
12347            }
12348            mStackSupervisor.resumeTopActivitiesLocked();
12349            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12350        }
12351    }
12352
12353    private boolean makeAppCrashingLocked(ProcessRecord app,
12354            String shortMsg, String longMsg, String stackTrace) {
12355        app.crashing = true;
12356        app.crashingReport = generateProcessError(app,
12357                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
12358        startAppProblemLocked(app);
12359        app.stopFreezingAllLocked();
12360        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
12361    }
12362
12363    private void makeAppNotRespondingLocked(ProcessRecord app,
12364            String activity, String shortMsg, String longMsg) {
12365        app.notResponding = true;
12366        app.notRespondingReport = generateProcessError(app,
12367                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
12368                activity, shortMsg, longMsg, null);
12369        startAppProblemLocked(app);
12370        app.stopFreezingAllLocked();
12371    }
12372
12373    /**
12374     * Generate a process error record, suitable for attachment to a ProcessRecord.
12375     *
12376     * @param app The ProcessRecord in which the error occurred.
12377     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
12378     *                      ActivityManager.AppErrorStateInfo
12379     * @param activity The activity associated with the crash, if known.
12380     * @param shortMsg Short message describing the crash.
12381     * @param longMsg Long message describing the crash.
12382     * @param stackTrace Full crash stack trace, may be null.
12383     *
12384     * @return Returns a fully-formed AppErrorStateInfo record.
12385     */
12386    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
12387            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
12388        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
12389
12390        report.condition = condition;
12391        report.processName = app.processName;
12392        report.pid = app.pid;
12393        report.uid = app.info.uid;
12394        report.tag = activity;
12395        report.shortMsg = shortMsg;
12396        report.longMsg = longMsg;
12397        report.stackTrace = stackTrace;
12398
12399        return report;
12400    }
12401
12402    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12403        synchronized (this) {
12404            app.crashing = false;
12405            app.crashingReport = null;
12406            app.notResponding = false;
12407            app.notRespondingReport = null;
12408            if (app.anrDialog == fromDialog) {
12409                app.anrDialog = null;
12410            }
12411            if (app.waitDialog == fromDialog) {
12412                app.waitDialog = null;
12413            }
12414            if (app.pid > 0 && app.pid != MY_PID) {
12415                handleAppCrashLocked(app, "user-terminated" /*reason*/,
12416                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
12417                app.kill("user request after error", true);
12418            }
12419        }
12420    }
12421
12422    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
12423            String shortMsg, String longMsg, String stackTrace) {
12424        long now = SystemClock.uptimeMillis();
12425
12426        Long crashTime;
12427        if (!app.isolated) {
12428            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
12429        } else {
12430            crashTime = null;
12431        }
12432        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
12433            // This process loses!
12434            Slog.w(TAG, "Process " + app.info.processName
12435                    + " has crashed too many times: killing!");
12436            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
12437                    app.userId, app.info.processName, app.uid);
12438            mStackSupervisor.handleAppCrashLocked(app);
12439            if (!app.persistent) {
12440                // We don't want to start this process again until the user
12441                // explicitly does so...  but for persistent process, we really
12442                // need to keep it running.  If a persistent process is actually
12443                // repeatedly crashing, then badness for everyone.
12444                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
12445                        app.info.processName);
12446                if (!app.isolated) {
12447                    // XXX We don't have a way to mark isolated processes
12448                    // as bad, since they don't have a peristent identity.
12449                    mBadProcesses.put(app.info.processName, app.uid,
12450                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
12451                    mProcessCrashTimes.remove(app.info.processName, app.uid);
12452                }
12453                app.bad = true;
12454                app.removed = true;
12455                // Don't let services in this process be restarted and potentially
12456                // annoy the user repeatedly.  Unless it is persistent, since those
12457                // processes run critical code.
12458                removeProcessLocked(app, false, false, "crash");
12459                mStackSupervisor.resumeTopActivitiesLocked();
12460                return false;
12461            }
12462            mStackSupervisor.resumeTopActivitiesLocked();
12463        } else {
12464            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
12465        }
12466
12467        // Bump up the crash count of any services currently running in the proc.
12468        for (int i=app.services.size()-1; i>=0; i--) {
12469            // Any services running in the application need to be placed
12470            // back in the pending list.
12471            ServiceRecord sr = app.services.valueAt(i);
12472            sr.crashCount++;
12473        }
12474
12475        // If the crashing process is what we consider to be the "home process" and it has been
12476        // replaced by a third-party app, clear the package preferred activities from packages
12477        // with a home activity running in the process to prevent a repeatedly crashing app
12478        // from blocking the user to manually clear the list.
12479        final ArrayList<ActivityRecord> activities = app.activities;
12480        if (app == mHomeProcess && activities.size() > 0
12481                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
12482            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
12483                final ActivityRecord r = activities.get(activityNdx);
12484                if (r.isHomeActivity()) {
12485                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
12486                    try {
12487                        ActivityThread.getPackageManager()
12488                                .clearPackagePreferredActivities(r.packageName);
12489                    } catch (RemoteException c) {
12490                        // pm is in same process, this will never happen.
12491                    }
12492                }
12493            }
12494        }
12495
12496        if (!app.isolated) {
12497            // XXX Can't keep track of crash times for isolated processes,
12498            // because they don't have a perisistent identity.
12499            mProcessCrashTimes.put(app.info.processName, app.uid, now);
12500        }
12501
12502        if (app.crashHandler != null) mHandler.post(app.crashHandler);
12503        return true;
12504    }
12505
12506    void startAppProblemLocked(ProcessRecord app) {
12507        // If this app is not running under the current user, then we
12508        // can't give it a report button because that would require
12509        // launching the report UI under a different user.
12510        app.errorReportReceiver = null;
12511
12512        for (int userId : mUserController.getCurrentProfileIdsLocked()) {
12513            if (app.userId == userId) {
12514                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12515                        mContext, app.info.packageName, app.info.flags);
12516            }
12517        }
12518        skipCurrentReceiverLocked(app);
12519    }
12520
12521    void skipCurrentReceiverLocked(ProcessRecord app) {
12522        for (BroadcastQueue queue : mBroadcastQueues) {
12523            queue.skipCurrentReceiverLocked(app);
12524        }
12525    }
12526
12527    /**
12528     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12529     * The application process will exit immediately after this call returns.
12530     * @param app object of the crashing app, null for the system server
12531     * @param crashInfo describing the exception
12532     */
12533    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12534        ProcessRecord r = findAppProcess(app, "Crash");
12535        final String processName = app == null ? "system_server"
12536                : (r == null ? "unknown" : r.processName);
12537
12538        handleApplicationCrashInner("crash", r, processName, crashInfo);
12539    }
12540
12541    /* Native crash reporting uses this inner version because it needs to be somewhat
12542     * decoupled from the AM-managed cleanup lifecycle
12543     */
12544    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12545            ApplicationErrorReport.CrashInfo crashInfo) {
12546        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12547                UserHandle.getUserId(Binder.getCallingUid()), processName,
12548                r == null ? -1 : r.info.flags,
12549                crashInfo.exceptionClassName,
12550                crashInfo.exceptionMessage,
12551                crashInfo.throwFileName,
12552                crashInfo.throwLineNumber);
12553
12554        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12555
12556        crashApplication(r, crashInfo);
12557    }
12558
12559    public void handleApplicationStrictModeViolation(
12560            IBinder app,
12561            int violationMask,
12562            StrictMode.ViolationInfo info) {
12563        ProcessRecord r = findAppProcess(app, "StrictMode");
12564        if (r == null) {
12565            return;
12566        }
12567
12568        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12569            Integer stackFingerprint = info.hashCode();
12570            boolean logIt = true;
12571            synchronized (mAlreadyLoggedViolatedStacks) {
12572                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12573                    logIt = false;
12574                    // TODO: sub-sample into EventLog for these, with
12575                    // the info.durationMillis?  Then we'd get
12576                    // the relative pain numbers, without logging all
12577                    // the stack traces repeatedly.  We'd want to do
12578                    // likewise in the client code, which also does
12579                    // dup suppression, before the Binder call.
12580                } else {
12581                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12582                        mAlreadyLoggedViolatedStacks.clear();
12583                    }
12584                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12585                }
12586            }
12587            if (logIt) {
12588                logStrictModeViolationToDropBox(r, info);
12589            }
12590        }
12591
12592        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12593            AppErrorResult result = new AppErrorResult();
12594            synchronized (this) {
12595                final long origId = Binder.clearCallingIdentity();
12596
12597                Message msg = Message.obtain();
12598                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12599                HashMap<String, Object> data = new HashMap<String, Object>();
12600                data.put("result", result);
12601                data.put("app", r);
12602                data.put("violationMask", violationMask);
12603                data.put("info", info);
12604                msg.obj = data;
12605                mUiHandler.sendMessage(msg);
12606
12607                Binder.restoreCallingIdentity(origId);
12608            }
12609            int res = result.get();
12610            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12611        }
12612    }
12613
12614    // Depending on the policy in effect, there could be a bunch of
12615    // these in quick succession so we try to batch these together to
12616    // minimize disk writes, number of dropbox entries, and maximize
12617    // compression, by having more fewer, larger records.
12618    private void logStrictModeViolationToDropBox(
12619            ProcessRecord process,
12620            StrictMode.ViolationInfo info) {
12621        if (info == null) {
12622            return;
12623        }
12624        final boolean isSystemApp = process == null ||
12625                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12626                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12627        final String processName = process == null ? "unknown" : process.processName;
12628        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12629        final DropBoxManager dbox = (DropBoxManager)
12630                mContext.getSystemService(Context.DROPBOX_SERVICE);
12631
12632        // Exit early if the dropbox isn't configured to accept this report type.
12633        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12634
12635        boolean bufferWasEmpty;
12636        boolean needsFlush;
12637        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12638        synchronized (sb) {
12639            bufferWasEmpty = sb.length() == 0;
12640            appendDropBoxProcessHeaders(process, processName, sb);
12641            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12642            sb.append("System-App: ").append(isSystemApp).append("\n");
12643            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12644            if (info.violationNumThisLoop != 0) {
12645                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12646            }
12647            if (info.numAnimationsRunning != 0) {
12648                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12649            }
12650            if (info.broadcastIntentAction != null) {
12651                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12652            }
12653            if (info.durationMillis != -1) {
12654                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12655            }
12656            if (info.numInstances != -1) {
12657                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12658            }
12659            if (info.tags != null) {
12660                for (String tag : info.tags) {
12661                    sb.append("Span-Tag: ").append(tag).append("\n");
12662                }
12663            }
12664            sb.append("\n");
12665            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12666                sb.append(info.crashInfo.stackTrace);
12667                sb.append("\n");
12668            }
12669            if (info.message != null) {
12670                sb.append(info.message);
12671                sb.append("\n");
12672            }
12673
12674            // Only buffer up to ~64k.  Various logging bits truncate
12675            // things at 128k.
12676            needsFlush = (sb.length() > 64 * 1024);
12677        }
12678
12679        // Flush immediately if the buffer's grown too large, or this
12680        // is a non-system app.  Non-system apps are isolated with a
12681        // different tag & policy and not batched.
12682        //
12683        // Batching is useful during internal testing with
12684        // StrictMode settings turned up high.  Without batching,
12685        // thousands of separate files could be created on boot.
12686        if (!isSystemApp || needsFlush) {
12687            new Thread("Error dump: " + dropboxTag) {
12688                @Override
12689                public void run() {
12690                    String report;
12691                    synchronized (sb) {
12692                        report = sb.toString();
12693                        sb.delete(0, sb.length());
12694                        sb.trimToSize();
12695                    }
12696                    if (report.length() != 0) {
12697                        dbox.addText(dropboxTag, report);
12698                    }
12699                }
12700            }.start();
12701            return;
12702        }
12703
12704        // System app batching:
12705        if (!bufferWasEmpty) {
12706            // An existing dropbox-writing thread is outstanding, so
12707            // we don't need to start it up.  The existing thread will
12708            // catch the buffer appends we just did.
12709            return;
12710        }
12711
12712        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12713        // (After this point, we shouldn't access AMS internal data structures.)
12714        new Thread("Error dump: " + dropboxTag) {
12715            @Override
12716            public void run() {
12717                // 5 second sleep to let stacks arrive and be batched together
12718                try {
12719                    Thread.sleep(5000);  // 5 seconds
12720                } catch (InterruptedException e) {}
12721
12722                String errorReport;
12723                synchronized (mStrictModeBuffer) {
12724                    errorReport = mStrictModeBuffer.toString();
12725                    if (errorReport.length() == 0) {
12726                        return;
12727                    }
12728                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12729                    mStrictModeBuffer.trimToSize();
12730                }
12731                dbox.addText(dropboxTag, errorReport);
12732            }
12733        }.start();
12734    }
12735
12736    /**
12737     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12738     * @param app object of the crashing app, null for the system server
12739     * @param tag reported by the caller
12740     * @param system whether this wtf is coming from the system
12741     * @param crashInfo describing the context of the error
12742     * @return true if the process should exit immediately (WTF is fatal)
12743     */
12744    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12745            final ApplicationErrorReport.CrashInfo crashInfo) {
12746        final int callingUid = Binder.getCallingUid();
12747        final int callingPid = Binder.getCallingPid();
12748
12749        if (system) {
12750            // If this is coming from the system, we could very well have low-level
12751            // system locks held, so we want to do this all asynchronously.  And we
12752            // never want this to become fatal, so there is that too.
12753            mHandler.post(new Runnable() {
12754                @Override public void run() {
12755                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12756                }
12757            });
12758            return false;
12759        }
12760
12761        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12762                crashInfo);
12763
12764        if (r != null && r.pid != Process.myPid() &&
12765                Settings.Global.getInt(mContext.getContentResolver(),
12766                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
12767            crashApplication(r, crashInfo);
12768            return true;
12769        } else {
12770            return false;
12771        }
12772    }
12773
12774    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12775            final ApplicationErrorReport.CrashInfo crashInfo) {
12776        final ProcessRecord r = findAppProcess(app, "WTF");
12777        final String processName = app == null ? "system_server"
12778                : (r == null ? "unknown" : r.processName);
12779
12780        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12781                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12782
12783        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12784
12785        return r;
12786    }
12787
12788    /**
12789     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12790     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12791     */
12792    private ProcessRecord findAppProcess(IBinder app, String reason) {
12793        if (app == null) {
12794            return null;
12795        }
12796
12797        synchronized (this) {
12798            final int NP = mProcessNames.getMap().size();
12799            for (int ip=0; ip<NP; ip++) {
12800                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12801                final int NA = apps.size();
12802                for (int ia=0; ia<NA; ia++) {
12803                    ProcessRecord p = apps.valueAt(ia);
12804                    if (p.thread != null && p.thread.asBinder() == app) {
12805                        return p;
12806                    }
12807                }
12808            }
12809
12810            Slog.w(TAG, "Can't find mystery application for " + reason
12811                    + " from pid=" + Binder.getCallingPid()
12812                    + " uid=" + Binder.getCallingUid() + ": " + app);
12813            return null;
12814        }
12815    }
12816
12817    /**
12818     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12819     * to append various headers to the dropbox log text.
12820     */
12821    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12822            StringBuilder sb) {
12823        // Watchdog thread ends up invoking this function (with
12824        // a null ProcessRecord) to add the stack file to dropbox.
12825        // Do not acquire a lock on this (am) in such cases, as it
12826        // could cause a potential deadlock, if and when watchdog
12827        // is invoked due to unavailability of lock on am and it
12828        // would prevent watchdog from killing system_server.
12829        if (process == null) {
12830            sb.append("Process: ").append(processName).append("\n");
12831            return;
12832        }
12833        // Note: ProcessRecord 'process' is guarded by the service
12834        // instance.  (notably process.pkgList, which could otherwise change
12835        // concurrently during execution of this method)
12836        synchronized (this) {
12837            sb.append("Process: ").append(processName).append("\n");
12838            int flags = process.info.flags;
12839            IPackageManager pm = AppGlobals.getPackageManager();
12840            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12841            for (int ip=0; ip<process.pkgList.size(); ip++) {
12842                String pkg = process.pkgList.keyAt(ip);
12843                sb.append("Package: ").append(pkg);
12844                try {
12845                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12846                    if (pi != null) {
12847                        sb.append(" v").append(pi.versionCode);
12848                        if (pi.versionName != null) {
12849                            sb.append(" (").append(pi.versionName).append(")");
12850                        }
12851                    }
12852                } catch (RemoteException e) {
12853                    Slog.e(TAG, "Error getting package info: " + pkg, e);
12854                }
12855                sb.append("\n");
12856            }
12857        }
12858    }
12859
12860    private static String processClass(ProcessRecord process) {
12861        if (process == null || process.pid == MY_PID) {
12862            return "system_server";
12863        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12864            return "system_app";
12865        } else {
12866            return "data_app";
12867        }
12868    }
12869
12870    /**
12871     * Write a description of an error (crash, WTF, ANR) to the drop box.
12872     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12873     * @param process which caused the error, null means the system server
12874     * @param activity which triggered the error, null if unknown
12875     * @param parent activity related to the error, null if unknown
12876     * @param subject line related to the error, null if absent
12877     * @param report in long form describing the error, null if absent
12878     * @param logFile to include in the report, null if none
12879     * @param crashInfo giving an application stack trace, null if absent
12880     */
12881    public void addErrorToDropBox(String eventType,
12882            ProcessRecord process, String processName, ActivityRecord activity,
12883            ActivityRecord parent, String subject,
12884            final String report, final File logFile,
12885            final ApplicationErrorReport.CrashInfo crashInfo) {
12886        // NOTE -- this must never acquire the ActivityManagerService lock,
12887        // otherwise the watchdog may be prevented from resetting the system.
12888
12889        final String dropboxTag = processClass(process) + "_" + eventType;
12890        final DropBoxManager dbox = (DropBoxManager)
12891                mContext.getSystemService(Context.DROPBOX_SERVICE);
12892
12893        // Exit early if the dropbox isn't configured to accept this report type.
12894        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12895
12896        final StringBuilder sb = new StringBuilder(1024);
12897        appendDropBoxProcessHeaders(process, processName, sb);
12898        if (activity != null) {
12899            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12900        }
12901        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12902            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12903        }
12904        if (parent != null && parent != activity) {
12905            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12906        }
12907        if (subject != null) {
12908            sb.append("Subject: ").append(subject).append("\n");
12909        }
12910        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12911        if (Debug.isDebuggerConnected()) {
12912            sb.append("Debugger: Connected\n");
12913        }
12914        sb.append("\n");
12915
12916        // Do the rest in a worker thread to avoid blocking the caller on I/O
12917        // (After this point, we shouldn't access AMS internal data structures.)
12918        Thread worker = new Thread("Error dump: " + dropboxTag) {
12919            @Override
12920            public void run() {
12921                if (report != null) {
12922                    sb.append(report);
12923                }
12924                if (logFile != null) {
12925                    try {
12926                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12927                                    "\n\n[[TRUNCATED]]"));
12928                    } catch (IOException e) {
12929                        Slog.e(TAG, "Error reading " + logFile, e);
12930                    }
12931                }
12932                if (crashInfo != null && crashInfo.stackTrace != null) {
12933                    sb.append(crashInfo.stackTrace);
12934                }
12935
12936                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12937                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12938                if (lines > 0) {
12939                    sb.append("\n");
12940
12941                    // Merge several logcat streams, and take the last N lines
12942                    InputStreamReader input = null;
12943                    try {
12944                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12945                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12946                                "-b", "crash",
12947                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12948
12949                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12950                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12951                        input = new InputStreamReader(logcat.getInputStream());
12952
12953                        int num;
12954                        char[] buf = new char[8192];
12955                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12956                    } catch (IOException e) {
12957                        Slog.e(TAG, "Error running logcat", e);
12958                    } finally {
12959                        if (input != null) try { input.close(); } catch (IOException e) {}
12960                    }
12961                }
12962
12963                dbox.addText(dropboxTag, sb.toString());
12964            }
12965        };
12966
12967        if (process == null) {
12968            // If process is null, we are being called from some internal code
12969            // and may be about to die -- run this synchronously.
12970            worker.run();
12971        } else {
12972            worker.start();
12973        }
12974    }
12975
12976    /**
12977     * Bring up the "unexpected error" dialog box for a crashing app.
12978     * Deal with edge cases (intercepts from instrumented applications,
12979     * ActivityController, error intent receivers, that sort of thing).
12980     * @param r the application crashing
12981     * @param crashInfo describing the failure
12982     */
12983    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12984        long timeMillis = System.currentTimeMillis();
12985        String shortMsg = crashInfo.exceptionClassName;
12986        String longMsg = crashInfo.exceptionMessage;
12987        String stackTrace = crashInfo.stackTrace;
12988        if (shortMsg != null && longMsg != null) {
12989            longMsg = shortMsg + ": " + longMsg;
12990        } else if (shortMsg != null) {
12991            longMsg = shortMsg;
12992        }
12993
12994        AppErrorResult result = new AppErrorResult();
12995        synchronized (this) {
12996            if (mController != null) {
12997                try {
12998                    String name = r != null ? r.processName : null;
12999                    int pid = r != null ? r.pid : Binder.getCallingPid();
13000                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
13001                    if (!mController.appCrashed(name, pid,
13002                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
13003                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
13004                                && "Native crash".equals(crashInfo.exceptionClassName)) {
13005                            Slog.w(TAG, "Skip killing native crashed app " + name
13006                                    + "(" + pid + ") during testing");
13007                        } else {
13008                            Slog.w(TAG, "Force-killing crashed app " + name
13009                                    + " at watcher's request");
13010                            if (r != null) {
13011                                r.kill("crash", true);
13012                            } else {
13013                                // Huh.
13014                                Process.killProcess(pid);
13015                                killProcessGroup(uid, pid);
13016                            }
13017                        }
13018                        return;
13019                    }
13020                } catch (RemoteException e) {
13021                    mController = null;
13022                    Watchdog.getInstance().setActivityController(null);
13023                }
13024            }
13025
13026            final long origId = Binder.clearCallingIdentity();
13027
13028            // If this process is running instrumentation, finish it.
13029            if (r != null && r.instrumentationClass != null) {
13030                Slog.w(TAG, "Error in app " + r.processName
13031                      + " running instrumentation " + r.instrumentationClass + ":");
13032                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
13033                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
13034                Bundle info = new Bundle();
13035                info.putString("shortMsg", shortMsg);
13036                info.putString("longMsg", longMsg);
13037                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
13038                Binder.restoreCallingIdentity(origId);
13039                return;
13040            }
13041
13042            // Log crash in battery stats.
13043            if (r != null) {
13044                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
13045            }
13046
13047            // If we can't identify the process or it's already exceeded its crash quota,
13048            // quit right away without showing a crash dialog.
13049            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
13050                Binder.restoreCallingIdentity(origId);
13051                return;
13052            }
13053
13054            Message msg = Message.obtain();
13055            msg.what = SHOW_ERROR_UI_MSG;
13056            HashMap data = new HashMap();
13057            data.put("result", result);
13058            data.put("app", r);
13059            msg.obj = data;
13060            mUiHandler.sendMessage(msg);
13061
13062            Binder.restoreCallingIdentity(origId);
13063        }
13064
13065        int res = result.get();
13066
13067        Intent appErrorIntent = null;
13068        synchronized (this) {
13069            if (r != null && !r.isolated) {
13070                // XXX Can't keep track of crash time for isolated processes,
13071                // since they don't have a persistent identity.
13072                mProcessCrashTimes.put(r.info.processName, r.uid,
13073                        SystemClock.uptimeMillis());
13074            }
13075            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
13076                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
13077            }
13078        }
13079
13080        if (appErrorIntent != null) {
13081            try {
13082                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
13083            } catch (ActivityNotFoundException e) {
13084                Slog.w(TAG, "bug report receiver dissappeared", e);
13085            }
13086        }
13087    }
13088
13089    Intent createAppErrorIntentLocked(ProcessRecord r,
13090            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
13091        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
13092        if (report == null) {
13093            return null;
13094        }
13095        Intent result = new Intent(Intent.ACTION_APP_ERROR);
13096        result.setComponent(r.errorReportReceiver);
13097        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
13098        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
13099        return result;
13100    }
13101
13102    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
13103            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
13104        if (r.errorReportReceiver == null) {
13105            return null;
13106        }
13107
13108        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
13109            return null;
13110        }
13111
13112        ApplicationErrorReport report = new ApplicationErrorReport();
13113        report.packageName = r.info.packageName;
13114        report.installerPackageName = r.errorReportReceiver.getPackageName();
13115        report.processName = r.processName;
13116        report.time = timeMillis;
13117        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
13118
13119        if (r.crashing || r.forceCrashReport) {
13120            report.type = ApplicationErrorReport.TYPE_CRASH;
13121            report.crashInfo = crashInfo;
13122        } else if (r.notResponding) {
13123            report.type = ApplicationErrorReport.TYPE_ANR;
13124            report.anrInfo = new ApplicationErrorReport.AnrInfo();
13125
13126            report.anrInfo.activity = r.notRespondingReport.tag;
13127            report.anrInfo.cause = r.notRespondingReport.shortMsg;
13128            report.anrInfo.info = r.notRespondingReport.longMsg;
13129        }
13130
13131        return report;
13132    }
13133
13134    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13135        enforceNotIsolatedCaller("getProcessesInErrorState");
13136        // assume our apps are happy - lazy create the list
13137        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13138
13139        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13140                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13141        int userId = UserHandle.getUserId(Binder.getCallingUid());
13142
13143        synchronized (this) {
13144
13145            // iterate across all processes
13146            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13147                ProcessRecord app = mLruProcesses.get(i);
13148                if (!allUsers && app.userId != userId) {
13149                    continue;
13150                }
13151                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13152                    // This one's in trouble, so we'll generate a report for it
13153                    // crashes are higher priority (in case there's a crash *and* an anr)
13154                    ActivityManager.ProcessErrorStateInfo report = null;
13155                    if (app.crashing) {
13156                        report = app.crashingReport;
13157                    } else if (app.notResponding) {
13158                        report = app.notRespondingReport;
13159                    }
13160
13161                    if (report != null) {
13162                        if (errList == null) {
13163                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13164                        }
13165                        errList.add(report);
13166                    } else {
13167                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13168                                " crashing = " + app.crashing +
13169                                " notResponding = " + app.notResponding);
13170                    }
13171                }
13172            }
13173        }
13174
13175        return errList;
13176    }
13177
13178    static int procStateToImportance(int procState, int memAdj,
13179            ActivityManager.RunningAppProcessInfo currApp) {
13180        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13181        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13182            currApp.lru = memAdj;
13183        } else {
13184            currApp.lru = 0;
13185        }
13186        return imp;
13187    }
13188
13189    private void fillInProcMemInfo(ProcessRecord app,
13190            ActivityManager.RunningAppProcessInfo outInfo) {
13191        outInfo.pid = app.pid;
13192        outInfo.uid = app.info.uid;
13193        if (mHeavyWeightProcess == app) {
13194            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13195        }
13196        if (app.persistent) {
13197            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13198        }
13199        if (app.activities.size() > 0) {
13200            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13201        }
13202        outInfo.lastTrimLevel = app.trimMemoryLevel;
13203        int adj = app.curAdj;
13204        int procState = app.curProcState;
13205        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13206        outInfo.importanceReasonCode = app.adjTypeCode;
13207        outInfo.processState = app.curProcState;
13208    }
13209
13210    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13211        enforceNotIsolatedCaller("getRunningAppProcesses");
13212
13213        final int callingUid = Binder.getCallingUid();
13214
13215        // Lazy instantiation of list
13216        List<ActivityManager.RunningAppProcessInfo> runList = null;
13217        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13218                callingUid) == PackageManager.PERMISSION_GRANTED;
13219        final int userId = UserHandle.getUserId(callingUid);
13220        final boolean allUids = isGetTasksAllowed(
13221                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13222
13223        synchronized (this) {
13224            // Iterate across all processes
13225            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13226                ProcessRecord app = mLruProcesses.get(i);
13227                if ((!allUsers && app.userId != userId)
13228                        || (!allUids && app.uid != callingUid)) {
13229                    continue;
13230                }
13231                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13232                    // Generate process state info for running application
13233                    ActivityManager.RunningAppProcessInfo currApp =
13234                        new ActivityManager.RunningAppProcessInfo(app.processName,
13235                                app.pid, app.getPackageList());
13236                    fillInProcMemInfo(app, currApp);
13237                    if (app.adjSource instanceof ProcessRecord) {
13238                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13239                        currApp.importanceReasonImportance =
13240                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13241                                        app.adjSourceProcState);
13242                    } else if (app.adjSource instanceof ActivityRecord) {
13243                        ActivityRecord r = (ActivityRecord)app.adjSource;
13244                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13245                    }
13246                    if (app.adjTarget instanceof ComponentName) {
13247                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13248                    }
13249                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13250                    //        + " lru=" + currApp.lru);
13251                    if (runList == null) {
13252                        runList = new ArrayList<>();
13253                    }
13254                    runList.add(currApp);
13255                }
13256            }
13257        }
13258        return runList;
13259    }
13260
13261    public List<ApplicationInfo> getRunningExternalApplications() {
13262        enforceNotIsolatedCaller("getRunningExternalApplications");
13263        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13264        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13265        if (runningApps != null && runningApps.size() > 0) {
13266            Set<String> extList = new HashSet<String>();
13267            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13268                if (app.pkgList != null) {
13269                    for (String pkg : app.pkgList) {
13270                        extList.add(pkg);
13271                    }
13272                }
13273            }
13274            IPackageManager pm = AppGlobals.getPackageManager();
13275            for (String pkg : extList) {
13276                try {
13277                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13278                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13279                        retList.add(info);
13280                    }
13281                } catch (RemoteException e) {
13282                }
13283            }
13284        }
13285        return retList;
13286    }
13287
13288    @Override
13289    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13290        enforceNotIsolatedCaller("getMyMemoryState");
13291        synchronized (this) {
13292            ProcessRecord proc;
13293            synchronized (mPidsSelfLocked) {
13294                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13295            }
13296            fillInProcMemInfo(proc, outInfo);
13297        }
13298    }
13299
13300    @Override
13301    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13302            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13303        (new ActivityManagerShellCommand(this, false)).exec(
13304                this, in, out, err, args, resultReceiver);
13305    }
13306
13307    @Override
13308    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13309        if (checkCallingPermission(android.Manifest.permission.DUMP)
13310                != PackageManager.PERMISSION_GRANTED) {
13311            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13312                    + Binder.getCallingPid()
13313                    + ", uid=" + Binder.getCallingUid()
13314                    + " without permission "
13315                    + android.Manifest.permission.DUMP);
13316            return;
13317        }
13318
13319        boolean dumpAll = false;
13320        boolean dumpClient = false;
13321        String dumpPackage = null;
13322
13323        int opti = 0;
13324        while (opti < args.length) {
13325            String opt = args[opti];
13326            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13327                break;
13328            }
13329            opti++;
13330            if ("-a".equals(opt)) {
13331                dumpAll = true;
13332            } else if ("-c".equals(opt)) {
13333                dumpClient = true;
13334            } else if ("-p".equals(opt)) {
13335                if (opti < args.length) {
13336                    dumpPackage = args[opti];
13337                    opti++;
13338                } else {
13339                    pw.println("Error: -p option requires package argument");
13340                    return;
13341                }
13342                dumpClient = true;
13343            } else if ("-h".equals(opt)) {
13344                ActivityManagerShellCommand.dumpHelp(pw, true);
13345                return;
13346            } else {
13347                pw.println("Unknown argument: " + opt + "; use -h for help");
13348            }
13349        }
13350
13351        long origId = Binder.clearCallingIdentity();
13352        boolean more = false;
13353        // Is the caller requesting to dump a particular piece of data?
13354        if (opti < args.length) {
13355            String cmd = args[opti];
13356            opti++;
13357            if ("activities".equals(cmd) || "a".equals(cmd)) {
13358                synchronized (this) {
13359                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13360                }
13361            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13362                synchronized (this) {
13363                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13364                }
13365            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13366                String[] newArgs;
13367                String name;
13368                if (opti >= args.length) {
13369                    name = null;
13370                    newArgs = EMPTY_STRING_ARRAY;
13371                } else {
13372                    dumpPackage = args[opti];
13373                    opti++;
13374                    newArgs = new String[args.length - opti];
13375                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13376                            args.length - opti);
13377                }
13378                synchronized (this) {
13379                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13380                }
13381            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13382                String[] newArgs;
13383                String name;
13384                if (opti >= args.length) {
13385                    name = null;
13386                    newArgs = EMPTY_STRING_ARRAY;
13387                } else {
13388                    dumpPackage = args[opti];
13389                    opti++;
13390                    newArgs = new String[args.length - opti];
13391                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13392                            args.length - opti);
13393                }
13394                synchronized (this) {
13395                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13396                }
13397            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13398                String[] newArgs;
13399                String name;
13400                if (opti >= args.length) {
13401                    name = null;
13402                    newArgs = EMPTY_STRING_ARRAY;
13403                } else {
13404                    dumpPackage = args[opti];
13405                    opti++;
13406                    newArgs = new String[args.length - opti];
13407                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13408                            args.length - opti);
13409                }
13410                synchronized (this) {
13411                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13412                }
13413            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13414                synchronized (this) {
13415                    dumpOomLocked(fd, pw, args, opti, true);
13416                }
13417            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13418                synchronized (this) {
13419                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13420                }
13421            } else if ("provider".equals(cmd)) {
13422                String[] newArgs;
13423                String name;
13424                if (opti >= args.length) {
13425                    name = null;
13426                    newArgs = EMPTY_STRING_ARRAY;
13427                } else {
13428                    name = args[opti];
13429                    opti++;
13430                    newArgs = new String[args.length - opti];
13431                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13432                }
13433                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13434                    pw.println("No providers match: " + name);
13435                    pw.println("Use -h for help.");
13436                }
13437            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13438                synchronized (this) {
13439                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13440                }
13441            } else if ("service".equals(cmd)) {
13442                String[] newArgs;
13443                String name;
13444                if (opti >= args.length) {
13445                    name = null;
13446                    newArgs = EMPTY_STRING_ARRAY;
13447                } else {
13448                    name = args[opti];
13449                    opti++;
13450                    newArgs = new String[args.length - opti];
13451                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13452                            args.length - opti);
13453                }
13454                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13455                    pw.println("No services match: " + name);
13456                    pw.println("Use -h for help.");
13457                }
13458            } else if ("package".equals(cmd)) {
13459                String[] newArgs;
13460                if (opti >= args.length) {
13461                    pw.println("package: no package name specified");
13462                    pw.println("Use -h for help.");
13463                } else {
13464                    dumpPackage = args[opti];
13465                    opti++;
13466                    newArgs = new String[args.length - opti];
13467                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13468                            args.length - opti);
13469                    args = newArgs;
13470                    opti = 0;
13471                    more = true;
13472                }
13473            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13474                synchronized (this) {
13475                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13476                }
13477            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13478                synchronized (this) {
13479                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13480                }
13481            } else {
13482                // Dumping a single activity?
13483                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13484                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13485                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13486                    if (res < 0) {
13487                        pw.println("Bad activity command, or no activities match: " + cmd);
13488                        pw.println("Use -h for help.");
13489                    }
13490                }
13491            }
13492            if (!more) {
13493                Binder.restoreCallingIdentity(origId);
13494                return;
13495            }
13496        }
13497
13498        // No piece of data specified, dump everything.
13499        synchronized (this) {
13500            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13501            pw.println();
13502            if (dumpAll) {
13503                pw.println("-------------------------------------------------------------------------------");
13504            }
13505            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13506            pw.println();
13507            if (dumpAll) {
13508                pw.println("-------------------------------------------------------------------------------");
13509            }
13510            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13511            pw.println();
13512            if (dumpAll) {
13513                pw.println("-------------------------------------------------------------------------------");
13514            }
13515            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13516            pw.println();
13517            if (dumpAll) {
13518                pw.println("-------------------------------------------------------------------------------");
13519            }
13520            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13521            pw.println();
13522            if (dumpAll) {
13523                pw.println("-------------------------------------------------------------------------------");
13524            }
13525            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13526            pw.println();
13527            if (dumpAll) {
13528                pw.println("-------------------------------------------------------------------------------");
13529            }
13530            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13531            if (mAssociations.size() > 0) {
13532                pw.println();
13533                if (dumpAll) {
13534                    pw.println("-------------------------------------------------------------------------------");
13535                }
13536                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13537            }
13538            pw.println();
13539            if (dumpAll) {
13540                pw.println("-------------------------------------------------------------------------------");
13541            }
13542            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13543        }
13544        Binder.restoreCallingIdentity(origId);
13545    }
13546
13547    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13548            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13549        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13550
13551        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13552                dumpPackage);
13553        boolean needSep = printedAnything;
13554
13555        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13556                dumpPackage, needSep, "  mFocusedActivity: ");
13557        if (printed) {
13558            printedAnything = true;
13559            needSep = false;
13560        }
13561
13562        if (dumpPackage == null) {
13563            if (needSep) {
13564                pw.println();
13565            }
13566            needSep = true;
13567            printedAnything = true;
13568            mStackSupervisor.dump(pw, "  ");
13569        }
13570
13571        if (!printedAnything) {
13572            pw.println("  (nothing)");
13573        }
13574    }
13575
13576    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13577            int opti, boolean dumpAll, String dumpPackage) {
13578        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13579
13580        boolean printedAnything = false;
13581
13582        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13583            boolean printedHeader = false;
13584
13585            final int N = mRecentTasks.size();
13586            for (int i=0; i<N; i++) {
13587                TaskRecord tr = mRecentTasks.get(i);
13588                if (dumpPackage != null) {
13589                    if (tr.realActivity == null ||
13590                            !dumpPackage.equals(tr.realActivity)) {
13591                        continue;
13592                    }
13593                }
13594                if (!printedHeader) {
13595                    pw.println("  Recent tasks:");
13596                    printedHeader = true;
13597                    printedAnything = true;
13598                }
13599                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13600                        pw.println(tr);
13601                if (dumpAll) {
13602                    mRecentTasks.get(i).dump(pw, "    ");
13603                }
13604            }
13605        }
13606
13607        if (!printedAnything) {
13608            pw.println("  (nothing)");
13609        }
13610    }
13611
13612    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13613            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13614        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13615
13616        int dumpUid = 0;
13617        if (dumpPackage != null) {
13618            IPackageManager pm = AppGlobals.getPackageManager();
13619            try {
13620                dumpUid = pm.getPackageUid(dumpPackage, 0);
13621            } catch (RemoteException e) {
13622            }
13623        }
13624
13625        boolean printedAnything = false;
13626
13627        final long now = SystemClock.uptimeMillis();
13628
13629        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13630            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13631                    = mAssociations.valueAt(i1);
13632            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13633                SparseArray<ArrayMap<String, Association>> sourceUids
13634                        = targetComponents.valueAt(i2);
13635                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13636                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13637                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13638                        Association ass = sourceProcesses.valueAt(i4);
13639                        if (dumpPackage != null) {
13640                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13641                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13642                                continue;
13643                            }
13644                        }
13645                        printedAnything = true;
13646                        pw.print("  ");
13647                        pw.print(ass.mTargetProcess);
13648                        pw.print("/");
13649                        UserHandle.formatUid(pw, ass.mTargetUid);
13650                        pw.print(" <- ");
13651                        pw.print(ass.mSourceProcess);
13652                        pw.print("/");
13653                        UserHandle.formatUid(pw, ass.mSourceUid);
13654                        pw.println();
13655                        pw.print("    via ");
13656                        pw.print(ass.mTargetComponent.flattenToShortString());
13657                        pw.println();
13658                        pw.print("    ");
13659                        long dur = ass.mTime;
13660                        if (ass.mNesting > 0) {
13661                            dur += now - ass.mStartTime;
13662                        }
13663                        TimeUtils.formatDuration(dur, pw);
13664                        pw.print(" (");
13665                        pw.print(ass.mCount);
13666                        pw.println(" times)");
13667                        if (ass.mNesting > 0) {
13668                            pw.print("    ");
13669                            pw.print(" Currently active: ");
13670                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13671                            pw.println();
13672                        }
13673                    }
13674                }
13675            }
13676
13677        }
13678
13679        if (!printedAnything) {
13680            pw.println("  (nothing)");
13681        }
13682    }
13683
13684    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13685            String header, boolean needSep) {
13686        boolean printed = false;
13687        int whichAppId = -1;
13688        if (dumpPackage != null) {
13689            try {
13690                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13691                        dumpPackage, 0);
13692                whichAppId = UserHandle.getAppId(info.uid);
13693            } catch (NameNotFoundException e) {
13694                e.printStackTrace();
13695            }
13696        }
13697        for (int i=0; i<uids.size(); i++) {
13698            UidRecord uidRec = uids.valueAt(i);
13699            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13700                continue;
13701            }
13702            if (!printed) {
13703                printed = true;
13704                if (needSep) {
13705                    pw.println();
13706                }
13707                pw.print("  ");
13708                pw.println(header);
13709                needSep = true;
13710            }
13711            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13712            pw.print(": "); pw.println(uidRec);
13713        }
13714        return printed;
13715    }
13716
13717    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13718            int opti, boolean dumpAll, String dumpPackage) {
13719        boolean needSep = false;
13720        boolean printedAnything = false;
13721        int numPers = 0;
13722
13723        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13724
13725        if (dumpAll) {
13726            final int NP = mProcessNames.getMap().size();
13727            for (int ip=0; ip<NP; ip++) {
13728                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13729                final int NA = procs.size();
13730                for (int ia=0; ia<NA; ia++) {
13731                    ProcessRecord r = procs.valueAt(ia);
13732                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13733                        continue;
13734                    }
13735                    if (!needSep) {
13736                        pw.println("  All known processes:");
13737                        needSep = true;
13738                        printedAnything = true;
13739                    }
13740                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13741                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13742                        pw.print(" "); pw.println(r);
13743                    r.dump(pw, "    ");
13744                    if (r.persistent) {
13745                        numPers++;
13746                    }
13747                }
13748            }
13749        }
13750
13751        if (mIsolatedProcesses.size() > 0) {
13752            boolean printed = false;
13753            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13754                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13755                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13756                    continue;
13757                }
13758                if (!printed) {
13759                    if (needSep) {
13760                        pw.println();
13761                    }
13762                    pw.println("  Isolated process list (sorted by uid):");
13763                    printedAnything = true;
13764                    printed = true;
13765                    needSep = true;
13766                }
13767                pw.println(String.format("%sIsolated #%2d: %s",
13768                        "    ", i, r.toString()));
13769            }
13770        }
13771
13772        if (mActiveUids.size() > 0) {
13773            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
13774                printedAnything = needSep = true;
13775            }
13776        }
13777        if (mValidateUids.size() > 0) {
13778            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
13779                printedAnything = needSep = true;
13780            }
13781        }
13782
13783        if (mLruProcesses.size() > 0) {
13784            if (needSep) {
13785                pw.println();
13786            }
13787            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13788                    pw.print(" total, non-act at ");
13789                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13790                    pw.print(", non-svc at ");
13791                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13792                    pw.println("):");
13793            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13794            needSep = true;
13795            printedAnything = true;
13796        }
13797
13798        if (dumpAll || dumpPackage != null) {
13799            synchronized (mPidsSelfLocked) {
13800                boolean printed = false;
13801                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13802                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13803                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13804                        continue;
13805                    }
13806                    if (!printed) {
13807                        if (needSep) pw.println();
13808                        needSep = true;
13809                        pw.println("  PID mappings:");
13810                        printed = true;
13811                        printedAnything = true;
13812                    }
13813                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13814                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13815                }
13816            }
13817        }
13818
13819        if (mForegroundProcesses.size() > 0) {
13820            synchronized (mPidsSelfLocked) {
13821                boolean printed = false;
13822                for (int i=0; i<mForegroundProcesses.size(); i++) {
13823                    ProcessRecord r = mPidsSelfLocked.get(
13824                            mForegroundProcesses.valueAt(i).pid);
13825                    if (dumpPackage != null && (r == null
13826                            || !r.pkgList.containsKey(dumpPackage))) {
13827                        continue;
13828                    }
13829                    if (!printed) {
13830                        if (needSep) pw.println();
13831                        needSep = true;
13832                        pw.println("  Foreground Processes:");
13833                        printed = true;
13834                        printedAnything = true;
13835                    }
13836                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13837                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13838                }
13839            }
13840        }
13841
13842        if (mPersistentStartingProcesses.size() > 0) {
13843            if (needSep) pw.println();
13844            needSep = true;
13845            printedAnything = true;
13846            pw.println("  Persisent processes that are starting:");
13847            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13848                    "Starting Norm", "Restarting PERS", dumpPackage);
13849        }
13850
13851        if (mRemovedProcesses.size() > 0) {
13852            if (needSep) pw.println();
13853            needSep = true;
13854            printedAnything = true;
13855            pw.println("  Processes that are being removed:");
13856            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13857                    "Removed Norm", "Removed PERS", dumpPackage);
13858        }
13859
13860        if (mProcessesOnHold.size() > 0) {
13861            if (needSep) pw.println();
13862            needSep = true;
13863            printedAnything = true;
13864            pw.println("  Processes that are on old until the system is ready:");
13865            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13866                    "OnHold Norm", "OnHold PERS", dumpPackage);
13867        }
13868
13869        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13870
13871        if (mProcessCrashTimes.getMap().size() > 0) {
13872            boolean printed = false;
13873            long now = SystemClock.uptimeMillis();
13874            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13875            final int NP = pmap.size();
13876            for (int ip=0; ip<NP; ip++) {
13877                String pname = pmap.keyAt(ip);
13878                SparseArray<Long> uids = pmap.valueAt(ip);
13879                final int N = uids.size();
13880                for (int i=0; i<N; i++) {
13881                    int puid = uids.keyAt(i);
13882                    ProcessRecord r = mProcessNames.get(pname, puid);
13883                    if (dumpPackage != null && (r == null
13884                            || !r.pkgList.containsKey(dumpPackage))) {
13885                        continue;
13886                    }
13887                    if (!printed) {
13888                        if (needSep) pw.println();
13889                        needSep = true;
13890                        pw.println("  Time since processes crashed:");
13891                        printed = true;
13892                        printedAnything = true;
13893                    }
13894                    pw.print("    Process "); pw.print(pname);
13895                            pw.print(" uid "); pw.print(puid);
13896                            pw.print(": last crashed ");
13897                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13898                            pw.println(" ago");
13899                }
13900            }
13901        }
13902
13903        if (mBadProcesses.getMap().size() > 0) {
13904            boolean printed = false;
13905            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13906            final int NP = pmap.size();
13907            for (int ip=0; ip<NP; ip++) {
13908                String pname = pmap.keyAt(ip);
13909                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13910                final int N = uids.size();
13911                for (int i=0; i<N; i++) {
13912                    int puid = uids.keyAt(i);
13913                    ProcessRecord r = mProcessNames.get(pname, puid);
13914                    if (dumpPackage != null && (r == null
13915                            || !r.pkgList.containsKey(dumpPackage))) {
13916                        continue;
13917                    }
13918                    if (!printed) {
13919                        if (needSep) pw.println();
13920                        needSep = true;
13921                        pw.println("  Bad processes:");
13922                        printedAnything = true;
13923                    }
13924                    BadProcessInfo info = uids.valueAt(i);
13925                    pw.print("    Bad process "); pw.print(pname);
13926                            pw.print(" uid "); pw.print(puid);
13927                            pw.print(": crashed at time "); pw.println(info.time);
13928                    if (info.shortMsg != null) {
13929                        pw.print("      Short msg: "); pw.println(info.shortMsg);
13930                    }
13931                    if (info.longMsg != null) {
13932                        pw.print("      Long msg: "); pw.println(info.longMsg);
13933                    }
13934                    if (info.stack != null) {
13935                        pw.println("      Stack:");
13936                        int lastPos = 0;
13937                        for (int pos=0; pos<info.stack.length(); pos++) {
13938                            if (info.stack.charAt(pos) == '\n') {
13939                                pw.print("        ");
13940                                pw.write(info.stack, lastPos, pos-lastPos);
13941                                pw.println();
13942                                lastPos = pos+1;
13943                            }
13944                        }
13945                        if (lastPos < info.stack.length()) {
13946                            pw.print("        ");
13947                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13948                            pw.println();
13949                        }
13950                    }
13951                }
13952            }
13953        }
13954
13955        if (dumpPackage == null) {
13956            pw.println();
13957            needSep = false;
13958            mUserController.dump(pw, dumpAll);
13959        }
13960        if (mHomeProcess != null && (dumpPackage == null
13961                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13962            if (needSep) {
13963                pw.println();
13964                needSep = false;
13965            }
13966            pw.println("  mHomeProcess: " + mHomeProcess);
13967        }
13968        if (mPreviousProcess != null && (dumpPackage == null
13969                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13970            if (needSep) {
13971                pw.println();
13972                needSep = false;
13973            }
13974            pw.println("  mPreviousProcess: " + mPreviousProcess);
13975        }
13976        if (dumpAll) {
13977            StringBuilder sb = new StringBuilder(128);
13978            sb.append("  mPreviousProcessVisibleTime: ");
13979            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13980            pw.println(sb);
13981        }
13982        if (mHeavyWeightProcess != null && (dumpPackage == null
13983                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13984            if (needSep) {
13985                pw.println();
13986                needSep = false;
13987            }
13988            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13989        }
13990        if (dumpPackage == null) {
13991            pw.println("  mConfiguration: " + mConfiguration);
13992        }
13993        if (dumpAll) {
13994            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13995            if (mCompatModePackages.getPackages().size() > 0) {
13996                boolean printed = false;
13997                for (Map.Entry<String, Integer> entry
13998                        : mCompatModePackages.getPackages().entrySet()) {
13999                    String pkg = entry.getKey();
14000                    int mode = entry.getValue();
14001                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14002                        continue;
14003                    }
14004                    if (!printed) {
14005                        pw.println("  mScreenCompatPackages:");
14006                        printed = true;
14007                    }
14008                    pw.print("    "); pw.print(pkg); pw.print(": ");
14009                            pw.print(mode); pw.println();
14010                }
14011            }
14012        }
14013        if (dumpPackage == null) {
14014            pw.println("  mWakefulness="
14015                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14016            pw.println("  mSleepTokens=" + mSleepTokens);
14017            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14018                    + lockScreenShownToString());
14019            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14020            if (mRunningVoice != null) {
14021                pw.println("  mRunningVoice=" + mRunningVoice);
14022                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14023            }
14024        }
14025        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14026                || mOrigWaitForDebugger) {
14027            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14028                    || dumpPackage.equals(mOrigDebugApp)) {
14029                if (needSep) {
14030                    pw.println();
14031                    needSep = false;
14032                }
14033                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14034                        + " mDebugTransient=" + mDebugTransient
14035                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14036            }
14037        }
14038        if (mCurAppTimeTracker != null) {
14039            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14040        }
14041        if (mMemWatchProcesses.getMap().size() > 0) {
14042            pw.println("  Mem watch processes:");
14043            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14044                    = mMemWatchProcesses.getMap();
14045            for (int i=0; i<procs.size(); i++) {
14046                final String proc = procs.keyAt(i);
14047                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14048                for (int j=0; j<uids.size(); j++) {
14049                    if (needSep) {
14050                        pw.println();
14051                        needSep = false;
14052                    }
14053                    StringBuilder sb = new StringBuilder();
14054                    sb.append("    ").append(proc).append('/');
14055                    UserHandle.formatUid(sb, uids.keyAt(j));
14056                    Pair<Long, String> val = uids.valueAt(j);
14057                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14058                    if (val.second != null) {
14059                        sb.append(", report to ").append(val.second);
14060                    }
14061                    pw.println(sb.toString());
14062                }
14063            }
14064            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14065            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14066            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14067                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14068        }
14069        if (mTrackAllocationApp != null) {
14070            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14071                if (needSep) {
14072                    pw.println();
14073                    needSep = false;
14074                }
14075                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14076            }
14077        }
14078        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14079                || mProfileFd != null) {
14080            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14081                if (needSep) {
14082                    pw.println();
14083                    needSep = false;
14084                }
14085                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14086                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14087                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14088                        + mAutoStopProfiler);
14089                pw.println("  mProfileType=" + mProfileType);
14090            }
14091        }
14092        if (dumpPackage == null) {
14093            if (mAlwaysFinishActivities || mController != null) {
14094                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14095                        + " mController=" + mController);
14096            }
14097            if (dumpAll) {
14098                pw.println("  Total persistent processes: " + numPers);
14099                pw.println("  mProcessesReady=" + mProcessesReady
14100                        + " mSystemReady=" + mSystemReady
14101                        + " mBooted=" + mBooted
14102                        + " mFactoryTest=" + mFactoryTest);
14103                pw.println("  mBooting=" + mBooting
14104                        + " mCallFinishBooting=" + mCallFinishBooting
14105                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14106                pw.print("  mLastPowerCheckRealtime=");
14107                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14108                        pw.println("");
14109                pw.print("  mLastPowerCheckUptime=");
14110                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14111                        pw.println("");
14112                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14113                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14114                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14115                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14116                        + " (" + mLruProcesses.size() + " total)"
14117                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14118                        + " mNumServiceProcs=" + mNumServiceProcs
14119                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14120                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14121                        + " mLastMemoryLevel" + mLastMemoryLevel
14122                        + " mLastNumProcesses" + mLastNumProcesses);
14123                long now = SystemClock.uptimeMillis();
14124                pw.print("  mLastIdleTime=");
14125                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14126                        pw.print(" mLowRamSinceLastIdle=");
14127                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14128                        pw.println();
14129            }
14130        }
14131
14132        if (!printedAnything) {
14133            pw.println("  (nothing)");
14134        }
14135    }
14136
14137    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14138            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14139        if (mProcessesToGc.size() > 0) {
14140            boolean printed = false;
14141            long now = SystemClock.uptimeMillis();
14142            for (int i=0; i<mProcessesToGc.size(); i++) {
14143                ProcessRecord proc = mProcessesToGc.get(i);
14144                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14145                    continue;
14146                }
14147                if (!printed) {
14148                    if (needSep) pw.println();
14149                    needSep = true;
14150                    pw.println("  Processes that are waiting to GC:");
14151                    printed = true;
14152                }
14153                pw.print("    Process "); pw.println(proc);
14154                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14155                        pw.print(", last gced=");
14156                        pw.print(now-proc.lastRequestedGc);
14157                        pw.print(" ms ago, last lowMem=");
14158                        pw.print(now-proc.lastLowMemory);
14159                        pw.println(" ms ago");
14160
14161            }
14162        }
14163        return needSep;
14164    }
14165
14166    void printOomLevel(PrintWriter pw, String name, int adj) {
14167        pw.print("    ");
14168        if (adj >= 0) {
14169            pw.print(' ');
14170            if (adj < 10) pw.print(' ');
14171        } else {
14172            if (adj > -10) pw.print(' ');
14173        }
14174        pw.print(adj);
14175        pw.print(": ");
14176        pw.print(name);
14177        pw.print(" (");
14178        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14179        pw.println(")");
14180    }
14181
14182    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14183            int opti, boolean dumpAll) {
14184        boolean needSep = false;
14185
14186        if (mLruProcesses.size() > 0) {
14187            if (needSep) pw.println();
14188            needSep = true;
14189            pw.println("  OOM levels:");
14190            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14191            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14192            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14193            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14194            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14195            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14196            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14197            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14198            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14199            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14200            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14201            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14202            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14203            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14204
14205            if (needSep) pw.println();
14206            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14207                    pw.print(" total, non-act at ");
14208                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14209                    pw.print(", non-svc at ");
14210                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14211                    pw.println("):");
14212            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14213            needSep = true;
14214        }
14215
14216        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14217
14218        pw.println();
14219        pw.println("  mHomeProcess: " + mHomeProcess);
14220        pw.println("  mPreviousProcess: " + mPreviousProcess);
14221        if (mHeavyWeightProcess != null) {
14222            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14223        }
14224
14225        return true;
14226    }
14227
14228    /**
14229     * There are three ways to call this:
14230     *  - no provider specified: dump all the providers
14231     *  - a flattened component name that matched an existing provider was specified as the
14232     *    first arg: dump that one provider
14233     *  - the first arg isn't the flattened component name of an existing provider:
14234     *    dump all providers whose component contains the first arg as a substring
14235     */
14236    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14237            int opti, boolean dumpAll) {
14238        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14239    }
14240
14241    static class ItemMatcher {
14242        ArrayList<ComponentName> components;
14243        ArrayList<String> strings;
14244        ArrayList<Integer> objects;
14245        boolean all;
14246
14247        ItemMatcher() {
14248            all = true;
14249        }
14250
14251        void build(String name) {
14252            ComponentName componentName = ComponentName.unflattenFromString(name);
14253            if (componentName != null) {
14254                if (components == null) {
14255                    components = new ArrayList<ComponentName>();
14256                }
14257                components.add(componentName);
14258                all = false;
14259            } else {
14260                int objectId = 0;
14261                // Not a '/' separated full component name; maybe an object ID?
14262                try {
14263                    objectId = Integer.parseInt(name, 16);
14264                    if (objects == null) {
14265                        objects = new ArrayList<Integer>();
14266                    }
14267                    objects.add(objectId);
14268                    all = false;
14269                } catch (RuntimeException e) {
14270                    // Not an integer; just do string match.
14271                    if (strings == null) {
14272                        strings = new ArrayList<String>();
14273                    }
14274                    strings.add(name);
14275                    all = false;
14276                }
14277            }
14278        }
14279
14280        int build(String[] args, int opti) {
14281            for (; opti<args.length; opti++) {
14282                String name = args[opti];
14283                if ("--".equals(name)) {
14284                    return opti+1;
14285                }
14286                build(name);
14287            }
14288            return opti;
14289        }
14290
14291        boolean match(Object object, ComponentName comp) {
14292            if (all) {
14293                return true;
14294            }
14295            if (components != null) {
14296                for (int i=0; i<components.size(); i++) {
14297                    if (components.get(i).equals(comp)) {
14298                        return true;
14299                    }
14300                }
14301            }
14302            if (objects != null) {
14303                for (int i=0; i<objects.size(); i++) {
14304                    if (System.identityHashCode(object) == objects.get(i)) {
14305                        return true;
14306                    }
14307                }
14308            }
14309            if (strings != null) {
14310                String flat = comp.flattenToString();
14311                for (int i=0; i<strings.size(); i++) {
14312                    if (flat.contains(strings.get(i))) {
14313                        return true;
14314                    }
14315                }
14316            }
14317            return false;
14318        }
14319    }
14320
14321    /**
14322     * There are three things that cmd can be:
14323     *  - a flattened component name that matches an existing activity
14324     *  - the cmd arg isn't the flattened component name of an existing activity:
14325     *    dump all activity whose component contains the cmd as a substring
14326     *  - A hex number of the ActivityRecord object instance.
14327     */
14328    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14329            int opti, boolean dumpAll) {
14330        ArrayList<ActivityRecord> activities;
14331
14332        synchronized (this) {
14333            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14334        }
14335
14336        if (activities.size() <= 0) {
14337            return false;
14338        }
14339
14340        String[] newArgs = new String[args.length - opti];
14341        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14342
14343        TaskRecord lastTask = null;
14344        boolean needSep = false;
14345        for (int i=activities.size()-1; i>=0; i--) {
14346            ActivityRecord r = activities.get(i);
14347            if (needSep) {
14348                pw.println();
14349            }
14350            needSep = true;
14351            synchronized (this) {
14352                if (lastTask != r.task) {
14353                    lastTask = r.task;
14354                    pw.print("TASK "); pw.print(lastTask.affinity);
14355                            pw.print(" id="); pw.println(lastTask.taskId);
14356                    if (dumpAll) {
14357                        lastTask.dump(pw, "  ");
14358                    }
14359                }
14360            }
14361            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14362        }
14363        return true;
14364    }
14365
14366    /**
14367     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14368     * there is a thread associated with the activity.
14369     */
14370    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14371            final ActivityRecord r, String[] args, boolean dumpAll) {
14372        String innerPrefix = prefix + "  ";
14373        synchronized (this) {
14374            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14375                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14376                    pw.print(" pid=");
14377                    if (r.app != null) pw.println(r.app.pid);
14378                    else pw.println("(not running)");
14379            if (dumpAll) {
14380                r.dump(pw, innerPrefix);
14381            }
14382        }
14383        if (r.app != null && r.app.thread != null) {
14384            // flush anything that is already in the PrintWriter since the thread is going
14385            // to write to the file descriptor directly
14386            pw.flush();
14387            try {
14388                TransferPipe tp = new TransferPipe();
14389                try {
14390                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14391                            r.appToken, innerPrefix, args);
14392                    tp.go(fd);
14393                } finally {
14394                    tp.kill();
14395                }
14396            } catch (IOException e) {
14397                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14398            } catch (RemoteException e) {
14399                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14400            }
14401        }
14402    }
14403
14404    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14405            int opti, boolean dumpAll, String dumpPackage) {
14406        boolean needSep = false;
14407        boolean onlyHistory = false;
14408        boolean printedAnything = false;
14409
14410        if ("history".equals(dumpPackage)) {
14411            if (opti < args.length && "-s".equals(args[opti])) {
14412                dumpAll = false;
14413            }
14414            onlyHistory = true;
14415            dumpPackage = null;
14416        }
14417
14418        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14419        if (!onlyHistory && dumpAll) {
14420            if (mRegisteredReceivers.size() > 0) {
14421                boolean printed = false;
14422                Iterator it = mRegisteredReceivers.values().iterator();
14423                while (it.hasNext()) {
14424                    ReceiverList r = (ReceiverList)it.next();
14425                    if (dumpPackage != null && (r.app == null ||
14426                            !dumpPackage.equals(r.app.info.packageName))) {
14427                        continue;
14428                    }
14429                    if (!printed) {
14430                        pw.println("  Registered Receivers:");
14431                        needSep = true;
14432                        printed = true;
14433                        printedAnything = true;
14434                    }
14435                    pw.print("  * "); pw.println(r);
14436                    r.dump(pw, "    ");
14437                }
14438            }
14439
14440            if (mReceiverResolver.dump(pw, needSep ?
14441                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14442                    "    ", dumpPackage, false, false)) {
14443                needSep = true;
14444                printedAnything = true;
14445            }
14446        }
14447
14448        for (BroadcastQueue q : mBroadcastQueues) {
14449            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14450            printedAnything |= needSep;
14451        }
14452
14453        needSep = true;
14454
14455        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14456            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14457                if (needSep) {
14458                    pw.println();
14459                }
14460                needSep = true;
14461                printedAnything = true;
14462                pw.print("  Sticky broadcasts for user ");
14463                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14464                StringBuilder sb = new StringBuilder(128);
14465                for (Map.Entry<String, ArrayList<Intent>> ent
14466                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14467                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14468                    if (dumpAll) {
14469                        pw.println(":");
14470                        ArrayList<Intent> intents = ent.getValue();
14471                        final int N = intents.size();
14472                        for (int i=0; i<N; i++) {
14473                            sb.setLength(0);
14474                            sb.append("    Intent: ");
14475                            intents.get(i).toShortString(sb, false, true, false, false);
14476                            pw.println(sb.toString());
14477                            Bundle bundle = intents.get(i).getExtras();
14478                            if (bundle != null) {
14479                                pw.print("      ");
14480                                pw.println(bundle.toString());
14481                            }
14482                        }
14483                    } else {
14484                        pw.println("");
14485                    }
14486                }
14487            }
14488        }
14489
14490        if (!onlyHistory && dumpAll) {
14491            pw.println();
14492            for (BroadcastQueue queue : mBroadcastQueues) {
14493                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14494                        + queue.mBroadcastsScheduled);
14495            }
14496            pw.println("  mHandler:");
14497            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14498            needSep = true;
14499            printedAnything = true;
14500        }
14501
14502        if (!printedAnything) {
14503            pw.println("  (nothing)");
14504        }
14505    }
14506
14507    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14508            int opti, boolean dumpAll, String dumpPackage) {
14509        boolean needSep;
14510        boolean printedAnything = false;
14511
14512        ItemMatcher matcher = new ItemMatcher();
14513        matcher.build(args, opti);
14514
14515        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14516
14517        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14518        printedAnything |= needSep;
14519
14520        if (mLaunchingProviders.size() > 0) {
14521            boolean printed = false;
14522            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14523                ContentProviderRecord r = mLaunchingProviders.get(i);
14524                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14525                    continue;
14526                }
14527                if (!printed) {
14528                    if (needSep) pw.println();
14529                    needSep = true;
14530                    pw.println("  Launching content providers:");
14531                    printed = true;
14532                    printedAnything = true;
14533                }
14534                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14535                        pw.println(r);
14536            }
14537        }
14538
14539        if (!printedAnything) {
14540            pw.println("  (nothing)");
14541        }
14542    }
14543
14544    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14545            int opti, boolean dumpAll, String dumpPackage) {
14546        boolean needSep = false;
14547        boolean printedAnything = false;
14548
14549        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14550
14551        if (mGrantedUriPermissions.size() > 0) {
14552            boolean printed = false;
14553            int dumpUid = -2;
14554            if (dumpPackage != null) {
14555                try {
14556                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14557                } catch (NameNotFoundException e) {
14558                    dumpUid = -1;
14559                }
14560            }
14561            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14562                int uid = mGrantedUriPermissions.keyAt(i);
14563                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14564                    continue;
14565                }
14566                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14567                if (!printed) {
14568                    if (needSep) pw.println();
14569                    needSep = true;
14570                    pw.println("  Granted Uri Permissions:");
14571                    printed = true;
14572                    printedAnything = true;
14573                }
14574                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14575                for (UriPermission perm : perms.values()) {
14576                    pw.print("    "); pw.println(perm);
14577                    if (dumpAll) {
14578                        perm.dump(pw, "      ");
14579                    }
14580                }
14581            }
14582        }
14583
14584        if (!printedAnything) {
14585            pw.println("  (nothing)");
14586        }
14587    }
14588
14589    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14590            int opti, boolean dumpAll, String dumpPackage) {
14591        boolean printed = false;
14592
14593        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14594
14595        if (mIntentSenderRecords.size() > 0) {
14596            Iterator<WeakReference<PendingIntentRecord>> it
14597                    = mIntentSenderRecords.values().iterator();
14598            while (it.hasNext()) {
14599                WeakReference<PendingIntentRecord> ref = it.next();
14600                PendingIntentRecord rec = ref != null ? ref.get(): null;
14601                if (dumpPackage != null && (rec == null
14602                        || !dumpPackage.equals(rec.key.packageName))) {
14603                    continue;
14604                }
14605                printed = true;
14606                if (rec != null) {
14607                    pw.print("  * "); pw.println(rec);
14608                    if (dumpAll) {
14609                        rec.dump(pw, "    ");
14610                    }
14611                } else {
14612                    pw.print("  * "); pw.println(ref);
14613                }
14614            }
14615        }
14616
14617        if (!printed) {
14618            pw.println("  (nothing)");
14619        }
14620    }
14621
14622    private static final int dumpProcessList(PrintWriter pw,
14623            ActivityManagerService service, List list,
14624            String prefix, String normalLabel, String persistentLabel,
14625            String dumpPackage) {
14626        int numPers = 0;
14627        final int N = list.size()-1;
14628        for (int i=N; i>=0; i--) {
14629            ProcessRecord r = (ProcessRecord)list.get(i);
14630            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14631                continue;
14632            }
14633            pw.println(String.format("%s%s #%2d: %s",
14634                    prefix, (r.persistent ? persistentLabel : normalLabel),
14635                    i, r.toString()));
14636            if (r.persistent) {
14637                numPers++;
14638            }
14639        }
14640        return numPers;
14641    }
14642
14643    private static final boolean dumpProcessOomList(PrintWriter pw,
14644            ActivityManagerService service, List<ProcessRecord> origList,
14645            String prefix, String normalLabel, String persistentLabel,
14646            boolean inclDetails, String dumpPackage) {
14647
14648        ArrayList<Pair<ProcessRecord, Integer>> list
14649                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14650        for (int i=0; i<origList.size(); i++) {
14651            ProcessRecord r = origList.get(i);
14652            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14653                continue;
14654            }
14655            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14656        }
14657
14658        if (list.size() <= 0) {
14659            return false;
14660        }
14661
14662        Comparator<Pair<ProcessRecord, Integer>> comparator
14663                = new Comparator<Pair<ProcessRecord, Integer>>() {
14664            @Override
14665            public int compare(Pair<ProcessRecord, Integer> object1,
14666                    Pair<ProcessRecord, Integer> object2) {
14667                if (object1.first.setAdj != object2.first.setAdj) {
14668                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14669                }
14670                if (object1.first.setProcState != object2.first.setProcState) {
14671                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14672                }
14673                if (object1.second.intValue() != object2.second.intValue()) {
14674                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14675                }
14676                return 0;
14677            }
14678        };
14679
14680        Collections.sort(list, comparator);
14681
14682        final long curRealtime = SystemClock.elapsedRealtime();
14683        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14684        final long curUptime = SystemClock.uptimeMillis();
14685        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14686
14687        for (int i=list.size()-1; i>=0; i--) {
14688            ProcessRecord r = list.get(i).first;
14689            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14690            char schedGroup;
14691            switch (r.setSchedGroup) {
14692                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14693                    schedGroup = 'B';
14694                    break;
14695                case Process.THREAD_GROUP_DEFAULT:
14696                    schedGroup = 'F';
14697                    break;
14698                default:
14699                    schedGroup = '?';
14700                    break;
14701            }
14702            char foreground;
14703            if (r.foregroundActivities) {
14704                foreground = 'A';
14705            } else if (r.foregroundServices) {
14706                foreground = 'S';
14707            } else {
14708                foreground = ' ';
14709            }
14710            String procState = ProcessList.makeProcStateString(r.curProcState);
14711            pw.print(prefix);
14712            pw.print(r.persistent ? persistentLabel : normalLabel);
14713            pw.print(" #");
14714            int num = (origList.size()-1)-list.get(i).second;
14715            if (num < 10) pw.print(' ');
14716            pw.print(num);
14717            pw.print(": ");
14718            pw.print(oomAdj);
14719            pw.print(' ');
14720            pw.print(schedGroup);
14721            pw.print('/');
14722            pw.print(foreground);
14723            pw.print('/');
14724            pw.print(procState);
14725            pw.print(" trm:");
14726            if (r.trimMemoryLevel < 10) pw.print(' ');
14727            pw.print(r.trimMemoryLevel);
14728            pw.print(' ');
14729            pw.print(r.toShortString());
14730            pw.print(" (");
14731            pw.print(r.adjType);
14732            pw.println(')');
14733            if (r.adjSource != null || r.adjTarget != null) {
14734                pw.print(prefix);
14735                pw.print("    ");
14736                if (r.adjTarget instanceof ComponentName) {
14737                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14738                } else if (r.adjTarget != null) {
14739                    pw.print(r.adjTarget.toString());
14740                } else {
14741                    pw.print("{null}");
14742                }
14743                pw.print("<=");
14744                if (r.adjSource instanceof ProcessRecord) {
14745                    pw.print("Proc{");
14746                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14747                    pw.println("}");
14748                } else if (r.adjSource != null) {
14749                    pw.println(r.adjSource.toString());
14750                } else {
14751                    pw.println("{null}");
14752                }
14753            }
14754            if (inclDetails) {
14755                pw.print(prefix);
14756                pw.print("    ");
14757                pw.print("oom: max="); pw.print(r.maxAdj);
14758                pw.print(" curRaw="); pw.print(r.curRawAdj);
14759                pw.print(" setRaw="); pw.print(r.setRawAdj);
14760                pw.print(" cur="); pw.print(r.curAdj);
14761                pw.print(" set="); pw.println(r.setAdj);
14762                pw.print(prefix);
14763                pw.print("    ");
14764                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14765                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14766                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14767                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14768                pw.println();
14769                pw.print(prefix);
14770                pw.print("    ");
14771                pw.print("cached="); pw.print(r.cached);
14772                pw.print(" empty="); pw.print(r.empty);
14773                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14774
14775                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14776                    if (r.lastWakeTime != 0) {
14777                        long wtime;
14778                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14779                        synchronized (stats) {
14780                            wtime = stats.getProcessWakeTime(r.info.uid,
14781                                    r.pid, curRealtime);
14782                        }
14783                        long timeUsed = wtime - r.lastWakeTime;
14784                        pw.print(prefix);
14785                        pw.print("    ");
14786                        pw.print("keep awake over ");
14787                        TimeUtils.formatDuration(realtimeSince, pw);
14788                        pw.print(" used ");
14789                        TimeUtils.formatDuration(timeUsed, pw);
14790                        pw.print(" (");
14791                        pw.print((timeUsed*100)/realtimeSince);
14792                        pw.println("%)");
14793                    }
14794                    if (r.lastCpuTime != 0) {
14795                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14796                        pw.print(prefix);
14797                        pw.print("    ");
14798                        pw.print("run cpu over ");
14799                        TimeUtils.formatDuration(uptimeSince, pw);
14800                        pw.print(" used ");
14801                        TimeUtils.formatDuration(timeUsed, pw);
14802                        pw.print(" (");
14803                        pw.print((timeUsed*100)/uptimeSince);
14804                        pw.println("%)");
14805                    }
14806                }
14807            }
14808        }
14809        return true;
14810    }
14811
14812    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14813            String[] args) {
14814        ArrayList<ProcessRecord> procs;
14815        synchronized (this) {
14816            if (args != null && args.length > start
14817                    && args[start].charAt(0) != '-') {
14818                procs = new ArrayList<ProcessRecord>();
14819                int pid = -1;
14820                try {
14821                    pid = Integer.parseInt(args[start]);
14822                } catch (NumberFormatException e) {
14823                }
14824                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14825                    ProcessRecord proc = mLruProcesses.get(i);
14826                    if (proc.pid == pid) {
14827                        procs.add(proc);
14828                    } else if (allPkgs && proc.pkgList != null
14829                            && proc.pkgList.containsKey(args[start])) {
14830                        procs.add(proc);
14831                    } else if (proc.processName.equals(args[start])) {
14832                        procs.add(proc);
14833                    }
14834                }
14835                if (procs.size() <= 0) {
14836                    return null;
14837                }
14838            } else {
14839                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14840            }
14841        }
14842        return procs;
14843    }
14844
14845    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14846            PrintWriter pw, String[] args) {
14847        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14848        if (procs == null) {
14849            pw.println("No process found for: " + args[0]);
14850            return;
14851        }
14852
14853        long uptime = SystemClock.uptimeMillis();
14854        long realtime = SystemClock.elapsedRealtime();
14855        pw.println("Applications Graphics Acceleration Info:");
14856        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14857
14858        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14859            ProcessRecord r = procs.get(i);
14860            if (r.thread != null) {
14861                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14862                pw.flush();
14863                try {
14864                    TransferPipe tp = new TransferPipe();
14865                    try {
14866                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14867                        tp.go(fd);
14868                    } finally {
14869                        tp.kill();
14870                    }
14871                } catch (IOException e) {
14872                    pw.println("Failure while dumping the app: " + r);
14873                    pw.flush();
14874                } catch (RemoteException e) {
14875                    pw.println("Got a RemoteException while dumping the app " + r);
14876                    pw.flush();
14877                }
14878            }
14879        }
14880    }
14881
14882    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14883        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14884        if (procs == null) {
14885            pw.println("No process found for: " + args[0]);
14886            return;
14887        }
14888
14889        pw.println("Applications Database Info:");
14890
14891        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14892            ProcessRecord r = procs.get(i);
14893            if (r.thread != null) {
14894                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14895                pw.flush();
14896                try {
14897                    TransferPipe tp = new TransferPipe();
14898                    try {
14899                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14900                        tp.go(fd);
14901                    } finally {
14902                        tp.kill();
14903                    }
14904                } catch (IOException e) {
14905                    pw.println("Failure while dumping the app: " + r);
14906                    pw.flush();
14907                } catch (RemoteException e) {
14908                    pw.println("Got a RemoteException while dumping the app " + r);
14909                    pw.flush();
14910                }
14911            }
14912        }
14913    }
14914
14915    final static class MemItem {
14916        final boolean isProc;
14917        final String label;
14918        final String shortLabel;
14919        final long pss;
14920        final int id;
14921        final boolean hasActivities;
14922        ArrayList<MemItem> subitems;
14923
14924        public MemItem(String _label, String _shortLabel, long _pss, int _id,
14925                boolean _hasActivities) {
14926            isProc = true;
14927            label = _label;
14928            shortLabel = _shortLabel;
14929            pss = _pss;
14930            id = _id;
14931            hasActivities = _hasActivities;
14932        }
14933
14934        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14935            isProc = false;
14936            label = _label;
14937            shortLabel = _shortLabel;
14938            pss = _pss;
14939            id = _id;
14940            hasActivities = false;
14941        }
14942    }
14943
14944    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14945            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14946        if (sort && !isCompact) {
14947            Collections.sort(items, new Comparator<MemItem>() {
14948                @Override
14949                public int compare(MemItem lhs, MemItem rhs) {
14950                    if (lhs.pss < rhs.pss) {
14951                        return 1;
14952                    } else if (lhs.pss > rhs.pss) {
14953                        return -1;
14954                    }
14955                    return 0;
14956                }
14957            });
14958        }
14959
14960        for (int i=0; i<items.size(); i++) {
14961            MemItem mi = items.get(i);
14962            if (!isCompact) {
14963                pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
14964            } else if (mi.isProc) {
14965                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14966                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14967                pw.println(mi.hasActivities ? ",a" : ",e");
14968            } else {
14969                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14970                pw.println(mi.pss);
14971            }
14972            if (mi.subitems != null) {
14973                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14974                        true, isCompact);
14975            }
14976        }
14977    }
14978
14979    // These are in KB.
14980    static final long[] DUMP_MEM_BUCKETS = new long[] {
14981        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14982        120*1024, 160*1024, 200*1024,
14983        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14984        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14985    };
14986
14987    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14988            boolean stackLike) {
14989        int start = label.lastIndexOf('.');
14990        if (start >= 0) start++;
14991        else start = 0;
14992        int end = label.length();
14993        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14994            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14995                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14996                out.append(bucket);
14997                out.append(stackLike ? "MB." : "MB ");
14998                out.append(label, start, end);
14999                return;
15000            }
15001        }
15002        out.append(memKB/1024);
15003        out.append(stackLike ? "MB." : "MB ");
15004        out.append(label, start, end);
15005    }
15006
15007    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15008            ProcessList.NATIVE_ADJ,
15009            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15010            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15011            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15012            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15013            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15014            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15015    };
15016    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15017            "Native",
15018            "System", "Persistent", "Persistent Service", "Foreground",
15019            "Visible", "Perceptible",
15020            "Heavy Weight", "Backup",
15021            "A Services", "Home",
15022            "Previous", "B Services", "Cached"
15023    };
15024    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15025            "native",
15026            "sys", "pers", "persvc", "fore",
15027            "vis", "percept",
15028            "heavy", "backup",
15029            "servicea", "home",
15030            "prev", "serviceb", "cached"
15031    };
15032
15033    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15034            long realtime, boolean isCheckinRequest, boolean isCompact) {
15035        if (isCheckinRequest || isCompact) {
15036            // short checkin version
15037            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15038        } else {
15039            pw.println("Applications Memory Usage (in Kilobytes):");
15040            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15041        }
15042    }
15043
15044    private static final int KSM_SHARED = 0;
15045    private static final int KSM_SHARING = 1;
15046    private static final int KSM_UNSHARED = 2;
15047    private static final int KSM_VOLATILE = 3;
15048
15049    private final long[] getKsmInfo() {
15050        long[] longOut = new long[4];
15051        final int[] SINGLE_LONG_FORMAT = new int[] {
15052            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15053        };
15054        long[] longTmp = new long[1];
15055        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15056                SINGLE_LONG_FORMAT, null, longTmp, null);
15057        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15058        longTmp[0] = 0;
15059        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15060                SINGLE_LONG_FORMAT, null, longTmp, null);
15061        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15062        longTmp[0] = 0;
15063        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15064                SINGLE_LONG_FORMAT, null, longTmp, null);
15065        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15066        longTmp[0] = 0;
15067        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15068                SINGLE_LONG_FORMAT, null, longTmp, null);
15069        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15070        return longOut;
15071    }
15072
15073    private static String stringifySize(long size, int order) {
15074        Locale locale = Locale.US;
15075        switch (order) {
15076            case 1:
15077                return String.format(locale, "%,13d", size);
15078            case 1024:
15079                return String.format(locale, "%,9dK", size / 1024);
15080            case 1024 * 1024:
15081                return String.format(locale, "%,5dM", size / 1024 / 1024);
15082            case 1024 * 1024 * 1024:
15083                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15084            default:
15085                throw new IllegalArgumentException("Invalid size order");
15086        }
15087    }
15088
15089    private static String stringifyKBSize(long size) {
15090        return stringifySize(size * 1024, 1024);
15091    }
15092
15093    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15094            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15095        boolean dumpDetails = false;
15096        boolean dumpFullDetails = false;
15097        boolean dumpDalvik = false;
15098        boolean dumpSummaryOnly = false;
15099        boolean oomOnly = false;
15100        boolean isCompact = false;
15101        boolean localOnly = false;
15102        boolean packages = false;
15103
15104        int opti = 0;
15105        while (opti < args.length) {
15106            String opt = args[opti];
15107            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15108                break;
15109            }
15110            opti++;
15111            if ("-a".equals(opt)) {
15112                dumpDetails = true;
15113                dumpFullDetails = true;
15114                dumpDalvik = true;
15115            } else if ("-d".equals(opt)) {
15116                dumpDalvik = true;
15117            } else if ("-c".equals(opt)) {
15118                isCompact = true;
15119            } else if ("-s".equals(opt)) {
15120                dumpDetails = true;
15121                dumpSummaryOnly = true;
15122            } else if ("--oom".equals(opt)) {
15123                oomOnly = true;
15124            } else if ("--local".equals(opt)) {
15125                localOnly = true;
15126            } else if ("--package".equals(opt)) {
15127                packages = true;
15128            } else if ("-h".equals(opt)) {
15129                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15130                pw.println("  -a: include all available information for each process.");
15131                pw.println("  -d: include dalvik details.");
15132                pw.println("  -c: dump in a compact machine-parseable representation.");
15133                pw.println("  -s: dump only summary of application memory usage.");
15134                pw.println("  --oom: only show processes organized by oom adj.");
15135                pw.println("  --local: only collect details locally, don't call process.");
15136                pw.println("  --package: interpret process arg as package, dumping all");
15137                pw.println("             processes that have loaded that package.");
15138                pw.println("If [process] is specified it can be the name or ");
15139                pw.println("pid of a specific process to dump.");
15140                return;
15141            } else {
15142                pw.println("Unknown argument: " + opt + "; use -h for help");
15143            }
15144        }
15145
15146        final boolean isCheckinRequest = scanArgs(args, "--checkin");
15147        long uptime = SystemClock.uptimeMillis();
15148        long realtime = SystemClock.elapsedRealtime();
15149        final long[] tmpLong = new long[1];
15150
15151        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15152        if (procs == null) {
15153            // No Java processes.  Maybe they want to print a native process.
15154            if (args != null && args.length > opti
15155                    && args[opti].charAt(0) != '-') {
15156                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15157                        = new ArrayList<ProcessCpuTracker.Stats>();
15158                updateCpuStatsNow();
15159                int findPid = -1;
15160                try {
15161                    findPid = Integer.parseInt(args[opti]);
15162                } catch (NumberFormatException e) {
15163                }
15164                synchronized (mProcessCpuTracker) {
15165                    final int N = mProcessCpuTracker.countStats();
15166                    for (int i=0; i<N; i++) {
15167                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15168                        if (st.pid == findPid || (st.baseName != null
15169                                && st.baseName.equals(args[opti]))) {
15170                            nativeProcs.add(st);
15171                        }
15172                    }
15173                }
15174                if (nativeProcs.size() > 0) {
15175                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15176                            isCompact);
15177                    Debug.MemoryInfo mi = null;
15178                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15179                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15180                        final int pid = r.pid;
15181                        if (!isCheckinRequest && dumpDetails) {
15182                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15183                        }
15184                        if (mi == null) {
15185                            mi = new Debug.MemoryInfo();
15186                        }
15187                        if (dumpDetails || (!brief && !oomOnly)) {
15188                            Debug.getMemoryInfo(pid, mi);
15189                        } else {
15190                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15191                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15192                        }
15193                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15194                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15195                        if (isCheckinRequest) {
15196                            pw.println();
15197                        }
15198                    }
15199                    return;
15200                }
15201            }
15202            pw.println("No process found for: " + args[opti]);
15203            return;
15204        }
15205
15206        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15207            dumpDetails = true;
15208        }
15209
15210        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15211
15212        String[] innerArgs = new String[args.length-opti];
15213        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15214
15215        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15216        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15217        long nativePss = 0;
15218        long dalvikPss = 0;
15219        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15220                EmptyArray.LONG;
15221        long otherPss = 0;
15222        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15223
15224        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15225        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15226                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15227
15228        long totalPss = 0;
15229        long cachedPss = 0;
15230
15231        Debug.MemoryInfo mi = null;
15232        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15233            final ProcessRecord r = procs.get(i);
15234            final IApplicationThread thread;
15235            final int pid;
15236            final int oomAdj;
15237            final boolean hasActivities;
15238            synchronized (this) {
15239                thread = r.thread;
15240                pid = r.pid;
15241                oomAdj = r.getSetAdjWithServices();
15242                hasActivities = r.activities.size() > 0;
15243            }
15244            if (thread != null) {
15245                if (!isCheckinRequest && dumpDetails) {
15246                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15247                }
15248                if (mi == null) {
15249                    mi = new Debug.MemoryInfo();
15250                }
15251                if (dumpDetails || (!brief && !oomOnly)) {
15252                    Debug.getMemoryInfo(pid, mi);
15253                } else {
15254                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15255                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15256                }
15257                if (dumpDetails) {
15258                    if (localOnly) {
15259                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15260                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15261                        if (isCheckinRequest) {
15262                            pw.println();
15263                        }
15264                    } else {
15265                        try {
15266                            pw.flush();
15267                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15268                                    dumpDalvik, dumpSummaryOnly, innerArgs);
15269                        } catch (RemoteException e) {
15270                            if (!isCheckinRequest) {
15271                                pw.println("Got RemoteException!");
15272                                pw.flush();
15273                            }
15274                        }
15275                    }
15276                }
15277
15278                final long myTotalPss = mi.getTotalPss();
15279                final long myTotalUss = mi.getTotalUss();
15280
15281                synchronized (this) {
15282                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15283                        // Record this for posterity if the process has been stable.
15284                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15285                    }
15286                }
15287
15288                if (!isCheckinRequest && mi != null) {
15289                    totalPss += myTotalPss;
15290                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15291                            (hasActivities ? " / activities)" : ")"),
15292                            r.processName, myTotalPss, pid, hasActivities);
15293                    procMems.add(pssItem);
15294                    procMemsMap.put(pid, pssItem);
15295
15296                    nativePss += mi.nativePss;
15297                    dalvikPss += mi.dalvikPss;
15298                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15299                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15300                    }
15301                    otherPss += mi.otherPss;
15302                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15303                        long mem = mi.getOtherPss(j);
15304                        miscPss[j] += mem;
15305                        otherPss -= mem;
15306                    }
15307
15308                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15309                        cachedPss += myTotalPss;
15310                    }
15311
15312                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15313                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
15314                                || oomIndex == (oomPss.length-1)) {
15315                            oomPss[oomIndex] += myTotalPss;
15316                            if (oomProcs[oomIndex] == null) {
15317                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15318                            }
15319                            oomProcs[oomIndex].add(pssItem);
15320                            break;
15321                        }
15322                    }
15323                }
15324            }
15325        }
15326
15327        long nativeProcTotalPss = 0;
15328
15329        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15330            // If we are showing aggregations, also look for native processes to
15331            // include so that our aggregations are more accurate.
15332            updateCpuStatsNow();
15333            mi = null;
15334            synchronized (mProcessCpuTracker) {
15335                final int N = mProcessCpuTracker.countStats();
15336                for (int i=0; i<N; i++) {
15337                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15338                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15339                        if (mi == null) {
15340                            mi = new Debug.MemoryInfo();
15341                        }
15342                        if (!brief && !oomOnly) {
15343                            Debug.getMemoryInfo(st.pid, mi);
15344                        } else {
15345                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15346                            mi.nativePrivateDirty = (int)tmpLong[0];
15347                        }
15348
15349                        final long myTotalPss = mi.getTotalPss();
15350                        totalPss += myTotalPss;
15351                        nativeProcTotalPss += myTotalPss;
15352
15353                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15354                                st.name, myTotalPss, st.pid, false);
15355                        procMems.add(pssItem);
15356
15357                        nativePss += mi.nativePss;
15358                        dalvikPss += mi.dalvikPss;
15359                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15360                            dalvikSubitemPss[j] += mi.getOtherPss(
15361                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
15362                        }
15363                        otherPss += mi.otherPss;
15364                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15365                            long mem = mi.getOtherPss(j);
15366                            miscPss[j] += mem;
15367                            otherPss -= mem;
15368                        }
15369                        oomPss[0] += myTotalPss;
15370                        if (oomProcs[0] == null) {
15371                            oomProcs[0] = new ArrayList<MemItem>();
15372                        }
15373                        oomProcs[0].add(pssItem);
15374                    }
15375                }
15376            }
15377
15378            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15379
15380            catMems.add(new MemItem("Native", "Native", nativePss, -1));
15381            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
15382            if (dalvikSubitemPss.length > 0) {
15383                dalvikItem.subitems = new ArrayList<MemItem>();
15384                for (int j=0; j<dalvikSubitemPss.length; j++) {
15385                    final String name = Debug.MemoryInfo.getOtherLabel(
15386                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15387                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
15388                }
15389            }
15390            catMems.add(dalvikItem);
15391            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
15392            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15393                String label = Debug.MemoryInfo.getOtherLabel(j);
15394                catMems.add(new MemItem(label, label, miscPss[j], j));
15395            }
15396
15397            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15398            for (int j=0; j<oomPss.length; j++) {
15399                if (oomPss[j] != 0) {
15400                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15401                            : DUMP_MEM_OOM_LABEL[j];
15402                    MemItem item = new MemItem(label, label, oomPss[j],
15403                            DUMP_MEM_OOM_ADJ[j]);
15404                    item.subitems = oomProcs[j];
15405                    oomMems.add(item);
15406                }
15407            }
15408
15409            if (!brief && !oomOnly && !isCompact) {
15410                pw.println();
15411                pw.println("Total PSS by process:");
15412                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
15413                pw.println();
15414            }
15415            if (!isCompact) {
15416                pw.println("Total PSS by OOM adjustment:");
15417            }
15418            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
15419            if (!brief && !oomOnly) {
15420                PrintWriter out = categoryPw != null ? categoryPw : pw;
15421                if (!isCompact) {
15422                    out.println();
15423                    out.println("Total PSS by category:");
15424                }
15425                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
15426            }
15427            if (!isCompact) {
15428                pw.println();
15429            }
15430            MemInfoReader memInfo = new MemInfoReader();
15431            memInfo.readMemInfo();
15432            if (nativeProcTotalPss > 0) {
15433                synchronized (this) {
15434                    final long cachedKb = memInfo.getCachedSizeKb();
15435                    final long freeKb = memInfo.getFreeSizeKb();
15436                    final long zramKb = memInfo.getZramTotalSizeKb();
15437                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15438                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15439                            kernelKb*1024, nativeProcTotalPss*1024);
15440                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15441                            nativeProcTotalPss);
15442                }
15443            }
15444            if (!brief) {
15445                if (!isCompact) {
15446                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15447                    pw.print(" (status ");
15448                    switch (mLastMemoryLevel) {
15449                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15450                            pw.println("normal)");
15451                            break;
15452                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15453                            pw.println("moderate)");
15454                            break;
15455                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15456                            pw.println("low)");
15457                            break;
15458                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15459                            pw.println("critical)");
15460                            break;
15461                        default:
15462                            pw.print(mLastMemoryLevel);
15463                            pw.println(")");
15464                            break;
15465                    }
15466                    pw.print(" Free RAM: ");
15467                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15468                            + memInfo.getFreeSizeKb()));
15469                    pw.print(" (");
15470                    pw.print(stringifyKBSize(cachedPss));
15471                    pw.print(" cached pss + ");
15472                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15473                    pw.print(" cached kernel + ");
15474                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15475                    pw.println(" free)");
15476                } else {
15477                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15478                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15479                            + memInfo.getFreeSizeKb()); pw.print(",");
15480                    pw.println(totalPss - cachedPss);
15481                }
15482            }
15483            if (!isCompact) {
15484                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15485                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15486                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15487                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15488                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(memInfo.getTotalSizeKb()
15489                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15490                        - memInfo.getKernelUsedSizeKb()));
15491            } else {
15492                pw.print("lostram,"); pw.println(memInfo.getTotalSizeKb()
15493                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15494                        - memInfo.getKernelUsedSizeKb());
15495            }
15496            if (!brief) {
15497                if (memInfo.getZramTotalSizeKb() != 0) {
15498                    if (!isCompact) {
15499                        pw.print("     ZRAM: ");
15500                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15501                                pw.print(" physical used for ");
15502                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15503                                        - memInfo.getSwapFreeSizeKb()));
15504                                pw.print(" in swap (");
15505                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15506                                pw.println(" total swap)");
15507                    } else {
15508                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15509                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15510                                pw.println(memInfo.getSwapFreeSizeKb());
15511                    }
15512                }
15513                final long[] ksm = getKsmInfo();
15514                if (!isCompact) {
15515                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15516                            || ksm[KSM_VOLATILE] != 0) {
15517                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15518                                pw.print(" saved from shared ");
15519                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15520                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15521                                pw.print(" unshared; ");
15522                                pw.print(stringifyKBSize(
15523                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15524                    }
15525                    pw.print("   Tuning: ");
15526                    pw.print(ActivityManager.staticGetMemoryClass());
15527                    pw.print(" (large ");
15528                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15529                    pw.print("), oom ");
15530                    pw.print(stringifySize(
15531                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15532                    pw.print(", restore limit ");
15533                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15534                    if (ActivityManager.isLowRamDeviceStatic()) {
15535                        pw.print(" (low-ram)");
15536                    }
15537                    if (ActivityManager.isHighEndGfx()) {
15538                        pw.print(" (high-end-gfx)");
15539                    }
15540                    pw.println();
15541                } else {
15542                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15543                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15544                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15545                    pw.print("tuning,");
15546                    pw.print(ActivityManager.staticGetMemoryClass());
15547                    pw.print(',');
15548                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15549                    pw.print(',');
15550                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15551                    if (ActivityManager.isLowRamDeviceStatic()) {
15552                        pw.print(",low-ram");
15553                    }
15554                    if (ActivityManager.isHighEndGfx()) {
15555                        pw.print(",high-end-gfx");
15556                    }
15557                    pw.println();
15558                }
15559            }
15560        }
15561    }
15562
15563    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15564            long memtrack, String name) {
15565        sb.append("  ");
15566        sb.append(ProcessList.makeOomAdjString(oomAdj));
15567        sb.append(' ');
15568        sb.append(ProcessList.makeProcStateString(procState));
15569        sb.append(' ');
15570        ProcessList.appendRamKb(sb, pss);
15571        sb.append(": ");
15572        sb.append(name);
15573        if (memtrack > 0) {
15574            sb.append(" (");
15575            sb.append(stringifyKBSize(memtrack));
15576            sb.append(" memtrack)");
15577        }
15578    }
15579
15580    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15581        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15582        sb.append(" (pid ");
15583        sb.append(mi.pid);
15584        sb.append(") ");
15585        sb.append(mi.adjType);
15586        sb.append('\n');
15587        if (mi.adjReason != null) {
15588            sb.append("                      ");
15589            sb.append(mi.adjReason);
15590            sb.append('\n');
15591        }
15592    }
15593
15594    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15595        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15596        for (int i=0, N=memInfos.size(); i<N; i++) {
15597            ProcessMemInfo mi = memInfos.get(i);
15598            infoMap.put(mi.pid, mi);
15599        }
15600        updateCpuStatsNow();
15601        long[] memtrackTmp = new long[1];
15602        synchronized (mProcessCpuTracker) {
15603            final int N = mProcessCpuTracker.countStats();
15604            for (int i=0; i<N; i++) {
15605                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15606                if (st.vsize > 0) {
15607                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15608                    if (pss > 0) {
15609                        if (infoMap.indexOfKey(st.pid) < 0) {
15610                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15611                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15612                            mi.pss = pss;
15613                            mi.memtrack = memtrackTmp[0];
15614                            memInfos.add(mi);
15615                        }
15616                    }
15617                }
15618            }
15619        }
15620
15621        long totalPss = 0;
15622        long totalMemtrack = 0;
15623        for (int i=0, N=memInfos.size(); i<N; i++) {
15624            ProcessMemInfo mi = memInfos.get(i);
15625            if (mi.pss == 0) {
15626                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15627                mi.memtrack = memtrackTmp[0];
15628            }
15629            totalPss += mi.pss;
15630            totalMemtrack += mi.memtrack;
15631        }
15632        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15633            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15634                if (lhs.oomAdj != rhs.oomAdj) {
15635                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15636                }
15637                if (lhs.pss != rhs.pss) {
15638                    return lhs.pss < rhs.pss ? 1 : -1;
15639                }
15640                return 0;
15641            }
15642        });
15643
15644        StringBuilder tag = new StringBuilder(128);
15645        StringBuilder stack = new StringBuilder(128);
15646        tag.append("Low on memory -- ");
15647        appendMemBucket(tag, totalPss, "total", false);
15648        appendMemBucket(stack, totalPss, "total", true);
15649
15650        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15651        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15652        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15653
15654        boolean firstLine = true;
15655        int lastOomAdj = Integer.MIN_VALUE;
15656        long extraNativeRam = 0;
15657        long extraNativeMemtrack = 0;
15658        long cachedPss = 0;
15659        for (int i=0, N=memInfos.size(); i<N; i++) {
15660            ProcessMemInfo mi = memInfos.get(i);
15661
15662            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15663                cachedPss += mi.pss;
15664            }
15665
15666            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15667                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15668                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15669                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15670                if (lastOomAdj != mi.oomAdj) {
15671                    lastOomAdj = mi.oomAdj;
15672                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15673                        tag.append(" / ");
15674                    }
15675                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15676                        if (firstLine) {
15677                            stack.append(":");
15678                            firstLine = false;
15679                        }
15680                        stack.append("\n\t at ");
15681                    } else {
15682                        stack.append("$");
15683                    }
15684                } else {
15685                    tag.append(" ");
15686                    stack.append("$");
15687                }
15688                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15689                    appendMemBucket(tag, mi.pss, mi.name, false);
15690                }
15691                appendMemBucket(stack, mi.pss, mi.name, true);
15692                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15693                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15694                    stack.append("(");
15695                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15696                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15697                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15698                            stack.append(":");
15699                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15700                        }
15701                    }
15702                    stack.append(")");
15703                }
15704            }
15705
15706            appendMemInfo(fullNativeBuilder, mi);
15707            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15708                // The short form only has native processes that are >= 512K.
15709                if (mi.pss >= 512) {
15710                    appendMemInfo(shortNativeBuilder, mi);
15711                } else {
15712                    extraNativeRam += mi.pss;
15713                    extraNativeMemtrack += mi.memtrack;
15714                }
15715            } else {
15716                // Short form has all other details, but if we have collected RAM
15717                // from smaller native processes let's dump a summary of that.
15718                if (extraNativeRam > 0) {
15719                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15720                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15721                    shortNativeBuilder.append('\n');
15722                    extraNativeRam = 0;
15723                }
15724                appendMemInfo(fullJavaBuilder, mi);
15725            }
15726        }
15727
15728        fullJavaBuilder.append("           ");
15729        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15730        fullJavaBuilder.append(": TOTAL");
15731        if (totalMemtrack > 0) {
15732            fullJavaBuilder.append(" (");
15733            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15734            fullJavaBuilder.append(" memtrack)");
15735        } else {
15736        }
15737        fullJavaBuilder.append("\n");
15738
15739        MemInfoReader memInfo = new MemInfoReader();
15740        memInfo.readMemInfo();
15741        final long[] infos = memInfo.getRawInfo();
15742
15743        StringBuilder memInfoBuilder = new StringBuilder(1024);
15744        Debug.getMemInfo(infos);
15745        memInfoBuilder.append("  MemInfo: ");
15746        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15747        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15748        memInfoBuilder.append(stringifyKBSize(
15749                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15750        memInfoBuilder.append(stringifyKBSize(
15751                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15752        memInfoBuilder.append(stringifyKBSize(
15753                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
15754        memInfoBuilder.append("           ");
15755        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
15756        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
15757        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
15758        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
15759        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15760            memInfoBuilder.append("  ZRAM: ");
15761            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
15762            memInfoBuilder.append(" RAM, ");
15763            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
15764            memInfoBuilder.append(" swap total, ");
15765            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
15766            memInfoBuilder.append(" swap free\n");
15767        }
15768        final long[] ksm = getKsmInfo();
15769        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15770                || ksm[KSM_VOLATILE] != 0) {
15771            memInfoBuilder.append("  KSM: ");
15772            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
15773            memInfoBuilder.append(" saved from shared ");
15774            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
15775            memInfoBuilder.append("\n       ");
15776            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
15777            memInfoBuilder.append(" unshared; ");
15778            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
15779            memInfoBuilder.append(" volatile\n");
15780        }
15781        memInfoBuilder.append("  Free RAM: ");
15782        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15783                + memInfo.getFreeSizeKb()));
15784        memInfoBuilder.append("\n");
15785        memInfoBuilder.append("  Used RAM: ");
15786        memInfoBuilder.append(stringifyKBSize(
15787                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
15788        memInfoBuilder.append("\n");
15789        memInfoBuilder.append("  Lost RAM: ");
15790        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
15791                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15792                - memInfo.getKernelUsedSizeKb()));
15793        memInfoBuilder.append("\n");
15794        Slog.i(TAG, "Low on memory:");
15795        Slog.i(TAG, shortNativeBuilder.toString());
15796        Slog.i(TAG, fullJavaBuilder.toString());
15797        Slog.i(TAG, memInfoBuilder.toString());
15798
15799        StringBuilder dropBuilder = new StringBuilder(1024);
15800        /*
15801        StringWriter oomSw = new StringWriter();
15802        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15803        StringWriter catSw = new StringWriter();
15804        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15805        String[] emptyArgs = new String[] { };
15806        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15807        oomPw.flush();
15808        String oomString = oomSw.toString();
15809        */
15810        dropBuilder.append("Low on memory:");
15811        dropBuilder.append(stack);
15812        dropBuilder.append('\n');
15813        dropBuilder.append(fullNativeBuilder);
15814        dropBuilder.append(fullJavaBuilder);
15815        dropBuilder.append('\n');
15816        dropBuilder.append(memInfoBuilder);
15817        dropBuilder.append('\n');
15818        /*
15819        dropBuilder.append(oomString);
15820        dropBuilder.append('\n');
15821        */
15822        StringWriter catSw = new StringWriter();
15823        synchronized (ActivityManagerService.this) {
15824            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15825            String[] emptyArgs = new String[] { };
15826            catPw.println();
15827            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15828            catPw.println();
15829            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15830                    false, false, null);
15831            catPw.println();
15832            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15833            catPw.flush();
15834        }
15835        dropBuilder.append(catSw.toString());
15836        addErrorToDropBox("lowmem", null, "system_server", null,
15837                null, tag.toString(), dropBuilder.toString(), null, null);
15838        //Slog.i(TAG, "Sent to dropbox:");
15839        //Slog.i(TAG, dropBuilder.toString());
15840        synchronized (ActivityManagerService.this) {
15841            long now = SystemClock.uptimeMillis();
15842            if (mLastMemUsageReportTime < now) {
15843                mLastMemUsageReportTime = now;
15844            }
15845        }
15846    }
15847
15848    /**
15849     * Searches array of arguments for the specified string
15850     * @param args array of argument strings
15851     * @param value value to search for
15852     * @return true if the value is contained in the array
15853     */
15854    private static boolean scanArgs(String[] args, String value) {
15855        if (args != null) {
15856            for (String arg : args) {
15857                if (value.equals(arg)) {
15858                    return true;
15859                }
15860            }
15861        }
15862        return false;
15863    }
15864
15865    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15866            ContentProviderRecord cpr, boolean always) {
15867        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15868
15869        if (!inLaunching || always) {
15870            synchronized (cpr) {
15871                cpr.launchingApp = null;
15872                cpr.notifyAll();
15873            }
15874            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15875            String names[] = cpr.info.authority.split(";");
15876            for (int j = 0; j < names.length; j++) {
15877                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15878            }
15879        }
15880
15881        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15882            ContentProviderConnection conn = cpr.connections.get(i);
15883            if (conn.waiting) {
15884                // If this connection is waiting for the provider, then we don't
15885                // need to mess with its process unless we are always removing
15886                // or for some reason the provider is not currently launching.
15887                if (inLaunching && !always) {
15888                    continue;
15889                }
15890            }
15891            ProcessRecord capp = conn.client;
15892            conn.dead = true;
15893            if (conn.stableCount > 0) {
15894                if (!capp.persistent && capp.thread != null
15895                        && capp.pid != 0
15896                        && capp.pid != MY_PID) {
15897                    capp.kill("depends on provider "
15898                            + cpr.name.flattenToShortString()
15899                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15900                }
15901            } else if (capp.thread != null && conn.provider.provider != null) {
15902                try {
15903                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15904                } catch (RemoteException e) {
15905                }
15906                // In the protocol here, we don't expect the client to correctly
15907                // clean up this connection, we'll just remove it.
15908                cpr.connections.remove(i);
15909                if (conn.client.conProviders.remove(conn)) {
15910                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15911                }
15912            }
15913        }
15914
15915        if (inLaunching && always) {
15916            mLaunchingProviders.remove(cpr);
15917        }
15918        return inLaunching;
15919    }
15920
15921    /**
15922     * Main code for cleaning up a process when it has gone away.  This is
15923     * called both as a result of the process dying, or directly when stopping
15924     * a process when running in single process mode.
15925     *
15926     * @return Returns true if the given process has been restarted, so the
15927     * app that was passed in must remain on the process lists.
15928     */
15929    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15930            boolean restarting, boolean allowRestart, int index) {
15931        if (index >= 0) {
15932            removeLruProcessLocked(app);
15933            ProcessList.remove(app.pid);
15934        }
15935
15936        mProcessesToGc.remove(app);
15937        mPendingPssProcesses.remove(app);
15938
15939        // Dismiss any open dialogs.
15940        if (app.crashDialog != null && !app.forceCrashReport) {
15941            app.crashDialog.dismiss();
15942            app.crashDialog = null;
15943        }
15944        if (app.anrDialog != null) {
15945            app.anrDialog.dismiss();
15946            app.anrDialog = null;
15947        }
15948        if (app.waitDialog != null) {
15949            app.waitDialog.dismiss();
15950            app.waitDialog = null;
15951        }
15952
15953        app.crashing = false;
15954        app.notResponding = false;
15955
15956        app.resetPackageList(mProcessStats);
15957        app.unlinkDeathRecipient();
15958        app.makeInactive(mProcessStats);
15959        app.waitingToKill = null;
15960        app.forcingToForeground = null;
15961        updateProcessForegroundLocked(app, false, false);
15962        app.foregroundActivities = false;
15963        app.hasShownUi = false;
15964        app.treatLikeActivity = false;
15965        app.hasAboveClient = false;
15966        app.hasClientActivities = false;
15967
15968        mServices.killServicesLocked(app, allowRestart);
15969
15970        boolean restart = false;
15971
15972        // Remove published content providers.
15973        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15974            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15975            final boolean always = app.bad || !allowRestart;
15976            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15977            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15978                // We left the provider in the launching list, need to
15979                // restart it.
15980                restart = true;
15981            }
15982
15983            cpr.provider = null;
15984            cpr.proc = null;
15985        }
15986        app.pubProviders.clear();
15987
15988        // Take care of any launching providers waiting for this process.
15989        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
15990            restart = true;
15991        }
15992
15993        // Unregister from connected content providers.
15994        if (!app.conProviders.isEmpty()) {
15995            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15996                ContentProviderConnection conn = app.conProviders.get(i);
15997                conn.provider.connections.remove(conn);
15998                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15999                        conn.provider.name);
16000            }
16001            app.conProviders.clear();
16002        }
16003
16004        // At this point there may be remaining entries in mLaunchingProviders
16005        // where we were the only one waiting, so they are no longer of use.
16006        // Look for these and clean up if found.
16007        // XXX Commented out for now.  Trying to figure out a way to reproduce
16008        // the actual situation to identify what is actually going on.
16009        if (false) {
16010            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16011                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16012                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16013                    synchronized (cpr) {
16014                        cpr.launchingApp = null;
16015                        cpr.notifyAll();
16016                    }
16017                }
16018            }
16019        }
16020
16021        skipCurrentReceiverLocked(app);
16022
16023        // Unregister any receivers.
16024        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16025            removeReceiverLocked(app.receivers.valueAt(i));
16026        }
16027        app.receivers.clear();
16028
16029        // If the app is undergoing backup, tell the backup manager about it
16030        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16031            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16032                    + mBackupTarget.appInfo + " died during backup");
16033            try {
16034                IBackupManager bm = IBackupManager.Stub.asInterface(
16035                        ServiceManager.getService(Context.BACKUP_SERVICE));
16036                bm.agentDisconnected(app.info.packageName);
16037            } catch (RemoteException e) {
16038                // can't happen; backup manager is local
16039            }
16040        }
16041
16042        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16043            ProcessChangeItem item = mPendingProcessChanges.get(i);
16044            if (item.pid == app.pid) {
16045                mPendingProcessChanges.remove(i);
16046                mAvailProcessChanges.add(item);
16047            }
16048        }
16049        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16050                null).sendToTarget();
16051
16052        // If the caller is restarting this app, then leave it in its
16053        // current lists and let the caller take care of it.
16054        if (restarting) {
16055            return false;
16056        }
16057
16058        if (!app.persistent || app.isolated) {
16059            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16060                    "Removing non-persistent process during cleanup: " + app);
16061            removeProcessNameLocked(app.processName, app.uid);
16062            if (mHeavyWeightProcess == app) {
16063                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16064                        mHeavyWeightProcess.userId, 0));
16065                mHeavyWeightProcess = null;
16066            }
16067        } else if (!app.removed) {
16068            // This app is persistent, so we need to keep its record around.
16069            // If it is not already on the pending app list, add it there
16070            // and start a new process for it.
16071            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16072                mPersistentStartingProcesses.add(app);
16073                restart = true;
16074            }
16075        }
16076        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16077                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16078        mProcessesOnHold.remove(app);
16079
16080        if (app == mHomeProcess) {
16081            mHomeProcess = null;
16082        }
16083        if (app == mPreviousProcess) {
16084            mPreviousProcess = null;
16085        }
16086
16087        if (restart && !app.isolated) {
16088            // We have components that still need to be running in the
16089            // process, so re-launch it.
16090            if (index < 0) {
16091                ProcessList.remove(app.pid);
16092            }
16093            addProcessNameLocked(app);
16094            startProcessLocked(app, "restart", app.processName);
16095            return true;
16096        } else if (app.pid > 0 && app.pid != MY_PID) {
16097            // Goodbye!
16098            boolean removed;
16099            synchronized (mPidsSelfLocked) {
16100                mPidsSelfLocked.remove(app.pid);
16101                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16102            }
16103            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16104            if (app.isolated) {
16105                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16106            }
16107            app.setPid(0);
16108        }
16109        return false;
16110    }
16111
16112    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16113        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16114            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16115            if (cpr.launchingApp == app) {
16116                return true;
16117            }
16118        }
16119        return false;
16120    }
16121
16122    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16123        // Look through the content providers we are waiting to have launched,
16124        // and if any run in this process then either schedule a restart of
16125        // the process or kill the client waiting for it if this process has
16126        // gone bad.
16127        boolean restart = false;
16128        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16129            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16130            if (cpr.launchingApp == app) {
16131                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16132                    restart = true;
16133                } else {
16134                    removeDyingProviderLocked(app, cpr, true);
16135                }
16136            }
16137        }
16138        return restart;
16139    }
16140
16141    // =========================================================
16142    // SERVICES
16143    // =========================================================
16144
16145    @Override
16146    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16147            int flags) {
16148        enforceNotIsolatedCaller("getServices");
16149        synchronized (this) {
16150            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16151        }
16152    }
16153
16154    @Override
16155    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16156        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16157        synchronized (this) {
16158            return mServices.getRunningServiceControlPanelLocked(name);
16159        }
16160    }
16161
16162    @Override
16163    public ComponentName startService(IApplicationThread caller, Intent service,
16164            String resolvedType, String callingPackage, int userId)
16165            throws TransactionTooLargeException {
16166        enforceNotIsolatedCaller("startService");
16167        // Refuse possible leaked file descriptors
16168        if (service != null && service.hasFileDescriptors() == true) {
16169            throw new IllegalArgumentException("File descriptors passed in Intent");
16170        }
16171
16172        if (callingPackage == null) {
16173            throw new IllegalArgumentException("callingPackage cannot be null");
16174        }
16175
16176        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16177                "startService: " + service + " type=" + resolvedType);
16178        synchronized(this) {
16179            final int callingPid = Binder.getCallingPid();
16180            final int callingUid = Binder.getCallingUid();
16181            final long origId = Binder.clearCallingIdentity();
16182            ComponentName res = mServices.startServiceLocked(caller, service,
16183                    resolvedType, callingPid, callingUid, callingPackage, userId);
16184            Binder.restoreCallingIdentity(origId);
16185            return res;
16186        }
16187    }
16188
16189    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16190            String callingPackage, int userId)
16191            throws TransactionTooLargeException {
16192        synchronized(this) {
16193            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16194                    "startServiceInPackage: " + service + " type=" + resolvedType);
16195            final long origId = Binder.clearCallingIdentity();
16196            ComponentName res = mServices.startServiceLocked(null, service,
16197                    resolvedType, -1, uid, callingPackage, userId);
16198            Binder.restoreCallingIdentity(origId);
16199            return res;
16200        }
16201    }
16202
16203    @Override
16204    public int stopService(IApplicationThread caller, Intent service,
16205            String resolvedType, int userId) {
16206        enforceNotIsolatedCaller("stopService");
16207        // Refuse possible leaked file descriptors
16208        if (service != null && service.hasFileDescriptors() == true) {
16209            throw new IllegalArgumentException("File descriptors passed in Intent");
16210        }
16211
16212        synchronized(this) {
16213            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16214        }
16215    }
16216
16217    @Override
16218    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16219        enforceNotIsolatedCaller("peekService");
16220        // Refuse possible leaked file descriptors
16221        if (service != null && service.hasFileDescriptors() == true) {
16222            throw new IllegalArgumentException("File descriptors passed in Intent");
16223        }
16224
16225        if (callingPackage == null) {
16226            throw new IllegalArgumentException("callingPackage cannot be null");
16227        }
16228
16229        synchronized(this) {
16230            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16231        }
16232    }
16233
16234    @Override
16235    public boolean stopServiceToken(ComponentName className, IBinder token,
16236            int startId) {
16237        synchronized(this) {
16238            return mServices.stopServiceTokenLocked(className, token, startId);
16239        }
16240    }
16241
16242    @Override
16243    public void setServiceForeground(ComponentName className, IBinder token,
16244            int id, Notification notification, boolean removeNotification) {
16245        synchronized(this) {
16246            mServices.setServiceForegroundLocked(className, token, id, notification,
16247                    removeNotification);
16248        }
16249    }
16250
16251    @Override
16252    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16253            boolean requireFull, String name, String callerPackage) {
16254        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16255                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16256    }
16257
16258    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16259            String className, int flags) {
16260        boolean result = false;
16261        // For apps that don't have pre-defined UIDs, check for permission
16262        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16263            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16264                if (ActivityManager.checkUidPermission(
16265                        INTERACT_ACROSS_USERS,
16266                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16267                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16268                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16269                            + " requests FLAG_SINGLE_USER, but app does not hold "
16270                            + INTERACT_ACROSS_USERS;
16271                    Slog.w(TAG, msg);
16272                    throw new SecurityException(msg);
16273                }
16274                // Permission passed
16275                result = true;
16276            }
16277        } else if ("system".equals(componentProcessName)) {
16278            result = true;
16279        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16280            // Phone app and persistent apps are allowed to export singleuser providers.
16281            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16282                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16283        }
16284        if (DEBUG_MU) Slog.v(TAG_MU,
16285                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16286                + Integer.toHexString(flags) + ") = " + result);
16287        return result;
16288    }
16289
16290    /**
16291     * Checks to see if the caller is in the same app as the singleton
16292     * component, or the component is in a special app. It allows special apps
16293     * to export singleton components but prevents exporting singleton
16294     * components for regular apps.
16295     */
16296    boolean isValidSingletonCall(int callingUid, int componentUid) {
16297        int componentAppId = UserHandle.getAppId(componentUid);
16298        return UserHandle.isSameApp(callingUid, componentUid)
16299                || componentAppId == Process.SYSTEM_UID
16300                || componentAppId == Process.PHONE_UID
16301                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16302                        == PackageManager.PERMISSION_GRANTED;
16303    }
16304
16305    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16306            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16307            int userId) throws TransactionTooLargeException {
16308        enforceNotIsolatedCaller("bindService");
16309
16310        // Refuse possible leaked file descriptors
16311        if (service != null && service.hasFileDescriptors() == true) {
16312            throw new IllegalArgumentException("File descriptors passed in Intent");
16313        }
16314
16315        if (callingPackage == null) {
16316            throw new IllegalArgumentException("callingPackage cannot be null");
16317        }
16318
16319        synchronized(this) {
16320            return mServices.bindServiceLocked(caller, token, service,
16321                    resolvedType, connection, flags, callingPackage, userId);
16322        }
16323    }
16324
16325    public boolean unbindService(IServiceConnection connection) {
16326        synchronized (this) {
16327            return mServices.unbindServiceLocked(connection);
16328        }
16329    }
16330
16331    public void publishService(IBinder token, Intent intent, IBinder service) {
16332        // Refuse possible leaked file descriptors
16333        if (intent != null && intent.hasFileDescriptors() == true) {
16334            throw new IllegalArgumentException("File descriptors passed in Intent");
16335        }
16336
16337        synchronized(this) {
16338            if (!(token instanceof ServiceRecord)) {
16339                throw new IllegalArgumentException("Invalid service token");
16340            }
16341            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16342        }
16343    }
16344
16345    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16346        // Refuse possible leaked file descriptors
16347        if (intent != null && intent.hasFileDescriptors() == true) {
16348            throw new IllegalArgumentException("File descriptors passed in Intent");
16349        }
16350
16351        synchronized(this) {
16352            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16353        }
16354    }
16355
16356    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16357        synchronized(this) {
16358            if (!(token instanceof ServiceRecord)) {
16359                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16360                throw new IllegalArgumentException("Invalid service token");
16361            }
16362            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16363        }
16364    }
16365
16366    // =========================================================
16367    // BACKUP AND RESTORE
16368    // =========================================================
16369
16370    // Cause the target app to be launched if necessary and its backup agent
16371    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16372    // activity manager to announce its creation.
16373    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16374        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16375                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16376        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16377
16378        synchronized(this) {
16379            // !!! TODO: currently no check here that we're already bound
16380            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16381            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16382            synchronized (stats) {
16383                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16384            }
16385
16386            // Backup agent is now in use, its package can't be stopped.
16387            try {
16388                AppGlobals.getPackageManager().setPackageStoppedState(
16389                        app.packageName, false, UserHandle.getUserId(app.uid));
16390            } catch (RemoteException e) {
16391            } catch (IllegalArgumentException e) {
16392                Slog.w(TAG, "Failed trying to unstop package "
16393                        + app.packageName + ": " + e);
16394            }
16395
16396            BackupRecord r = new BackupRecord(ss, app, backupMode);
16397            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16398                    ? new ComponentName(app.packageName, app.backupAgentName)
16399                    : new ComponentName("android", "FullBackupAgent");
16400            // startProcessLocked() returns existing proc's record if it's already running
16401            ProcessRecord proc = startProcessLocked(app.processName, app,
16402                    false, 0, "backup", hostingName, false, false, false);
16403            if (proc == null) {
16404                Slog.e(TAG, "Unable to start backup agent process " + r);
16405                return false;
16406            }
16407
16408            r.app = proc;
16409            mBackupTarget = r;
16410            mBackupAppName = app.packageName;
16411
16412            // Try not to kill the process during backup
16413            updateOomAdjLocked(proc);
16414
16415            // If the process is already attached, schedule the creation of the backup agent now.
16416            // If it is not yet live, this will be done when it attaches to the framework.
16417            if (proc.thread != null) {
16418                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16419                try {
16420                    proc.thread.scheduleCreateBackupAgent(app,
16421                            compatibilityInfoForPackageLocked(app), backupMode);
16422                } catch (RemoteException e) {
16423                    // Will time out on the backup manager side
16424                }
16425            } else {
16426                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16427            }
16428            // Invariants: at this point, the target app process exists and the application
16429            // is either already running or in the process of coming up.  mBackupTarget and
16430            // mBackupAppName describe the app, so that when it binds back to the AM we
16431            // know that it's scheduled for a backup-agent operation.
16432        }
16433
16434        return true;
16435    }
16436
16437    @Override
16438    public void clearPendingBackup() {
16439        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16440        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16441
16442        synchronized (this) {
16443            mBackupTarget = null;
16444            mBackupAppName = null;
16445        }
16446    }
16447
16448    // A backup agent has just come up
16449    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16450        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16451                + " = " + agent);
16452
16453        synchronized(this) {
16454            if (!agentPackageName.equals(mBackupAppName)) {
16455                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16456                return;
16457            }
16458        }
16459
16460        long oldIdent = Binder.clearCallingIdentity();
16461        try {
16462            IBackupManager bm = IBackupManager.Stub.asInterface(
16463                    ServiceManager.getService(Context.BACKUP_SERVICE));
16464            bm.agentConnected(agentPackageName, agent);
16465        } catch (RemoteException e) {
16466            // can't happen; the backup manager service is local
16467        } catch (Exception e) {
16468            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16469            e.printStackTrace();
16470        } finally {
16471            Binder.restoreCallingIdentity(oldIdent);
16472        }
16473    }
16474
16475    // done with this agent
16476    public void unbindBackupAgent(ApplicationInfo appInfo) {
16477        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16478        if (appInfo == null) {
16479            Slog.w(TAG, "unbind backup agent for null app");
16480            return;
16481        }
16482
16483        synchronized(this) {
16484            try {
16485                if (mBackupAppName == null) {
16486                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16487                    return;
16488                }
16489
16490                if (!mBackupAppName.equals(appInfo.packageName)) {
16491                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16492                    return;
16493                }
16494
16495                // Not backing this app up any more; reset its OOM adjustment
16496                final ProcessRecord proc = mBackupTarget.app;
16497                updateOomAdjLocked(proc);
16498
16499                // If the app crashed during backup, 'thread' will be null here
16500                if (proc.thread != null) {
16501                    try {
16502                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16503                                compatibilityInfoForPackageLocked(appInfo));
16504                    } catch (Exception e) {
16505                        Slog.e(TAG, "Exception when unbinding backup agent:");
16506                        e.printStackTrace();
16507                    }
16508                }
16509            } finally {
16510                mBackupTarget = null;
16511                mBackupAppName = null;
16512            }
16513        }
16514    }
16515    // =========================================================
16516    // BROADCASTS
16517    // =========================================================
16518
16519    boolean isPendingBroadcastProcessLocked(int pid) {
16520        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16521                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16522    }
16523
16524    void skipPendingBroadcastLocked(int pid) {
16525            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16526            for (BroadcastQueue queue : mBroadcastQueues) {
16527                queue.skipPendingBroadcastLocked(pid);
16528            }
16529    }
16530
16531    // The app just attached; send any pending broadcasts that it should receive
16532    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16533        boolean didSomething = false;
16534        for (BroadcastQueue queue : mBroadcastQueues) {
16535            didSomething |= queue.sendPendingBroadcastsLocked(app);
16536        }
16537        return didSomething;
16538    }
16539
16540    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16541            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16542        enforceNotIsolatedCaller("registerReceiver");
16543        ArrayList<Intent> stickyIntents = null;
16544        ProcessRecord callerApp = null;
16545        int callingUid;
16546        int callingPid;
16547        synchronized(this) {
16548            if (caller != null) {
16549                callerApp = getRecordForAppLocked(caller);
16550                if (callerApp == null) {
16551                    throw new SecurityException(
16552                            "Unable to find app for caller " + caller
16553                            + " (pid=" + Binder.getCallingPid()
16554                            + ") when registering receiver " + receiver);
16555                }
16556                if (callerApp.info.uid != Process.SYSTEM_UID &&
16557                        !callerApp.pkgList.containsKey(callerPackage) &&
16558                        !"android".equals(callerPackage)) {
16559                    throw new SecurityException("Given caller package " + callerPackage
16560                            + " is not running in process " + callerApp);
16561                }
16562                callingUid = callerApp.info.uid;
16563                callingPid = callerApp.pid;
16564            } else {
16565                callerPackage = null;
16566                callingUid = Binder.getCallingUid();
16567                callingPid = Binder.getCallingPid();
16568            }
16569
16570            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16571                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16572
16573            Iterator<String> actions = filter.actionsIterator();
16574            if (actions == null) {
16575                ArrayList<String> noAction = new ArrayList<String>(1);
16576                noAction.add(null);
16577                actions = noAction.iterator();
16578            }
16579
16580            // Collect stickies of users
16581            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16582            while (actions.hasNext()) {
16583                String action = actions.next();
16584                for (int id : userIds) {
16585                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16586                    if (stickies != null) {
16587                        ArrayList<Intent> intents = stickies.get(action);
16588                        if (intents != null) {
16589                            if (stickyIntents == null) {
16590                                stickyIntents = new ArrayList<Intent>();
16591                            }
16592                            stickyIntents.addAll(intents);
16593                        }
16594                    }
16595                }
16596            }
16597        }
16598
16599        ArrayList<Intent> allSticky = null;
16600        if (stickyIntents != null) {
16601            final ContentResolver resolver = mContext.getContentResolver();
16602            // Look for any matching sticky broadcasts...
16603            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16604                Intent intent = stickyIntents.get(i);
16605                // If intent has scheme "content", it will need to acccess
16606                // provider that needs to lock mProviderMap in ActivityThread
16607                // and also it may need to wait application response, so we
16608                // cannot lock ActivityManagerService here.
16609                if (filter.match(resolver, intent, true, TAG) >= 0) {
16610                    if (allSticky == null) {
16611                        allSticky = new ArrayList<Intent>();
16612                    }
16613                    allSticky.add(intent);
16614                }
16615            }
16616        }
16617
16618        // The first sticky in the list is returned directly back to the client.
16619        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16620        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16621        if (receiver == null) {
16622            return sticky;
16623        }
16624
16625        synchronized (this) {
16626            if (callerApp != null && (callerApp.thread == null
16627                    || callerApp.thread.asBinder() != caller.asBinder())) {
16628                // Original caller already died
16629                return null;
16630            }
16631            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16632            if (rl == null) {
16633                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16634                        userId, receiver);
16635                if (rl.app != null) {
16636                    rl.app.receivers.add(rl);
16637                } else {
16638                    try {
16639                        receiver.asBinder().linkToDeath(rl, 0);
16640                    } catch (RemoteException e) {
16641                        return sticky;
16642                    }
16643                    rl.linkedToDeath = true;
16644                }
16645                mRegisteredReceivers.put(receiver.asBinder(), rl);
16646            } else if (rl.uid != callingUid) {
16647                throw new IllegalArgumentException(
16648                        "Receiver requested to register for uid " + callingUid
16649                        + " was previously registered for uid " + rl.uid);
16650            } else if (rl.pid != callingPid) {
16651                throw new IllegalArgumentException(
16652                        "Receiver requested to register for pid " + callingPid
16653                        + " was previously registered for pid " + rl.pid);
16654            } else if (rl.userId != userId) {
16655                throw new IllegalArgumentException(
16656                        "Receiver requested to register for user " + userId
16657                        + " was previously registered for user " + rl.userId);
16658            }
16659            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16660                    permission, callingUid, userId);
16661            rl.add(bf);
16662            if (!bf.debugCheck()) {
16663                Slog.w(TAG, "==> For Dynamic broadcast");
16664            }
16665            mReceiverResolver.addFilter(bf);
16666
16667            // Enqueue broadcasts for all existing stickies that match
16668            // this filter.
16669            if (allSticky != null) {
16670                ArrayList receivers = new ArrayList();
16671                receivers.add(bf);
16672
16673                final int stickyCount = allSticky.size();
16674                for (int i = 0; i < stickyCount; i++) {
16675                    Intent intent = allSticky.get(i);
16676                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16677                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16678                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16679                            null, 0, null, null, false, true, true, -1);
16680                    queue.enqueueParallelBroadcastLocked(r);
16681                    queue.scheduleBroadcastsLocked();
16682                }
16683            }
16684
16685            return sticky;
16686        }
16687    }
16688
16689    public void unregisterReceiver(IIntentReceiver receiver) {
16690        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16691
16692        final long origId = Binder.clearCallingIdentity();
16693        try {
16694            boolean doTrim = false;
16695
16696            synchronized(this) {
16697                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16698                if (rl != null) {
16699                    final BroadcastRecord r = rl.curBroadcast;
16700                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16701                        final boolean doNext = r.queue.finishReceiverLocked(
16702                                r, r.resultCode, r.resultData, r.resultExtras,
16703                                r.resultAbort, false);
16704                        if (doNext) {
16705                            doTrim = true;
16706                            r.queue.processNextBroadcast(false);
16707                        }
16708                    }
16709
16710                    if (rl.app != null) {
16711                        rl.app.receivers.remove(rl);
16712                    }
16713                    removeReceiverLocked(rl);
16714                    if (rl.linkedToDeath) {
16715                        rl.linkedToDeath = false;
16716                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16717                    }
16718                }
16719            }
16720
16721            // If we actually concluded any broadcasts, we might now be able
16722            // to trim the recipients' apps from our working set
16723            if (doTrim) {
16724                trimApplications();
16725                return;
16726            }
16727
16728        } finally {
16729            Binder.restoreCallingIdentity(origId);
16730        }
16731    }
16732
16733    void removeReceiverLocked(ReceiverList rl) {
16734        mRegisteredReceivers.remove(rl.receiver.asBinder());
16735        for (int i = rl.size() - 1; i >= 0; i--) {
16736            mReceiverResolver.removeFilter(rl.get(i));
16737        }
16738    }
16739
16740    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16741        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16742            ProcessRecord r = mLruProcesses.get(i);
16743            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16744                try {
16745                    r.thread.dispatchPackageBroadcast(cmd, packages);
16746                } catch (RemoteException ex) {
16747                }
16748            }
16749        }
16750    }
16751
16752    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16753            int callingUid, int[] users) {
16754        List<ResolveInfo> receivers = null;
16755        try {
16756            HashSet<ComponentName> singleUserReceivers = null;
16757            boolean scannedFirstReceivers = false;
16758            for (int user : users) {
16759                // Skip users that have Shell restrictions
16760                if (callingUid == Process.SHELL_UID
16761                        && mUserController.hasUserRestriction(
16762                        UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16763                    continue;
16764                }
16765                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16766                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16767                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
16768                    // If this is not the system user, we need to check for
16769                    // any receivers that should be filtered out.
16770                    for (int i=0; i<newReceivers.size(); i++) {
16771                        ResolveInfo ri = newReceivers.get(i);
16772                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
16773                            newReceivers.remove(i);
16774                            i--;
16775                        }
16776                    }
16777                }
16778                if (newReceivers != null && newReceivers.size() == 0) {
16779                    newReceivers = null;
16780                }
16781                if (receivers == null) {
16782                    receivers = newReceivers;
16783                } else if (newReceivers != null) {
16784                    // We need to concatenate the additional receivers
16785                    // found with what we have do far.  This would be easy,
16786                    // but we also need to de-dup any receivers that are
16787                    // singleUser.
16788                    if (!scannedFirstReceivers) {
16789                        // Collect any single user receivers we had already retrieved.
16790                        scannedFirstReceivers = true;
16791                        for (int i=0; i<receivers.size(); i++) {
16792                            ResolveInfo ri = receivers.get(i);
16793                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16794                                ComponentName cn = new ComponentName(
16795                                        ri.activityInfo.packageName, ri.activityInfo.name);
16796                                if (singleUserReceivers == null) {
16797                                    singleUserReceivers = new HashSet<ComponentName>();
16798                                }
16799                                singleUserReceivers.add(cn);
16800                            }
16801                        }
16802                    }
16803                    // Add the new results to the existing results, tracking
16804                    // and de-dupping single user receivers.
16805                    for (int i=0; i<newReceivers.size(); i++) {
16806                        ResolveInfo ri = newReceivers.get(i);
16807                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16808                            ComponentName cn = new ComponentName(
16809                                    ri.activityInfo.packageName, ri.activityInfo.name);
16810                            if (singleUserReceivers == null) {
16811                                singleUserReceivers = new HashSet<ComponentName>();
16812                            }
16813                            if (!singleUserReceivers.contains(cn)) {
16814                                singleUserReceivers.add(cn);
16815                                receivers.add(ri);
16816                            }
16817                        } else {
16818                            receivers.add(ri);
16819                        }
16820                    }
16821                }
16822            }
16823        } catch (RemoteException ex) {
16824            // pm is in same process, this will never happen.
16825        }
16826        return receivers;
16827    }
16828
16829    final int broadcastIntentLocked(ProcessRecord callerApp,
16830            String callerPackage, Intent intent, String resolvedType,
16831            IIntentReceiver resultTo, int resultCode, String resultData,
16832            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
16833            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16834        intent = new Intent(intent);
16835
16836        // By default broadcasts do not go to stopped apps.
16837        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16838
16839        // If we have not finished booting, don't allow this to launch new processes.
16840        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16841            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16842        }
16843
16844        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16845                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16846                + " ordered=" + ordered + " userid=" + userId);
16847        if ((resultTo != null) && !ordered) {
16848            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16849        }
16850
16851        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16852                ALLOW_NON_FULL, "broadcast", callerPackage);
16853
16854        // Make sure that the user who is receiving this broadcast is running.
16855        // If not, we will just skip it. Make an exception for shutdown broadcasts
16856        // and upgrade steps.
16857
16858        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
16859            if ((callingUid != Process.SYSTEM_UID
16860                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16861                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16862                Slog.w(TAG, "Skipping broadcast of " + intent
16863                        + ": user " + userId + " is stopped");
16864                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16865            }
16866        }
16867
16868        BroadcastOptions brOptions = null;
16869        if (bOptions != null) {
16870            brOptions = new BroadcastOptions(bOptions);
16871            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16872                // See if the caller is allowed to do this.  Note we are checking against
16873                // the actual real caller (not whoever provided the operation as say a
16874                // PendingIntent), because that who is actually supplied the arguments.
16875                if (checkComponentPermission(
16876                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16877                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16878                        != PackageManager.PERMISSION_GRANTED) {
16879                    String msg = "Permission Denial: " + intent.getAction()
16880                            + " broadcast from " + callerPackage + " (pid=" + callingPid
16881                            + ", uid=" + callingUid + ")"
16882                            + " requires "
16883                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16884                    Slog.w(TAG, msg);
16885                    throw new SecurityException(msg);
16886                }
16887            }
16888        }
16889
16890        /*
16891         * Prevent non-system code (defined here to be non-persistent
16892         * processes) from sending protected broadcasts.
16893         */
16894        int callingAppId = UserHandle.getAppId(callingUid);
16895        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16896            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16897            || callingAppId == Process.NFC_UID || callingUid == 0) {
16898            // Always okay.
16899        } else if (callerApp == null || !callerApp.persistent) {
16900            try {
16901                if (AppGlobals.getPackageManager().isProtectedBroadcast(
16902                        intent.getAction())) {
16903                    String msg = "Permission Denial: not allowed to send broadcast "
16904                            + intent.getAction() + " from pid="
16905                            + callingPid + ", uid=" + callingUid;
16906                    Slog.w(TAG, msg);
16907                    throw new SecurityException(msg);
16908                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16909                    // Special case for compatibility: we don't want apps to send this,
16910                    // but historically it has not been protected and apps may be using it
16911                    // to poke their own app widget.  So, instead of making it protected,
16912                    // just limit it to the caller.
16913                    if (callerApp == null) {
16914                        String msg = "Permission Denial: not allowed to send broadcast "
16915                                + intent.getAction() + " from unknown caller.";
16916                        Slog.w(TAG, msg);
16917                        throw new SecurityException(msg);
16918                    } else if (intent.getComponent() != null) {
16919                        // They are good enough to send to an explicit component...  verify
16920                        // it is being sent to the calling app.
16921                        if (!intent.getComponent().getPackageName().equals(
16922                                callerApp.info.packageName)) {
16923                            String msg = "Permission Denial: not allowed to send broadcast "
16924                                    + intent.getAction() + " to "
16925                                    + intent.getComponent().getPackageName() + " from "
16926                                    + callerApp.info.packageName;
16927                            Slog.w(TAG, msg);
16928                            throw new SecurityException(msg);
16929                        }
16930                    } else {
16931                        // Limit broadcast to their own package.
16932                        intent.setPackage(callerApp.info.packageName);
16933                    }
16934                }
16935            } catch (RemoteException e) {
16936                Slog.w(TAG, "Remote exception", e);
16937                return ActivityManager.BROADCAST_SUCCESS;
16938            }
16939        }
16940
16941        final String action = intent.getAction();
16942        if (action != null) {
16943            switch (action) {
16944                case Intent.ACTION_UID_REMOVED:
16945                case Intent.ACTION_PACKAGE_REMOVED:
16946                case Intent.ACTION_PACKAGE_CHANGED:
16947                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16948                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16949                    // Handle special intents: if this broadcast is from the package
16950                    // manager about a package being removed, we need to remove all of
16951                    // its activities from the history stack.
16952                    if (checkComponentPermission(
16953                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16954                            callingPid, callingUid, -1, true)
16955                            != PackageManager.PERMISSION_GRANTED) {
16956                        String msg = "Permission Denial: " + intent.getAction()
16957                                + " broadcast from " + callerPackage + " (pid=" + callingPid
16958                                + ", uid=" + callingUid + ")"
16959                                + " requires "
16960                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16961                        Slog.w(TAG, msg);
16962                        throw new SecurityException(msg);
16963                    }
16964                    switch (action) {
16965                        case Intent.ACTION_UID_REMOVED:
16966                            final Bundle intentExtras = intent.getExtras();
16967                            final int uid = intentExtras != null
16968                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16969                            if (uid >= 0) {
16970                                mBatteryStatsService.removeUid(uid);
16971                                mAppOpsService.uidRemoved(uid);
16972                            }
16973                            break;
16974                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16975                            // If resources are unavailable just force stop all those packages
16976                            // and flush the attribute cache as well.
16977                            String list[] =
16978                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16979                            if (list != null && list.length > 0) {
16980                                for (int i = 0; i < list.length; i++) {
16981                                    forceStopPackageLocked(list[i], -1, false, true, true,
16982                                            false, false, userId, "storage unmount");
16983                                }
16984                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16985                                sendPackageBroadcastLocked(
16986                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16987                                        userId);
16988                            }
16989                            break;
16990                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16991                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16992                            break;
16993                        case Intent.ACTION_PACKAGE_REMOVED:
16994                        case Intent.ACTION_PACKAGE_CHANGED:
16995                            Uri data = intent.getData();
16996                            String ssp;
16997                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16998                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16999                                boolean fullUninstall = removed &&
17000                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17001                                final boolean killProcess =
17002                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17003                                if (killProcess) {
17004                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17005                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17006                                            false, true, true, false, fullUninstall, userId,
17007                                            removed ? "pkg removed" : "pkg changed");
17008                                }
17009                                if (removed) {
17010                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
17011                                            new String[] {ssp}, userId);
17012                                    if (fullUninstall) {
17013                                        mAppOpsService.packageRemoved(
17014                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17015
17016                                        // Remove all permissions granted from/to this package
17017                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17018
17019                                        removeTasksByPackageNameLocked(ssp, userId);
17020                                        mBatteryStatsService.notePackageUninstalled(ssp);
17021                                    }
17022                                } else {
17023                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17024                                            intent.getStringArrayExtra(
17025                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17026                                }
17027                            }
17028                            break;
17029                    }
17030                    break;
17031                case Intent.ACTION_PACKAGE_ADDED:
17032                    // Special case for adding a package: by default turn on compatibility mode.
17033                    Uri data = intent.getData();
17034                    String ssp;
17035                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17036                        final boolean replacing =
17037                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17038                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17039
17040                        try {
17041                            ApplicationInfo ai = AppGlobals.getPackageManager().
17042                                    getApplicationInfo(ssp, 0, 0);
17043                            mBatteryStatsService.notePackageInstalled(ssp,
17044                                    ai != null ? ai.versionCode : 0);
17045                        } catch (RemoteException e) {
17046                        }
17047                    }
17048                    break;
17049                case Intent.ACTION_TIMEZONE_CHANGED:
17050                    // If this is the time zone changed action, queue up a message that will reset
17051                    // the timezone of all currently running processes. This message will get
17052                    // queued up before the broadcast happens.
17053                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17054                    break;
17055                case Intent.ACTION_TIME_CHANGED:
17056                    // If the user set the time, let all running processes know.
17057                    final int is24Hour =
17058                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17059                                    : 0;
17060                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17061                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17062                    synchronized (stats) {
17063                        stats.noteCurrentTimeChangedLocked();
17064                    }
17065                    break;
17066                case Intent.ACTION_CLEAR_DNS_CACHE:
17067                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17068                    break;
17069                case Proxy.PROXY_CHANGE_ACTION:
17070                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17071                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17072                    break;
17073            }
17074        }
17075
17076        // Add to the sticky list if requested.
17077        if (sticky) {
17078            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17079                    callingPid, callingUid)
17080                    != PackageManager.PERMISSION_GRANTED) {
17081                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17082                        + callingPid + ", uid=" + callingUid
17083                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17084                Slog.w(TAG, msg);
17085                throw new SecurityException(msg);
17086            }
17087            if (requiredPermissions != null && requiredPermissions.length > 0) {
17088                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17089                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17090                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17091            }
17092            if (intent.getComponent() != null) {
17093                throw new SecurityException(
17094                        "Sticky broadcasts can't target a specific component");
17095            }
17096            // We use userId directly here, since the "all" target is maintained
17097            // as a separate set of sticky broadcasts.
17098            if (userId != UserHandle.USER_ALL) {
17099                // But first, if this is not a broadcast to all users, then
17100                // make sure it doesn't conflict with an existing broadcast to
17101                // all users.
17102                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17103                        UserHandle.USER_ALL);
17104                if (stickies != null) {
17105                    ArrayList<Intent> list = stickies.get(intent.getAction());
17106                    if (list != null) {
17107                        int N = list.size();
17108                        int i;
17109                        for (i=0; i<N; i++) {
17110                            if (intent.filterEquals(list.get(i))) {
17111                                throw new IllegalArgumentException(
17112                                        "Sticky broadcast " + intent + " for user "
17113                                        + userId + " conflicts with existing global broadcast");
17114                            }
17115                        }
17116                    }
17117                }
17118            }
17119            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17120            if (stickies == null) {
17121                stickies = new ArrayMap<>();
17122                mStickyBroadcasts.put(userId, stickies);
17123            }
17124            ArrayList<Intent> list = stickies.get(intent.getAction());
17125            if (list == null) {
17126                list = new ArrayList<>();
17127                stickies.put(intent.getAction(), list);
17128            }
17129            final int stickiesCount = list.size();
17130            int i;
17131            for (i = 0; i < stickiesCount; i++) {
17132                if (intent.filterEquals(list.get(i))) {
17133                    // This sticky already exists, replace it.
17134                    list.set(i, new Intent(intent));
17135                    break;
17136                }
17137            }
17138            if (i >= stickiesCount) {
17139                list.add(new Intent(intent));
17140            }
17141        }
17142
17143        int[] users;
17144        if (userId == UserHandle.USER_ALL) {
17145            // Caller wants broadcast to go to all started users.
17146            users = mUserController.getStartedUserArrayLocked();
17147        } else {
17148            // Caller wants broadcast to go to one specific user.
17149            users = new int[] {userId};
17150        }
17151
17152        // Figure out who all will receive this broadcast.
17153        List receivers = null;
17154        List<BroadcastFilter> registeredReceivers = null;
17155        // Need to resolve the intent to interested receivers...
17156        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17157                 == 0) {
17158            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17159        }
17160        if (intent.getComponent() == null) {
17161            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17162                // Query one target user at a time, excluding shell-restricted users
17163                for (int i = 0; i < users.length; i++) {
17164                    if (mUserController.hasUserRestriction(
17165                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17166                        continue;
17167                    }
17168                    List<BroadcastFilter> registeredReceiversForUser =
17169                            mReceiverResolver.queryIntent(intent,
17170                                    resolvedType, false, users[i]);
17171                    if (registeredReceivers == null) {
17172                        registeredReceivers = registeredReceiversForUser;
17173                    } else if (registeredReceiversForUser != null) {
17174                        registeredReceivers.addAll(registeredReceiversForUser);
17175                    }
17176                }
17177            } else {
17178                registeredReceivers = mReceiverResolver.queryIntent(intent,
17179                        resolvedType, false, userId);
17180            }
17181        }
17182
17183        final boolean replacePending =
17184                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17185
17186        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17187                + " replacePending=" + replacePending);
17188
17189        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17190        if (!ordered && NR > 0) {
17191            // If we are not serializing this broadcast, then send the
17192            // registered receivers separately so they don't wait for the
17193            // components to be launched.
17194            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17195            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17196                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17197                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17198                    resultExtras, ordered, sticky, false, userId);
17199            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17200            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17201            if (!replaced) {
17202                queue.enqueueParallelBroadcastLocked(r);
17203                queue.scheduleBroadcastsLocked();
17204            }
17205            registeredReceivers = null;
17206            NR = 0;
17207        }
17208
17209        // Merge into one list.
17210        int ir = 0;
17211        if (receivers != null) {
17212            // A special case for PACKAGE_ADDED: do not allow the package
17213            // being added to see this broadcast.  This prevents them from
17214            // using this as a back door to get run as soon as they are
17215            // installed.  Maybe in the future we want to have a special install
17216            // broadcast or such for apps, but we'd like to deliberately make
17217            // this decision.
17218            String skipPackages[] = null;
17219            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17220                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17221                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17222                Uri data = intent.getData();
17223                if (data != null) {
17224                    String pkgName = data.getSchemeSpecificPart();
17225                    if (pkgName != null) {
17226                        skipPackages = new String[] { pkgName };
17227                    }
17228                }
17229            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17230                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17231            }
17232            if (skipPackages != null && (skipPackages.length > 0)) {
17233                for (String skipPackage : skipPackages) {
17234                    if (skipPackage != null) {
17235                        int NT = receivers.size();
17236                        for (int it=0; it<NT; it++) {
17237                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17238                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17239                                receivers.remove(it);
17240                                it--;
17241                                NT--;
17242                            }
17243                        }
17244                    }
17245                }
17246            }
17247
17248            int NT = receivers != null ? receivers.size() : 0;
17249            int it = 0;
17250            ResolveInfo curt = null;
17251            BroadcastFilter curr = null;
17252            while (it < NT && ir < NR) {
17253                if (curt == null) {
17254                    curt = (ResolveInfo)receivers.get(it);
17255                }
17256                if (curr == null) {
17257                    curr = registeredReceivers.get(ir);
17258                }
17259                if (curr.getPriority() >= curt.priority) {
17260                    // Insert this broadcast record into the final list.
17261                    receivers.add(it, curr);
17262                    ir++;
17263                    curr = null;
17264                    it++;
17265                    NT++;
17266                } else {
17267                    // Skip to the next ResolveInfo in the final list.
17268                    it++;
17269                    curt = null;
17270                }
17271            }
17272        }
17273        while (ir < NR) {
17274            if (receivers == null) {
17275                receivers = new ArrayList();
17276            }
17277            receivers.add(registeredReceivers.get(ir));
17278            ir++;
17279        }
17280
17281        if ((receivers != null && receivers.size() > 0)
17282                || resultTo != null) {
17283            BroadcastQueue queue = broadcastQueueForIntent(intent);
17284            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17285                    callerPackage, callingPid, callingUid, resolvedType,
17286                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17287                    resultData, resultExtras, ordered, sticky, false, userId);
17288
17289            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17290                    + ": prev had " + queue.mOrderedBroadcasts.size());
17291            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17292                    "Enqueueing broadcast " + r.intent.getAction());
17293
17294            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17295            if (!replaced) {
17296                queue.enqueueOrderedBroadcastLocked(r);
17297                queue.scheduleBroadcastsLocked();
17298            }
17299        }
17300
17301        return ActivityManager.BROADCAST_SUCCESS;
17302    }
17303
17304    final Intent verifyBroadcastLocked(Intent intent) {
17305        // Refuse possible leaked file descriptors
17306        if (intent != null && intent.hasFileDescriptors() == true) {
17307            throw new IllegalArgumentException("File descriptors passed in Intent");
17308        }
17309
17310        int flags = intent.getFlags();
17311
17312        if (!mProcessesReady) {
17313            // if the caller really truly claims to know what they're doing, go
17314            // ahead and allow the broadcast without launching any receivers
17315            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17316                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17317            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17318                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17319                        + " before boot completion");
17320                throw new IllegalStateException("Cannot broadcast before boot completed");
17321            }
17322        }
17323
17324        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17325            throw new IllegalArgumentException(
17326                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17327        }
17328
17329        return intent;
17330    }
17331
17332    public final int broadcastIntent(IApplicationThread caller,
17333            Intent intent, String resolvedType, IIntentReceiver resultTo,
17334            int resultCode, String resultData, Bundle resultExtras,
17335            String[] requiredPermissions, int appOp, Bundle bOptions,
17336            boolean serialized, boolean sticky, int userId) {
17337        enforceNotIsolatedCaller("broadcastIntent");
17338        synchronized(this) {
17339            intent = verifyBroadcastLocked(intent);
17340
17341            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17342            final int callingPid = Binder.getCallingPid();
17343            final int callingUid = Binder.getCallingUid();
17344            final long origId = Binder.clearCallingIdentity();
17345            int res = broadcastIntentLocked(callerApp,
17346                    callerApp != null ? callerApp.info.packageName : null,
17347                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17348                    requiredPermissions, appOp, null, serialized, sticky,
17349                    callingPid, callingUid, userId);
17350            Binder.restoreCallingIdentity(origId);
17351            return res;
17352        }
17353    }
17354
17355
17356    int broadcastIntentInPackage(String packageName, int uid,
17357            Intent intent, String resolvedType, IIntentReceiver resultTo,
17358            int resultCode, String resultData, Bundle resultExtras,
17359            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17360            int userId) {
17361        synchronized(this) {
17362            intent = verifyBroadcastLocked(intent);
17363
17364            final long origId = Binder.clearCallingIdentity();
17365            String[] requiredPermissions = requiredPermission == null ? null
17366                    : new String[] {requiredPermission};
17367            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17368                    resultTo, resultCode, resultData, resultExtras,
17369                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17370                    sticky, -1, uid, userId);
17371            Binder.restoreCallingIdentity(origId);
17372            return res;
17373        }
17374    }
17375
17376    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17377        // Refuse possible leaked file descriptors
17378        if (intent != null && intent.hasFileDescriptors() == true) {
17379            throw new IllegalArgumentException("File descriptors passed in Intent");
17380        }
17381
17382        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17383                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17384
17385        synchronized(this) {
17386            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17387                    != PackageManager.PERMISSION_GRANTED) {
17388                String msg = "Permission Denial: unbroadcastIntent() from pid="
17389                        + Binder.getCallingPid()
17390                        + ", uid=" + Binder.getCallingUid()
17391                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17392                Slog.w(TAG, msg);
17393                throw new SecurityException(msg);
17394            }
17395            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17396            if (stickies != null) {
17397                ArrayList<Intent> list = stickies.get(intent.getAction());
17398                if (list != null) {
17399                    int N = list.size();
17400                    int i;
17401                    for (i=0; i<N; i++) {
17402                        if (intent.filterEquals(list.get(i))) {
17403                            list.remove(i);
17404                            break;
17405                        }
17406                    }
17407                    if (list.size() <= 0) {
17408                        stickies.remove(intent.getAction());
17409                    }
17410                }
17411                if (stickies.size() <= 0) {
17412                    mStickyBroadcasts.remove(userId);
17413                }
17414            }
17415        }
17416    }
17417
17418    void backgroundServicesFinishedLocked(int userId) {
17419        for (BroadcastQueue queue : mBroadcastQueues) {
17420            queue.backgroundServicesFinishedLocked(userId);
17421        }
17422    }
17423
17424    public void finishReceiver(IBinder who, int resultCode, String resultData,
17425            Bundle resultExtras, boolean resultAbort, int flags) {
17426        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17427
17428        // Refuse possible leaked file descriptors
17429        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17430            throw new IllegalArgumentException("File descriptors passed in Bundle");
17431        }
17432
17433        final long origId = Binder.clearCallingIdentity();
17434        try {
17435            boolean doNext = false;
17436            BroadcastRecord r;
17437
17438            synchronized(this) {
17439                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17440                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17441                r = queue.getMatchingOrderedReceiver(who);
17442                if (r != null) {
17443                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17444                        resultData, resultExtras, resultAbort, true);
17445                }
17446            }
17447
17448            if (doNext) {
17449                r.queue.processNextBroadcast(false);
17450            }
17451            trimApplications();
17452        } finally {
17453            Binder.restoreCallingIdentity(origId);
17454        }
17455    }
17456
17457    // =========================================================
17458    // INSTRUMENTATION
17459    // =========================================================
17460
17461    public boolean startInstrumentation(ComponentName className,
17462            String profileFile, int flags, Bundle arguments,
17463            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17464            int userId, String abiOverride) {
17465        enforceNotIsolatedCaller("startInstrumentation");
17466        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17467                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17468        // Refuse possible leaked file descriptors
17469        if (arguments != null && arguments.hasFileDescriptors()) {
17470            throw new IllegalArgumentException("File descriptors passed in Bundle");
17471        }
17472
17473        synchronized(this) {
17474            InstrumentationInfo ii = null;
17475            ApplicationInfo ai = null;
17476            try {
17477                ii = mContext.getPackageManager().getInstrumentationInfo(
17478                    className, STOCK_PM_FLAGS);
17479                ai = AppGlobals.getPackageManager().getApplicationInfo(
17480                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17481            } catch (PackageManager.NameNotFoundException e) {
17482            } catch (RemoteException e) {
17483            }
17484            if (ii == null) {
17485                reportStartInstrumentationFailure(watcher, className,
17486                        "Unable to find instrumentation info for: " + className);
17487                return false;
17488            }
17489            if (ai == null) {
17490                reportStartInstrumentationFailure(watcher, className,
17491                        "Unable to find instrumentation target package: " + ii.targetPackage);
17492                return false;
17493            }
17494
17495            int match = mContext.getPackageManager().checkSignatures(
17496                    ii.targetPackage, ii.packageName);
17497            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17498                String msg = "Permission Denial: starting instrumentation "
17499                        + className + " from pid="
17500                        + Binder.getCallingPid()
17501                        + ", uid=" + Binder.getCallingPid()
17502                        + " not allowed because package " + ii.packageName
17503                        + " does not have a signature matching the target "
17504                        + ii.targetPackage;
17505                reportStartInstrumentationFailure(watcher, className, msg);
17506                throw new SecurityException(msg);
17507            }
17508
17509            final long origId = Binder.clearCallingIdentity();
17510            // Instrumentation can kill and relaunch even persistent processes
17511            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17512                    "start instr");
17513            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17514            app.instrumentationClass = className;
17515            app.instrumentationInfo = ai;
17516            app.instrumentationProfileFile = profileFile;
17517            app.instrumentationArguments = arguments;
17518            app.instrumentationWatcher = watcher;
17519            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17520            app.instrumentationResultClass = className;
17521            Binder.restoreCallingIdentity(origId);
17522        }
17523
17524        return true;
17525    }
17526
17527    /**
17528     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17529     * error to the logs, but if somebody is watching, send the report there too.  This enables
17530     * the "am" command to report errors with more information.
17531     *
17532     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17533     * @param cn The component name of the instrumentation.
17534     * @param report The error report.
17535     */
17536    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17537            ComponentName cn, String report) {
17538        Slog.w(TAG, report);
17539        try {
17540            if (watcher != null) {
17541                Bundle results = new Bundle();
17542                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17543                results.putString("Error", report);
17544                watcher.instrumentationStatus(cn, -1, results);
17545            }
17546        } catch (RemoteException e) {
17547            Slog.w(TAG, e);
17548        }
17549    }
17550
17551    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17552        if (app.instrumentationWatcher != null) {
17553            try {
17554                // NOTE:  IInstrumentationWatcher *must* be oneway here
17555                app.instrumentationWatcher.instrumentationFinished(
17556                    app.instrumentationClass,
17557                    resultCode,
17558                    results);
17559            } catch (RemoteException e) {
17560            }
17561        }
17562
17563        // Can't call out of the system process with a lock held, so post a message.
17564        if (app.instrumentationUiAutomationConnection != null) {
17565            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17566                    app.instrumentationUiAutomationConnection).sendToTarget();
17567        }
17568
17569        app.instrumentationWatcher = null;
17570        app.instrumentationUiAutomationConnection = null;
17571        app.instrumentationClass = null;
17572        app.instrumentationInfo = null;
17573        app.instrumentationProfileFile = null;
17574        app.instrumentationArguments = null;
17575
17576        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17577                "finished inst");
17578    }
17579
17580    public void finishInstrumentation(IApplicationThread target,
17581            int resultCode, Bundle results) {
17582        int userId = UserHandle.getCallingUserId();
17583        // Refuse possible leaked file descriptors
17584        if (results != null && results.hasFileDescriptors()) {
17585            throw new IllegalArgumentException("File descriptors passed in Intent");
17586        }
17587
17588        synchronized(this) {
17589            ProcessRecord app = getRecordForAppLocked(target);
17590            if (app == null) {
17591                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17592                return;
17593            }
17594            final long origId = Binder.clearCallingIdentity();
17595            finishInstrumentationLocked(app, resultCode, results);
17596            Binder.restoreCallingIdentity(origId);
17597        }
17598    }
17599
17600    // =========================================================
17601    // CONFIGURATION
17602    // =========================================================
17603
17604    public ConfigurationInfo getDeviceConfigurationInfo() {
17605        ConfigurationInfo config = new ConfigurationInfo();
17606        synchronized (this) {
17607            config.reqTouchScreen = mConfiguration.touchscreen;
17608            config.reqKeyboardType = mConfiguration.keyboard;
17609            config.reqNavigation = mConfiguration.navigation;
17610            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17611                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17612                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17613            }
17614            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17615                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17616                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17617            }
17618            config.reqGlEsVersion = GL_ES_VERSION;
17619        }
17620        return config;
17621    }
17622
17623    ActivityStack getFocusedStack() {
17624        return mStackSupervisor.getFocusedStack();
17625    }
17626
17627    @Override
17628    public int getFocusedStackId() throws RemoteException {
17629        ActivityStack focusedStack = getFocusedStack();
17630        if (focusedStack != null) {
17631            return focusedStack.getStackId();
17632        }
17633        return -1;
17634    }
17635
17636    public Configuration getConfiguration() {
17637        Configuration ci;
17638        synchronized(this) {
17639            ci = new Configuration(mConfiguration);
17640            ci.userSetLocale = false;
17641        }
17642        return ci;
17643    }
17644
17645    @Override
17646    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17647        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
17648                "suppressResizeConfigChanges()");
17649        synchronized (this) {
17650            mSuppressResizeConfigChanges = suppress;
17651        }
17652    }
17653
17654    @Override
17655    public void removeStack(int stackId) {
17656        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
17657                "detahStack()");
17658        if (stackId == HOME_STACK_ID) {
17659            throw new IllegalArgumentException("Removing home stack is not allowed.");
17660        }
17661        synchronized (this) {
17662            long origId = Binder.clearCallingIdentity();
17663            ActivityStack stack = mStackSupervisor.getStack(stackId);
17664            if (stack != null) {
17665                ArrayList<TaskRecord> tasks = stack.getAllTasks();
17666                for (int i = tasks.size() - 1; i >= 0; i--) {
17667                    removeTaskByIdLocked(tasks.get(i).taskId, false /* killProcess */,
17668                            !REMOVE_FROM_RECENTS);
17669                }
17670            }
17671            Binder.restoreCallingIdentity(origId);
17672        }
17673    }
17674
17675    @Override
17676    public void updatePersistentConfiguration(Configuration values) {
17677        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17678                "updateConfiguration()");
17679        enforceWriteSettingsPermission("updateConfiguration()");
17680        if (values == null) {
17681            throw new NullPointerException("Configuration must not be null");
17682        }
17683
17684        int userId = UserHandle.getCallingUserId();
17685
17686        synchronized(this) {
17687            final long origId = Binder.clearCallingIdentity();
17688            updateConfigurationLocked(values, null, false, true, userId);
17689            Binder.restoreCallingIdentity(origId);
17690        }
17691    }
17692
17693    private void enforceWriteSettingsPermission(String func) {
17694        int uid = Binder.getCallingUid();
17695        if (uid == Process.ROOT_UID) {
17696            return;
17697        }
17698
17699        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17700                Settings.getPackageNameForUid(mContext, uid), false)) {
17701            return;
17702        }
17703
17704        String msg = "Permission Denial: " + func + " from pid="
17705                + Binder.getCallingPid()
17706                + ", uid=" + uid
17707                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17708        Slog.w(TAG, msg);
17709        throw new SecurityException(msg);
17710    }
17711
17712    public void updateConfiguration(Configuration values) {
17713        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17714                "updateConfiguration()");
17715
17716        synchronized(this) {
17717            if (values == null && mWindowManager != null) {
17718                // sentinel: fetch the current configuration from the window manager
17719                values = mWindowManager.computeNewConfiguration();
17720            }
17721
17722            if (mWindowManager != null) {
17723                mProcessList.applyDisplaySize(mWindowManager);
17724            }
17725
17726            final long origId = Binder.clearCallingIdentity();
17727            if (values != null) {
17728                Settings.System.clearConfiguration(values);
17729            }
17730            updateConfigurationLocked(values, null, false);
17731            Binder.restoreCallingIdentity(origId);
17732        }
17733    }
17734
17735    void updateUserConfigurationLocked() {
17736        Configuration configuration = new Configuration(mConfiguration);
17737        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
17738                mUserController.getCurrentUserIdLocked());
17739        updateConfigurationLocked(configuration, null, false);
17740    }
17741
17742    boolean updateConfigurationLocked(Configuration values,
17743            ActivityRecord starting, boolean initLocale) {
17744        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
17745        return updateConfigurationLocked(values, starting, initLocale, false,
17746                UserHandle.USER_NULL);
17747    }
17748
17749    // To cache the list of supported system locales
17750    private String[] mSupportedSystemLocales = null;
17751
17752    /**
17753     * Do either or both things: (1) change the current configuration, and (2)
17754     * make sure the given activity is running with the (now) current
17755     * configuration.  Returns true if the activity has been left running, or
17756     * false if <var>starting</var> is being destroyed to match the new
17757     * configuration.
17758     *
17759     * @param userId is only used when persistent parameter is set to true to persist configuration
17760     *               for that particular user
17761     */
17762    boolean updateConfigurationLocked(Configuration values,
17763            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
17764        int changes = 0;
17765
17766        if (values != null) {
17767            Configuration newConfig = new Configuration(mConfiguration);
17768            changes = newConfig.updateFrom(values);
17769            if (changes != 0) {
17770                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17771                        "Updating configuration to: " + values);
17772
17773                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17774
17775                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
17776                    if (mSupportedSystemLocales == null) {
17777                        mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
17778                    }
17779                    final Locale locale = values.getLocales().getBestMatch(mSupportedSystemLocales);
17780                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
17781                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17782                            locale));
17783                }
17784
17785                mConfigurationSeq++;
17786                if (mConfigurationSeq <= 0) {
17787                    mConfigurationSeq = 1;
17788                }
17789                newConfig.seq = mConfigurationSeq;
17790                mConfiguration = newConfig;
17791                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17792                mUsageStatsService.reportConfigurationChange(newConfig,
17793                        mUserController.getCurrentUserIdLocked());
17794                //mUsageStatsService.noteStartConfig(newConfig);
17795
17796                final Configuration configCopy = new Configuration(mConfiguration);
17797
17798                // TODO: If our config changes, should we auto dismiss any currently
17799                // showing dialogs?
17800                mShowDialogs = shouldShowDialogs(newConfig);
17801
17802                AttributeCache ac = AttributeCache.instance();
17803                if (ac != null) {
17804                    ac.updateConfiguration(configCopy);
17805                }
17806
17807                // Make sure all resources in our process are updated
17808                // right now, so that anyone who is going to retrieve
17809                // resource values after we return will be sure to get
17810                // the new ones.  This is especially important during
17811                // boot, where the first config change needs to guarantee
17812                // all resources have that config before following boot
17813                // code is executed.
17814                mSystemThread.applyConfigurationToResources(configCopy);
17815
17816                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17817                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17818                    msg.obj = new Configuration(configCopy);
17819                    msg.arg1 = userId;
17820                    mHandler.sendMessage(msg);
17821                }
17822
17823                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17824                    ProcessRecord app = mLruProcesses.get(i);
17825                    try {
17826                        if (app.thread != null) {
17827                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17828                                    + app.processName + " new config " + mConfiguration);
17829                            app.thread.scheduleConfigurationChanged(configCopy);
17830                        }
17831                    } catch (Exception e) {
17832                    }
17833                }
17834                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17835                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17836                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
17837                        | Intent.FLAG_RECEIVER_FOREGROUND);
17838                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17839                        null, AppOpsManager.OP_NONE, null, false, false,
17840                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17841                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17842                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17843                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17844                    if (!mProcessesReady) {
17845                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17846                    }
17847                    broadcastIntentLocked(null, null, intent,
17848                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17849                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17850                }
17851            }
17852        }
17853
17854        boolean kept = true;
17855        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17856        // mainStack is null during startup.
17857        if (mainStack != null) {
17858            if (changes != 0 && starting == null) {
17859                // If the configuration changed, and the caller is not already
17860                // in the process of starting an activity, then find the top
17861                // activity to check if its configuration needs to change.
17862                starting = mainStack.topRunningActivityLocked();
17863            }
17864
17865            if (starting != null) {
17866                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
17867                // And we need to make sure at this point that all other activities
17868                // are made visible with the correct configuration.
17869                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
17870                        !PRESERVE_WINDOWS);
17871            }
17872        }
17873
17874        if (values != null && mWindowManager != null) {
17875            mWindowManager.setNewConfiguration(mConfiguration);
17876        }
17877
17878        return kept;
17879    }
17880
17881    /**
17882     * Decide based on the configuration whether we should shouw the ANR,
17883     * crash, etc dialogs.  The idea is that if there is no affordnace to
17884     * press the on-screen buttons, we shouldn't show the dialog.
17885     *
17886     * A thought: SystemUI might also want to get told about this, the Power
17887     * dialog / global actions also might want different behaviors.
17888     */
17889    private static final boolean shouldShowDialogs(Configuration config) {
17890        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17891                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17892                && config.navigation == Configuration.NAVIGATION_NONAV);
17893    }
17894
17895    @Override
17896    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17897        synchronized (this) {
17898            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17899            if (srec != null) {
17900                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17901            }
17902        }
17903        return false;
17904    }
17905
17906    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17907            Intent resultData) {
17908
17909        synchronized (this) {
17910            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17911            if (r != null) {
17912                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17913            }
17914            return false;
17915        }
17916    }
17917
17918    public int getLaunchedFromUid(IBinder activityToken) {
17919        ActivityRecord srec;
17920        synchronized (this) {
17921            srec = ActivityRecord.forTokenLocked(activityToken);
17922        }
17923        if (srec == null) {
17924            return -1;
17925        }
17926        return srec.launchedFromUid;
17927    }
17928
17929    public String getLaunchedFromPackage(IBinder activityToken) {
17930        ActivityRecord srec;
17931        synchronized (this) {
17932            srec = ActivityRecord.forTokenLocked(activityToken);
17933        }
17934        if (srec == null) {
17935            return null;
17936        }
17937        return srec.launchedFromPackage;
17938    }
17939
17940    // =========================================================
17941    // LIFETIME MANAGEMENT
17942    // =========================================================
17943
17944    // Returns which broadcast queue the app is the current [or imminent] receiver
17945    // on, or 'null' if the app is not an active broadcast recipient.
17946    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17947        BroadcastRecord r = app.curReceiver;
17948        if (r != null) {
17949            return r.queue;
17950        }
17951
17952        // It's not the current receiver, but it might be starting up to become one
17953        synchronized (this) {
17954            for (BroadcastQueue queue : mBroadcastQueues) {
17955                r = queue.mPendingBroadcast;
17956                if (r != null && r.curApp == app) {
17957                    // found it; report which queue it's in
17958                    return queue;
17959                }
17960            }
17961        }
17962
17963        return null;
17964    }
17965
17966    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17967            ComponentName targetComponent, String targetProcess) {
17968        if (!mTrackingAssociations) {
17969            return null;
17970        }
17971        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17972                = mAssociations.get(targetUid);
17973        if (components == null) {
17974            components = new ArrayMap<>();
17975            mAssociations.put(targetUid, components);
17976        }
17977        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17978        if (sourceUids == null) {
17979            sourceUids = new SparseArray<>();
17980            components.put(targetComponent, sourceUids);
17981        }
17982        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17983        if (sourceProcesses == null) {
17984            sourceProcesses = new ArrayMap<>();
17985            sourceUids.put(sourceUid, sourceProcesses);
17986        }
17987        Association ass = sourceProcesses.get(sourceProcess);
17988        if (ass == null) {
17989            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17990                    targetProcess);
17991            sourceProcesses.put(sourceProcess, ass);
17992        }
17993        ass.mCount++;
17994        ass.mNesting++;
17995        if (ass.mNesting == 1) {
17996            ass.mStartTime = SystemClock.uptimeMillis();
17997        }
17998        return ass;
17999    }
18000
18001    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18002            ComponentName targetComponent) {
18003        if (!mTrackingAssociations) {
18004            return;
18005        }
18006        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18007                = mAssociations.get(targetUid);
18008        if (components == null) {
18009            return;
18010        }
18011        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18012        if (sourceUids == null) {
18013            return;
18014        }
18015        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18016        if (sourceProcesses == null) {
18017            return;
18018        }
18019        Association ass = sourceProcesses.get(sourceProcess);
18020        if (ass == null || ass.mNesting <= 0) {
18021            return;
18022        }
18023        ass.mNesting--;
18024        if (ass.mNesting == 0) {
18025            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
18026        }
18027    }
18028
18029    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18030            boolean doingAll, long now) {
18031        if (mAdjSeq == app.adjSeq) {
18032            // This adjustment has already been computed.
18033            return app.curRawAdj;
18034        }
18035
18036        if (app.thread == null) {
18037            app.adjSeq = mAdjSeq;
18038            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18039            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18040            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18041        }
18042
18043        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18044        app.adjSource = null;
18045        app.adjTarget = null;
18046        app.empty = false;
18047        app.cached = false;
18048
18049        final int activitiesSize = app.activities.size();
18050
18051        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18052            // The max adjustment doesn't allow this app to be anything
18053            // below foreground, so it is not worth doing work for it.
18054            app.adjType = "fixed";
18055            app.adjSeq = mAdjSeq;
18056            app.curRawAdj = app.maxAdj;
18057            app.foregroundActivities = false;
18058            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
18059            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18060            // System processes can do UI, and when they do we want to have
18061            // them trim their memory after the user leaves the UI.  To
18062            // facilitate this, here we need to determine whether or not it
18063            // is currently showing UI.
18064            app.systemNoUi = true;
18065            if (app == TOP_APP) {
18066                app.systemNoUi = false;
18067            } else if (activitiesSize > 0) {
18068                for (int j = 0; j < activitiesSize; j++) {
18069                    final ActivityRecord r = app.activities.get(j);
18070                    if (r.visible) {
18071                        app.systemNoUi = false;
18072                    }
18073                }
18074            }
18075            if (!app.systemNoUi) {
18076                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18077            }
18078            return (app.curAdj=app.maxAdj);
18079        }
18080
18081        app.systemNoUi = false;
18082
18083        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18084
18085        // Determine the importance of the process, starting with most
18086        // important to least, and assign an appropriate OOM adjustment.
18087        int adj;
18088        int schedGroup;
18089        int procState;
18090        boolean foregroundActivities = false;
18091        BroadcastQueue queue;
18092        if (app == TOP_APP) {
18093            // The last app on the list is the foreground app.
18094            adj = ProcessList.FOREGROUND_APP_ADJ;
18095            schedGroup = Process.THREAD_GROUP_DEFAULT;
18096            app.adjType = "top-activity";
18097            foregroundActivities = true;
18098            procState = PROCESS_STATE_CUR_TOP;
18099        } else if (app.instrumentationClass != null) {
18100            // Don't want to kill running instrumentation.
18101            adj = ProcessList.FOREGROUND_APP_ADJ;
18102            schedGroup = Process.THREAD_GROUP_DEFAULT;
18103            app.adjType = "instrumentation";
18104            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18105        } else if ((queue = isReceivingBroadcast(app)) != null) {
18106            // An app that is currently receiving a broadcast also
18107            // counts as being in the foreground for OOM killer purposes.
18108            // It's placed in a sched group based on the nature of the
18109            // broadcast as reflected by which queue it's active in.
18110            adj = ProcessList.FOREGROUND_APP_ADJ;
18111            schedGroup = (queue == mFgBroadcastQueue)
18112                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18113            app.adjType = "broadcast";
18114            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18115        } else if (app.executingServices.size() > 0) {
18116            // An app that is currently executing a service callback also
18117            // counts as being in the foreground.
18118            adj = ProcessList.FOREGROUND_APP_ADJ;
18119            schedGroup = app.execServicesFg ?
18120                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18121            app.adjType = "exec-service";
18122            procState = ActivityManager.PROCESS_STATE_SERVICE;
18123            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18124        } else {
18125            // As far as we know the process is empty.  We may change our mind later.
18126            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18127            // At this point we don't actually know the adjustment.  Use the cached adj
18128            // value that the caller wants us to.
18129            adj = cachedAdj;
18130            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18131            app.cached = true;
18132            app.empty = true;
18133            app.adjType = "cch-empty";
18134        }
18135
18136        // Examine all activities if not already foreground.
18137        if (!foregroundActivities && activitiesSize > 0) {
18138            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18139            for (int j = 0; j < activitiesSize; j++) {
18140                final ActivityRecord r = app.activities.get(j);
18141                if (r.app != app) {
18142                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
18143                            + app + "?!? Using " + r.app + " instead.");
18144                    continue;
18145                }
18146                if (r.visible) {
18147                    // App has a visible activity; only upgrade adjustment.
18148                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18149                        adj = ProcessList.VISIBLE_APP_ADJ;
18150                        app.adjType = "visible";
18151                    }
18152                    if (procState > PROCESS_STATE_CUR_TOP) {
18153                        procState = PROCESS_STATE_CUR_TOP;
18154                    }
18155                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18156                    app.cached = false;
18157                    app.empty = false;
18158                    foregroundActivities = true;
18159                    if (r.task != null && minLayer > 0) {
18160                        final int layer = r.task.mLayerRank;
18161                        if (layer >= 0 && minLayer > layer) {
18162                            minLayer = layer;
18163                        }
18164                    }
18165                    break;
18166                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18167                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18168                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18169                        app.adjType = "pausing";
18170                    }
18171                    if (procState > PROCESS_STATE_CUR_TOP) {
18172                        procState = PROCESS_STATE_CUR_TOP;
18173                    }
18174                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18175                    app.cached = false;
18176                    app.empty = false;
18177                    foregroundActivities = true;
18178                } else if (r.state == ActivityState.STOPPING) {
18179                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18180                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18181                        app.adjType = "stopping";
18182                    }
18183                    // For the process state, we will at this point consider the
18184                    // process to be cached.  It will be cached either as an activity
18185                    // or empty depending on whether the activity is finishing.  We do
18186                    // this so that we can treat the process as cached for purposes of
18187                    // memory trimming (determing current memory level, trim command to
18188                    // send to process) since there can be an arbitrary number of stopping
18189                    // processes and they should soon all go into the cached state.
18190                    if (!r.finishing) {
18191                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18192                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18193                        }
18194                    }
18195                    app.cached = false;
18196                    app.empty = false;
18197                    foregroundActivities = true;
18198                } else {
18199                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18200                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18201                        app.adjType = "cch-act";
18202                    }
18203                }
18204            }
18205            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18206                adj += minLayer;
18207            }
18208        }
18209
18210        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18211                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18212            if (app.foregroundServices) {
18213                // The user is aware of this app, so make it visible.
18214                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18215                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18216                app.cached = false;
18217                app.adjType = "fg-service";
18218                schedGroup = Process.THREAD_GROUP_DEFAULT;
18219            } else if (app.forcingToForeground != null) {
18220                // The user is aware of this app, so make it visible.
18221                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18222                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18223                app.cached = false;
18224                app.adjType = "force-fg";
18225                app.adjSource = app.forcingToForeground;
18226                schedGroup = Process.THREAD_GROUP_DEFAULT;
18227            }
18228        }
18229
18230        if (app == mHeavyWeightProcess) {
18231            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18232                // We don't want to kill the current heavy-weight process.
18233                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18234                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18235                app.cached = false;
18236                app.adjType = "heavy";
18237            }
18238            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18239                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18240            }
18241        }
18242
18243        if (app == mHomeProcess) {
18244            if (adj > ProcessList.HOME_APP_ADJ) {
18245                // This process is hosting what we currently consider to be the
18246                // home app, so we don't want to let it go into the background.
18247                adj = ProcessList.HOME_APP_ADJ;
18248                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18249                app.cached = false;
18250                app.adjType = "home";
18251            }
18252            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18253                procState = ActivityManager.PROCESS_STATE_HOME;
18254            }
18255        }
18256
18257        if (app == mPreviousProcess && app.activities.size() > 0) {
18258            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18259                // This was the previous process that showed UI to the user.
18260                // We want to try to keep it around more aggressively, to give
18261                // a good experience around switching between two apps.
18262                adj = ProcessList.PREVIOUS_APP_ADJ;
18263                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18264                app.cached = false;
18265                app.adjType = "previous";
18266            }
18267            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18268                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18269            }
18270        }
18271
18272        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18273                + " reason=" + app.adjType);
18274
18275        // By default, we use the computed adjustment.  It may be changed if
18276        // there are applications dependent on our services or providers, but
18277        // this gives us a baseline and makes sure we don't get into an
18278        // infinite recursion.
18279        app.adjSeq = mAdjSeq;
18280        app.curRawAdj = adj;
18281        app.hasStartedServices = false;
18282
18283        if (mBackupTarget != null && app == mBackupTarget.app) {
18284            // If possible we want to avoid killing apps while they're being backed up
18285            if (adj > ProcessList.BACKUP_APP_ADJ) {
18286                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18287                adj = ProcessList.BACKUP_APP_ADJ;
18288                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18289                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18290                }
18291                app.adjType = "backup";
18292                app.cached = false;
18293            }
18294            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18295                procState = ActivityManager.PROCESS_STATE_BACKUP;
18296            }
18297        }
18298
18299        boolean mayBeTop = false;
18300
18301        for (int is = app.services.size()-1;
18302                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18303                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18304                        || procState > ActivityManager.PROCESS_STATE_TOP);
18305                is--) {
18306            ServiceRecord s = app.services.valueAt(is);
18307            if (s.startRequested) {
18308                app.hasStartedServices = true;
18309                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18310                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18311                }
18312                if (app.hasShownUi && app != mHomeProcess) {
18313                    // If this process has shown some UI, let it immediately
18314                    // go to the LRU list because it may be pretty heavy with
18315                    // UI stuff.  We'll tag it with a label just to help
18316                    // debug and understand what is going on.
18317                    if (adj > ProcessList.SERVICE_ADJ) {
18318                        app.adjType = "cch-started-ui-services";
18319                    }
18320                } else {
18321                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18322                        // This service has seen some activity within
18323                        // recent memory, so we will keep its process ahead
18324                        // of the background processes.
18325                        if (adj > ProcessList.SERVICE_ADJ) {
18326                            adj = ProcessList.SERVICE_ADJ;
18327                            app.adjType = "started-services";
18328                            app.cached = false;
18329                        }
18330                    }
18331                    // If we have let the service slide into the background
18332                    // state, still have some text describing what it is doing
18333                    // even though the service no longer has an impact.
18334                    if (adj > ProcessList.SERVICE_ADJ) {
18335                        app.adjType = "cch-started-services";
18336                    }
18337                }
18338            }
18339            for (int conni = s.connections.size()-1;
18340                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18341                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18342                            || procState > ActivityManager.PROCESS_STATE_TOP);
18343                    conni--) {
18344                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18345                for (int i = 0;
18346                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18347                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18348                                || procState > ActivityManager.PROCESS_STATE_TOP);
18349                        i++) {
18350                    // XXX should compute this based on the max of
18351                    // all connected clients.
18352                    ConnectionRecord cr = clist.get(i);
18353                    if (cr.binding.client == app) {
18354                        // Binding to ourself is not interesting.
18355                        continue;
18356                    }
18357                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18358                        ProcessRecord client = cr.binding.client;
18359                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18360                                TOP_APP, doingAll, now);
18361                        int clientProcState = client.curProcState;
18362                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18363                            // If the other app is cached for any reason, for purposes here
18364                            // we are going to consider it empty.  The specific cached state
18365                            // doesn't propagate except under certain conditions.
18366                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18367                        }
18368                        String adjType = null;
18369                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18370                            // Not doing bind OOM management, so treat
18371                            // this guy more like a started service.
18372                            if (app.hasShownUi && app != mHomeProcess) {
18373                                // If this process has shown some UI, let it immediately
18374                                // go to the LRU list because it may be pretty heavy with
18375                                // UI stuff.  We'll tag it with a label just to help
18376                                // debug and understand what is going on.
18377                                if (adj > clientAdj) {
18378                                    adjType = "cch-bound-ui-services";
18379                                }
18380                                app.cached = false;
18381                                clientAdj = adj;
18382                                clientProcState = procState;
18383                            } else {
18384                                if (now >= (s.lastActivity
18385                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18386                                    // This service has not seen activity within
18387                                    // recent memory, so allow it to drop to the
18388                                    // LRU list if there is no other reason to keep
18389                                    // it around.  We'll also tag it with a label just
18390                                    // to help debug and undertand what is going on.
18391                                    if (adj > clientAdj) {
18392                                        adjType = "cch-bound-services";
18393                                    }
18394                                    clientAdj = adj;
18395                                }
18396                            }
18397                        }
18398                        if (adj > clientAdj) {
18399                            // If this process has recently shown UI, and
18400                            // the process that is binding to it is less
18401                            // important than being visible, then we don't
18402                            // care about the binding as much as we care
18403                            // about letting this process get into the LRU
18404                            // list to be killed and restarted if needed for
18405                            // memory.
18406                            if (app.hasShownUi && app != mHomeProcess
18407                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18408                                adjType = "cch-bound-ui-services";
18409                            } else {
18410                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18411                                        |Context.BIND_IMPORTANT)) != 0) {
18412                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18413                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18414                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18415                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18416                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18417                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18418                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18419                                    adj = clientAdj;
18420                                } else {
18421                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18422                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18423                                    }
18424                                }
18425                                if (!client.cached) {
18426                                    app.cached = false;
18427                                }
18428                                adjType = "service";
18429                            }
18430                        }
18431                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18432                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18433                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18434                            }
18435                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18436                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18437                                    // Special handling of clients who are in the top state.
18438                                    // We *may* want to consider this process to be in the
18439                                    // top state as well, but only if there is not another
18440                                    // reason for it to be running.  Being on the top is a
18441                                    // special state, meaning you are specifically running
18442                                    // for the current top app.  If the process is already
18443                                    // running in the background for some other reason, it
18444                                    // is more important to continue considering it to be
18445                                    // in the background state.
18446                                    mayBeTop = true;
18447                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18448                                } else {
18449                                    // Special handling for above-top states (persistent
18450                                    // processes).  These should not bring the current process
18451                                    // into the top state, since they are not on top.  Instead
18452                                    // give them the best state after that.
18453                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18454                                        clientProcState =
18455                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18456                                    } else if (mWakefulness
18457                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18458                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18459                                                    != 0) {
18460                                        clientProcState =
18461                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18462                                    } else {
18463                                        clientProcState =
18464                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18465                                    }
18466                                }
18467                            }
18468                        } else {
18469                            if (clientProcState <
18470                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18471                                clientProcState =
18472                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18473                            }
18474                        }
18475                        if (procState > clientProcState) {
18476                            procState = clientProcState;
18477                        }
18478                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18479                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18480                            app.pendingUiClean = true;
18481                        }
18482                        if (adjType != null) {
18483                            app.adjType = adjType;
18484                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18485                                    .REASON_SERVICE_IN_USE;
18486                            app.adjSource = cr.binding.client;
18487                            app.adjSourceProcState = clientProcState;
18488                            app.adjTarget = s.name;
18489                        }
18490                    }
18491                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18492                        app.treatLikeActivity = true;
18493                    }
18494                    final ActivityRecord a = cr.activity;
18495                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18496                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18497                                (a.visible || a.state == ActivityState.RESUMED
18498                                 || a.state == ActivityState.PAUSING)) {
18499                            adj = ProcessList.FOREGROUND_APP_ADJ;
18500                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18501                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18502                            }
18503                            app.cached = false;
18504                            app.adjType = "service";
18505                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18506                                    .REASON_SERVICE_IN_USE;
18507                            app.adjSource = a;
18508                            app.adjSourceProcState = procState;
18509                            app.adjTarget = s.name;
18510                        }
18511                    }
18512                }
18513            }
18514        }
18515
18516        for (int provi = app.pubProviders.size()-1;
18517                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18518                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18519                        || procState > ActivityManager.PROCESS_STATE_TOP);
18520                provi--) {
18521            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18522            for (int i = cpr.connections.size()-1;
18523                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18524                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18525                            || procState > ActivityManager.PROCESS_STATE_TOP);
18526                    i--) {
18527                ContentProviderConnection conn = cpr.connections.get(i);
18528                ProcessRecord client = conn.client;
18529                if (client == app) {
18530                    // Being our own client is not interesting.
18531                    continue;
18532                }
18533                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18534                int clientProcState = client.curProcState;
18535                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18536                    // If the other app is cached for any reason, for purposes here
18537                    // we are going to consider it empty.
18538                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18539                }
18540                if (adj > clientAdj) {
18541                    if (app.hasShownUi && app != mHomeProcess
18542                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18543                        app.adjType = "cch-ui-provider";
18544                    } else {
18545                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18546                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18547                        app.adjType = "provider";
18548                    }
18549                    app.cached &= client.cached;
18550                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18551                            .REASON_PROVIDER_IN_USE;
18552                    app.adjSource = client;
18553                    app.adjSourceProcState = clientProcState;
18554                    app.adjTarget = cpr.name;
18555                }
18556                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18557                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18558                        // Special handling of clients who are in the top state.
18559                        // We *may* want to consider this process to be in the
18560                        // top state as well, but only if there is not another
18561                        // reason for it to be running.  Being on the top is a
18562                        // special state, meaning you are specifically running
18563                        // for the current top app.  If the process is already
18564                        // running in the background for some other reason, it
18565                        // is more important to continue considering it to be
18566                        // in the background state.
18567                        mayBeTop = true;
18568                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18569                    } else {
18570                        // Special handling for above-top states (persistent
18571                        // processes).  These should not bring the current process
18572                        // into the top state, since they are not on top.  Instead
18573                        // give them the best state after that.
18574                        clientProcState =
18575                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18576                    }
18577                }
18578                if (procState > clientProcState) {
18579                    procState = clientProcState;
18580                }
18581                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18582                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18583                }
18584            }
18585            // If the provider has external (non-framework) process
18586            // dependencies, ensure that its adjustment is at least
18587            // FOREGROUND_APP_ADJ.
18588            if (cpr.hasExternalProcessHandles()) {
18589                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18590                    adj = ProcessList.FOREGROUND_APP_ADJ;
18591                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18592                    app.cached = false;
18593                    app.adjType = "provider";
18594                    app.adjTarget = cpr.name;
18595                }
18596                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18597                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18598                }
18599            }
18600        }
18601
18602        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
18603            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18604                adj = ProcessList.PREVIOUS_APP_ADJ;
18605                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18606                app.cached = false;
18607                app.adjType = "provider";
18608            }
18609            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18610                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18611            }
18612        }
18613
18614        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18615            // A client of one of our services or providers is in the top state.  We
18616            // *may* want to be in the top state, but not if we are already running in
18617            // the background for some other reason.  For the decision here, we are going
18618            // to pick out a few specific states that we want to remain in when a client
18619            // is top (states that tend to be longer-term) and otherwise allow it to go
18620            // to the top state.
18621            switch (procState) {
18622                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18623                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18624                case ActivityManager.PROCESS_STATE_SERVICE:
18625                    // These all are longer-term states, so pull them up to the top
18626                    // of the background states, but not all the way to the top state.
18627                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18628                    break;
18629                default:
18630                    // Otherwise, top is a better choice, so take it.
18631                    procState = ActivityManager.PROCESS_STATE_TOP;
18632                    break;
18633            }
18634        }
18635
18636        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18637            if (app.hasClientActivities) {
18638                // This is a cached process, but with client activities.  Mark it so.
18639                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18640                app.adjType = "cch-client-act";
18641            } else if (app.treatLikeActivity) {
18642                // This is a cached process, but somebody wants us to treat it like it has
18643                // an activity, okay!
18644                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18645                app.adjType = "cch-as-act";
18646            }
18647        }
18648
18649        if (adj == ProcessList.SERVICE_ADJ) {
18650            if (doingAll) {
18651                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18652                mNewNumServiceProcs++;
18653                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18654                if (!app.serviceb) {
18655                    // This service isn't far enough down on the LRU list to
18656                    // normally be a B service, but if we are low on RAM and it
18657                    // is large we want to force it down since we would prefer to
18658                    // keep launcher over it.
18659                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18660                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18661                        app.serviceHighRam = true;
18662                        app.serviceb = true;
18663                        //Slog.i(TAG, "ADJ " + app + " high ram!");
18664                    } else {
18665                        mNewNumAServiceProcs++;
18666                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
18667                    }
18668                } else {
18669                    app.serviceHighRam = false;
18670                }
18671            }
18672            if (app.serviceb) {
18673                adj = ProcessList.SERVICE_B_ADJ;
18674            }
18675        }
18676
18677        app.curRawAdj = adj;
18678
18679        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18680        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18681        if (adj > app.maxAdj) {
18682            adj = app.maxAdj;
18683            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18684                schedGroup = Process.THREAD_GROUP_DEFAULT;
18685            }
18686        }
18687
18688        // Do final modification to adj.  Everything we do between here and applying
18689        // the final setAdj must be done in this function, because we will also use
18690        // it when computing the final cached adj later.  Note that we don't need to
18691        // worry about this for max adj above, since max adj will always be used to
18692        // keep it out of the cached vaues.
18693        app.curAdj = app.modifyRawOomAdj(adj);
18694        app.curSchedGroup = schedGroup;
18695        app.curProcState = procState;
18696        app.foregroundActivities = foregroundActivities;
18697
18698        return app.curRawAdj;
18699    }
18700
18701    /**
18702     * Record new PSS sample for a process.
18703     */
18704    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18705        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18706        proc.lastPssTime = now;
18707        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18708        if (DEBUG_PSS) Slog.d(TAG_PSS,
18709                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18710                + " state=" + ProcessList.makeProcStateString(procState));
18711        if (proc.initialIdlePss == 0) {
18712            proc.initialIdlePss = pss;
18713        }
18714        proc.lastPss = pss;
18715        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18716            proc.lastCachedPss = pss;
18717        }
18718
18719        final SparseArray<Pair<Long, String>> watchUids
18720                = mMemWatchProcesses.getMap().get(proc.processName);
18721        Long check = null;
18722        if (watchUids != null) {
18723            Pair<Long, String> val = watchUids.get(proc.uid);
18724            if (val == null) {
18725                val = watchUids.get(0);
18726            }
18727            if (val != null) {
18728                check = val.first;
18729            }
18730        }
18731        if (check != null) {
18732            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18733                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18734                if (!isDebuggable) {
18735                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18736                        isDebuggable = true;
18737                    }
18738                }
18739                if (isDebuggable) {
18740                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18741                    final ProcessRecord myProc = proc;
18742                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
18743                    mMemWatchDumpProcName = proc.processName;
18744                    mMemWatchDumpFile = heapdumpFile.toString();
18745                    mMemWatchDumpPid = proc.pid;
18746                    mMemWatchDumpUid = proc.uid;
18747                    BackgroundThread.getHandler().post(new Runnable() {
18748                        @Override
18749                        public void run() {
18750                            revokeUriPermission(ActivityThread.currentActivityThread()
18751                                            .getApplicationThread(),
18752                                    DumpHeapActivity.JAVA_URI,
18753                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18754                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18755                                    UserHandle.myUserId());
18756                            ParcelFileDescriptor fd = null;
18757                            try {
18758                                heapdumpFile.delete();
18759                                fd = ParcelFileDescriptor.open(heapdumpFile,
18760                                        ParcelFileDescriptor.MODE_CREATE |
18761                                                ParcelFileDescriptor.MODE_TRUNCATE |
18762                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
18763                                                ParcelFileDescriptor.MODE_APPEND);
18764                                IApplicationThread thread = myProc.thread;
18765                                if (thread != null) {
18766                                    try {
18767                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
18768                                                "Requesting dump heap from "
18769                                                + myProc + " to " + heapdumpFile);
18770                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
18771                                    } catch (RemoteException e) {
18772                                    }
18773                                }
18774                            } catch (FileNotFoundException e) {
18775                                e.printStackTrace();
18776                            } finally {
18777                                if (fd != null) {
18778                                    try {
18779                                        fd.close();
18780                                    } catch (IOException e) {
18781                                    }
18782                                }
18783                            }
18784                        }
18785                    });
18786                } else {
18787                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18788                            + ", but debugging not enabled");
18789                }
18790            }
18791        }
18792    }
18793
18794    /**
18795     * Schedule PSS collection of a process.
18796     */
18797    void requestPssLocked(ProcessRecord proc, int procState) {
18798        if (mPendingPssProcesses.contains(proc)) {
18799            return;
18800        }
18801        if (mPendingPssProcesses.size() == 0) {
18802            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18803        }
18804        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18805        proc.pssProcState = procState;
18806        mPendingPssProcesses.add(proc);
18807    }
18808
18809    /**
18810     * Schedule PSS collection of all processes.
18811     */
18812    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18813        if (!always) {
18814            if (now < (mLastFullPssTime +
18815                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18816                return;
18817            }
18818        }
18819        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18820        mLastFullPssTime = now;
18821        mFullPssPending = true;
18822        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18823        mPendingPssProcesses.clear();
18824        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18825            ProcessRecord app = mLruProcesses.get(i);
18826            if (app.thread == null
18827                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18828                continue;
18829            }
18830            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18831                app.pssProcState = app.setProcState;
18832                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18833                        mTestPssMode, isSleeping(), now);
18834                mPendingPssProcesses.add(app);
18835            }
18836        }
18837        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18838    }
18839
18840    public void setTestPssMode(boolean enabled) {
18841        synchronized (this) {
18842            mTestPssMode = enabled;
18843            if (enabled) {
18844                // Whenever we enable the mode, we want to take a snapshot all of current
18845                // process mem use.
18846                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18847            }
18848        }
18849    }
18850
18851    /**
18852     * Ask a given process to GC right now.
18853     */
18854    final void performAppGcLocked(ProcessRecord app) {
18855        try {
18856            app.lastRequestedGc = SystemClock.uptimeMillis();
18857            if (app.thread != null) {
18858                if (app.reportLowMemory) {
18859                    app.reportLowMemory = false;
18860                    app.thread.scheduleLowMemory();
18861                } else {
18862                    app.thread.processInBackground();
18863                }
18864            }
18865        } catch (Exception e) {
18866            // whatever.
18867        }
18868    }
18869
18870    /**
18871     * Returns true if things are idle enough to perform GCs.
18872     */
18873    private final boolean canGcNowLocked() {
18874        boolean processingBroadcasts = false;
18875        for (BroadcastQueue q : mBroadcastQueues) {
18876            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18877                processingBroadcasts = true;
18878            }
18879        }
18880        return !processingBroadcasts
18881                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18882    }
18883
18884    /**
18885     * Perform GCs on all processes that are waiting for it, but only
18886     * if things are idle.
18887     */
18888    final void performAppGcsLocked() {
18889        final int N = mProcessesToGc.size();
18890        if (N <= 0) {
18891            return;
18892        }
18893        if (canGcNowLocked()) {
18894            while (mProcessesToGc.size() > 0) {
18895                ProcessRecord proc = mProcessesToGc.remove(0);
18896                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18897                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18898                            <= SystemClock.uptimeMillis()) {
18899                        // To avoid spamming the system, we will GC processes one
18900                        // at a time, waiting a few seconds between each.
18901                        performAppGcLocked(proc);
18902                        scheduleAppGcsLocked();
18903                        return;
18904                    } else {
18905                        // It hasn't been long enough since we last GCed this
18906                        // process...  put it in the list to wait for its time.
18907                        addProcessToGcListLocked(proc);
18908                        break;
18909                    }
18910                }
18911            }
18912
18913            scheduleAppGcsLocked();
18914        }
18915    }
18916
18917    /**
18918     * If all looks good, perform GCs on all processes waiting for them.
18919     */
18920    final void performAppGcsIfAppropriateLocked() {
18921        if (canGcNowLocked()) {
18922            performAppGcsLocked();
18923            return;
18924        }
18925        // Still not idle, wait some more.
18926        scheduleAppGcsLocked();
18927    }
18928
18929    /**
18930     * Schedule the execution of all pending app GCs.
18931     */
18932    final void scheduleAppGcsLocked() {
18933        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18934
18935        if (mProcessesToGc.size() > 0) {
18936            // Schedule a GC for the time to the next process.
18937            ProcessRecord proc = mProcessesToGc.get(0);
18938            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18939
18940            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18941            long now = SystemClock.uptimeMillis();
18942            if (when < (now+GC_TIMEOUT)) {
18943                when = now + GC_TIMEOUT;
18944            }
18945            mHandler.sendMessageAtTime(msg, when);
18946        }
18947    }
18948
18949    /**
18950     * Add a process to the array of processes waiting to be GCed.  Keeps the
18951     * list in sorted order by the last GC time.  The process can't already be
18952     * on the list.
18953     */
18954    final void addProcessToGcListLocked(ProcessRecord proc) {
18955        boolean added = false;
18956        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18957            if (mProcessesToGc.get(i).lastRequestedGc <
18958                    proc.lastRequestedGc) {
18959                added = true;
18960                mProcessesToGc.add(i+1, proc);
18961                break;
18962            }
18963        }
18964        if (!added) {
18965            mProcessesToGc.add(0, proc);
18966        }
18967    }
18968
18969    /**
18970     * Set up to ask a process to GC itself.  This will either do it
18971     * immediately, or put it on the list of processes to gc the next
18972     * time things are idle.
18973     */
18974    final void scheduleAppGcLocked(ProcessRecord app) {
18975        long now = SystemClock.uptimeMillis();
18976        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18977            return;
18978        }
18979        if (!mProcessesToGc.contains(app)) {
18980            addProcessToGcListLocked(app);
18981            scheduleAppGcsLocked();
18982        }
18983    }
18984
18985    final void checkExcessivePowerUsageLocked(boolean doKills) {
18986        updateCpuStatsNow();
18987
18988        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18989        boolean doWakeKills = doKills;
18990        boolean doCpuKills = doKills;
18991        if (mLastPowerCheckRealtime == 0) {
18992            doWakeKills = false;
18993        }
18994        if (mLastPowerCheckUptime == 0) {
18995            doCpuKills = false;
18996        }
18997        if (stats.isScreenOn()) {
18998            doWakeKills = false;
18999        }
19000        final long curRealtime = SystemClock.elapsedRealtime();
19001        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19002        final long curUptime = SystemClock.uptimeMillis();
19003        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19004        mLastPowerCheckRealtime = curRealtime;
19005        mLastPowerCheckUptime = curUptime;
19006        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19007            doWakeKills = false;
19008        }
19009        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19010            doCpuKills = false;
19011        }
19012        int i = mLruProcesses.size();
19013        while (i > 0) {
19014            i--;
19015            ProcessRecord app = mLruProcesses.get(i);
19016            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19017                long wtime;
19018                synchronized (stats) {
19019                    wtime = stats.getProcessWakeTime(app.info.uid,
19020                            app.pid, curRealtime);
19021                }
19022                long wtimeUsed = wtime - app.lastWakeTime;
19023                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19024                if (DEBUG_POWER) {
19025                    StringBuilder sb = new StringBuilder(128);
19026                    sb.append("Wake for ");
19027                    app.toShortString(sb);
19028                    sb.append(": over ");
19029                    TimeUtils.formatDuration(realtimeSince, sb);
19030                    sb.append(" used ");
19031                    TimeUtils.formatDuration(wtimeUsed, sb);
19032                    sb.append(" (");
19033                    sb.append((wtimeUsed*100)/realtimeSince);
19034                    sb.append("%)");
19035                    Slog.i(TAG_POWER, sb.toString());
19036                    sb.setLength(0);
19037                    sb.append("CPU for ");
19038                    app.toShortString(sb);
19039                    sb.append(": over ");
19040                    TimeUtils.formatDuration(uptimeSince, sb);
19041                    sb.append(" used ");
19042                    TimeUtils.formatDuration(cputimeUsed, sb);
19043                    sb.append(" (");
19044                    sb.append((cputimeUsed*100)/uptimeSince);
19045                    sb.append("%)");
19046                    Slog.i(TAG_POWER, sb.toString());
19047                }
19048                // If a process has held a wake lock for more
19049                // than 50% of the time during this period,
19050                // that sounds bad.  Kill!
19051                if (doWakeKills && realtimeSince > 0
19052                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19053                    synchronized (stats) {
19054                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19055                                realtimeSince, wtimeUsed);
19056                    }
19057                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19058                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19059                } else if (doCpuKills && uptimeSince > 0
19060                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19061                    synchronized (stats) {
19062                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19063                                uptimeSince, cputimeUsed);
19064                    }
19065                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19066                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19067                } else {
19068                    app.lastWakeTime = wtime;
19069                    app.lastCpuTime = app.curCpuTime;
19070                }
19071            }
19072        }
19073    }
19074
19075    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19076            long nowElapsed) {
19077        boolean success = true;
19078
19079        if (app.curRawAdj != app.setRawAdj) {
19080            app.setRawAdj = app.curRawAdj;
19081        }
19082
19083        int changes = 0;
19084
19085        if (app.curAdj != app.setAdj) {
19086            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19087            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19088                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19089                    + app.adjType);
19090            app.setAdj = app.curAdj;
19091        }
19092
19093        if (app.setSchedGroup != app.curSchedGroup) {
19094            app.setSchedGroup = app.curSchedGroup;
19095            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19096                    "Setting process group of " + app.processName
19097                    + " to " + app.curSchedGroup);
19098            if (app.waitingToKill != null && app.curReceiver == null
19099                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
19100                app.kill(app.waitingToKill, true);
19101                success = false;
19102            } else {
19103                if (true) {
19104                    long oldId = Binder.clearCallingIdentity();
19105                    try {
19106                        Process.setProcessGroup(app.pid, app.curSchedGroup);
19107                    } catch (Exception e) {
19108                        Slog.w(TAG, "Failed setting process group of " + app.pid
19109                                + " to " + app.curSchedGroup);
19110                        e.printStackTrace();
19111                    } finally {
19112                        Binder.restoreCallingIdentity(oldId);
19113                    }
19114                } else {
19115                    if (app.thread != null) {
19116                        try {
19117                            app.thread.setSchedulingGroup(app.curSchedGroup);
19118                        } catch (RemoteException e) {
19119                        }
19120                    }
19121                }
19122            }
19123        }
19124        if (app.repForegroundActivities != app.foregroundActivities) {
19125            app.repForegroundActivities = app.foregroundActivities;
19126            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19127        }
19128        if (app.repProcState != app.curProcState) {
19129            app.repProcState = app.curProcState;
19130            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19131            if (app.thread != null) {
19132                try {
19133                    if (false) {
19134                        //RuntimeException h = new RuntimeException("here");
19135                        Slog.i(TAG, "Sending new process state " + app.repProcState
19136                                + " to " + app /*, h*/);
19137                    }
19138                    app.thread.setProcessState(app.repProcState);
19139                } catch (RemoteException e) {
19140                }
19141            }
19142        }
19143        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19144                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19145            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19146                // Experimental code to more aggressively collect pss while
19147                // running test...  the problem is that this tends to collect
19148                // the data right when a process is transitioning between process
19149                // states, which well tend to give noisy data.
19150                long start = SystemClock.uptimeMillis();
19151                long pss = Debug.getPss(app.pid, mTmpLong, null);
19152                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
19153                mPendingPssProcesses.remove(app);
19154                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19155                        + " to " + app.curProcState + ": "
19156                        + (SystemClock.uptimeMillis()-start) + "ms");
19157            }
19158            app.lastStateTime = now;
19159            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19160                    mTestPssMode, isSleeping(), now);
19161            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19162                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19163                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19164                    + (app.nextPssTime-now) + ": " + app);
19165        } else {
19166            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19167                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19168                    mTestPssMode)))) {
19169                requestPssLocked(app, app.setProcState);
19170                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19171                        mTestPssMode, isSleeping(), now);
19172            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19173                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19174        }
19175        if (app.setProcState != app.curProcState) {
19176            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19177                    "Proc state change of " + app.processName
19178                            + " to " + app.curProcState);
19179            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19180            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19181            if (setImportant && !curImportant) {
19182                // This app is no longer something we consider important enough to allow to
19183                // use arbitrary amounts of battery power.  Note
19184                // its current wake lock time to later know to kill it if
19185                // it is not behaving well.
19186                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19187                synchronized (stats) {
19188                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19189                            app.pid, nowElapsed);
19190                }
19191                app.lastCpuTime = app.curCpuTime;
19192
19193            }
19194            // Inform UsageStats of important process state change
19195            // Must be called before updating setProcState
19196            maybeUpdateUsageStatsLocked(app, nowElapsed);
19197
19198            app.setProcState = app.curProcState;
19199            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19200                app.notCachedSinceIdle = false;
19201            }
19202            if (!doingAll) {
19203                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19204            } else {
19205                app.procStateChanged = true;
19206            }
19207        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19208                > USAGE_STATS_INTERACTION_INTERVAL) {
19209            // For apps that sit around for a long time in the interactive state, we need
19210            // to report this at least once a day so they don't go idle.
19211            maybeUpdateUsageStatsLocked(app, nowElapsed);
19212        }
19213
19214        if (changes != 0) {
19215            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19216                    "Changes in " + app + ": " + changes);
19217            int i = mPendingProcessChanges.size()-1;
19218            ProcessChangeItem item = null;
19219            while (i >= 0) {
19220                item = mPendingProcessChanges.get(i);
19221                if (item.pid == app.pid) {
19222                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19223                            "Re-using existing item: " + item);
19224                    break;
19225                }
19226                i--;
19227            }
19228            if (i < 0) {
19229                // No existing item in pending changes; need a new one.
19230                final int NA = mAvailProcessChanges.size();
19231                if (NA > 0) {
19232                    item = mAvailProcessChanges.remove(NA-1);
19233                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19234                            "Retrieving available item: " + item);
19235                } else {
19236                    item = new ProcessChangeItem();
19237                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19238                            "Allocating new item: " + item);
19239                }
19240                item.changes = 0;
19241                item.pid = app.pid;
19242                item.uid = app.info.uid;
19243                if (mPendingProcessChanges.size() == 0) {
19244                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19245                            "*** Enqueueing dispatch processes changed!");
19246                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19247                }
19248                mPendingProcessChanges.add(item);
19249            }
19250            item.changes |= changes;
19251            item.processState = app.repProcState;
19252            item.foregroundActivities = app.repForegroundActivities;
19253            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19254                    "Item " + Integer.toHexString(System.identityHashCode(item))
19255                    + " " + app.toShortString() + ": changes=" + item.changes
19256                    + " procState=" + item.processState
19257                    + " foreground=" + item.foregroundActivities
19258                    + " type=" + app.adjType + " source=" + app.adjSource
19259                    + " target=" + app.adjTarget);
19260        }
19261
19262        return success;
19263    }
19264
19265    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19266        final UidRecord.ChangeItem pendingChange;
19267        if (uidRec == null || uidRec.pendingChange == null) {
19268            if (mPendingUidChanges.size() == 0) {
19269                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19270                        "*** Enqueueing dispatch uid changed!");
19271                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19272            }
19273            final int NA = mAvailUidChanges.size();
19274            if (NA > 0) {
19275                pendingChange = mAvailUidChanges.remove(NA-1);
19276                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19277                        "Retrieving available item: " + pendingChange);
19278            } else {
19279                pendingChange = new UidRecord.ChangeItem();
19280                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19281                        "Allocating new item: " + pendingChange);
19282            }
19283            if (uidRec != null) {
19284                uidRec.pendingChange = pendingChange;
19285                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19286                    // If this uid is going away, and we haven't yet reported it is gone,
19287                    // then do so now.
19288                    change = UidRecord.CHANGE_GONE_IDLE;
19289                }
19290            } else if (uid < 0) {
19291                throw new IllegalArgumentException("No UidRecord or uid");
19292            }
19293            pendingChange.uidRecord = uidRec;
19294            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19295            mPendingUidChanges.add(pendingChange);
19296        } else {
19297            pendingChange = uidRec.pendingChange;
19298            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19299                change = UidRecord.CHANGE_GONE_IDLE;
19300            }
19301        }
19302        pendingChange.change = change;
19303        pendingChange.processState = uidRec != null
19304                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19305    }
19306
19307    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19308            String authority) {
19309        if (app == null) return;
19310        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19311            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19312            if (userState == null) return;
19313            final long now = SystemClock.elapsedRealtime();
19314            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19315            if (lastReported == null || lastReported < now - 60 * 1000L) {
19316                mUsageStatsService.reportContentProviderUsage(
19317                        authority, providerPkgName, app.userId);
19318                userState.mProviderLastReportedFg.put(authority, now);
19319            }
19320        }
19321    }
19322
19323    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19324        if (DEBUG_USAGE_STATS) {
19325            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19326                    + "] state changes: old = " + app.setProcState + ", new = "
19327                    + app.curProcState);
19328        }
19329        if (mUsageStatsService == null) {
19330            return;
19331        }
19332        boolean isInteraction;
19333        // To avoid some abuse patterns, we are going to be careful about what we consider
19334        // to be an app interaction.  Being the top activity doesn't count while the display
19335        // is sleeping, nor do short foreground services.
19336        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19337            isInteraction = true;
19338            app.fgInteractionTime = 0;
19339        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19340            if (app.fgInteractionTime == 0) {
19341                app.fgInteractionTime = nowElapsed;
19342                isInteraction = false;
19343            } else {
19344                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19345            }
19346        } else {
19347            isInteraction = app.curProcState
19348                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19349            app.fgInteractionTime = 0;
19350        }
19351        if (isInteraction && (!app.reportedInteraction
19352                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19353            app.interactionEventTime = nowElapsed;
19354            String[] packages = app.getPackageList();
19355            if (packages != null) {
19356                for (int i = 0; i < packages.length; i++) {
19357                    mUsageStatsService.reportEvent(packages[i], app.userId,
19358                            UsageEvents.Event.SYSTEM_INTERACTION);
19359                }
19360            }
19361        }
19362        app.reportedInteraction = isInteraction;
19363        if (!isInteraction) {
19364            app.interactionEventTime = 0;
19365        }
19366    }
19367
19368    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19369        if (proc.thread != null) {
19370            if (proc.baseProcessTracker != null) {
19371                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19372            }
19373            if (proc.repProcState >= 0) {
19374                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
19375                        proc.repProcState);
19376            }
19377        }
19378    }
19379
19380    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19381            ProcessRecord TOP_APP, boolean doingAll, long now) {
19382        if (app.thread == null) {
19383            return false;
19384        }
19385
19386        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19387
19388        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19389    }
19390
19391    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19392            boolean oomAdj) {
19393        if (isForeground != proc.foregroundServices) {
19394            proc.foregroundServices = isForeground;
19395            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19396                    proc.info.uid);
19397            if (isForeground) {
19398                if (curProcs == null) {
19399                    curProcs = new ArrayList<ProcessRecord>();
19400                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19401                }
19402                if (!curProcs.contains(proc)) {
19403                    curProcs.add(proc);
19404                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19405                            proc.info.packageName, proc.info.uid);
19406                }
19407            } else {
19408                if (curProcs != null) {
19409                    if (curProcs.remove(proc)) {
19410                        mBatteryStatsService.noteEvent(
19411                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19412                                proc.info.packageName, proc.info.uid);
19413                        if (curProcs.size() <= 0) {
19414                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19415                        }
19416                    }
19417                }
19418            }
19419            if (oomAdj) {
19420                updateOomAdjLocked();
19421            }
19422        }
19423    }
19424
19425    private final ActivityRecord resumedAppLocked() {
19426        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19427        String pkg;
19428        int uid;
19429        if (act != null) {
19430            pkg = act.packageName;
19431            uid = act.info.applicationInfo.uid;
19432        } else {
19433            pkg = null;
19434            uid = -1;
19435        }
19436        // Has the UID or resumed package name changed?
19437        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19438                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19439            if (mCurResumedPackage != null) {
19440                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19441                        mCurResumedPackage, mCurResumedUid);
19442            }
19443            mCurResumedPackage = pkg;
19444            mCurResumedUid = uid;
19445            if (mCurResumedPackage != null) {
19446                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19447                        mCurResumedPackage, mCurResumedUid);
19448            }
19449        }
19450        return act;
19451    }
19452
19453    final boolean updateOomAdjLocked(ProcessRecord app) {
19454        final ActivityRecord TOP_ACT = resumedAppLocked();
19455        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19456        final boolean wasCached = app.cached;
19457
19458        mAdjSeq++;
19459
19460        // This is the desired cached adjusment we want to tell it to use.
19461        // If our app is currently cached, we know it, and that is it.  Otherwise,
19462        // we don't know it yet, and it needs to now be cached we will then
19463        // need to do a complete oom adj.
19464        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19465                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19466        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19467                SystemClock.uptimeMillis());
19468        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19469            // Changed to/from cached state, so apps after it in the LRU
19470            // list may also be changed.
19471            updateOomAdjLocked();
19472        }
19473        return success;
19474    }
19475
19476    final void updateOomAdjLocked() {
19477        final ActivityRecord TOP_ACT = resumedAppLocked();
19478        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19479        final long now = SystemClock.uptimeMillis();
19480        final long nowElapsed = SystemClock.elapsedRealtime();
19481        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19482        final int N = mLruProcesses.size();
19483
19484        if (false) {
19485            RuntimeException e = new RuntimeException();
19486            e.fillInStackTrace();
19487            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19488        }
19489
19490        // Reset state in all uid records.
19491        for (int i=mActiveUids.size()-1; i>=0; i--) {
19492            final UidRecord uidRec = mActiveUids.valueAt(i);
19493            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19494                    "Starting update of " + uidRec);
19495            uidRec.reset();
19496        }
19497
19498        mStackSupervisor.rankTaskLayersIfNeeded();
19499
19500        mAdjSeq++;
19501        mNewNumServiceProcs = 0;
19502        mNewNumAServiceProcs = 0;
19503
19504        final int emptyProcessLimit;
19505        final int cachedProcessLimit;
19506        if (mProcessLimit <= 0) {
19507            emptyProcessLimit = cachedProcessLimit = 0;
19508        } else if (mProcessLimit == 1) {
19509            emptyProcessLimit = 1;
19510            cachedProcessLimit = 0;
19511        } else {
19512            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19513            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19514        }
19515
19516        // Let's determine how many processes we have running vs.
19517        // how many slots we have for background processes; we may want
19518        // to put multiple processes in a slot of there are enough of
19519        // them.
19520        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19521                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19522        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19523        if (numEmptyProcs > cachedProcessLimit) {
19524            // If there are more empty processes than our limit on cached
19525            // processes, then use the cached process limit for the factor.
19526            // This ensures that the really old empty processes get pushed
19527            // down to the bottom, so if we are running low on memory we will
19528            // have a better chance at keeping around more cached processes
19529            // instead of a gazillion empty processes.
19530            numEmptyProcs = cachedProcessLimit;
19531        }
19532        int emptyFactor = numEmptyProcs/numSlots;
19533        if (emptyFactor < 1) emptyFactor = 1;
19534        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19535        if (cachedFactor < 1) cachedFactor = 1;
19536        int stepCached = 0;
19537        int stepEmpty = 0;
19538        int numCached = 0;
19539        int numEmpty = 0;
19540        int numTrimming = 0;
19541
19542        mNumNonCachedProcs = 0;
19543        mNumCachedHiddenProcs = 0;
19544
19545        // First update the OOM adjustment for each of the
19546        // application processes based on their current state.
19547        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19548        int nextCachedAdj = curCachedAdj+1;
19549        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19550        int nextEmptyAdj = curEmptyAdj+2;
19551        for (int i=N-1; i>=0; i--) {
19552            ProcessRecord app = mLruProcesses.get(i);
19553            if (!app.killedByAm && app.thread != null) {
19554                app.procStateChanged = false;
19555                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19556
19557                // If we haven't yet assigned the final cached adj
19558                // to the process, do that now.
19559                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19560                    switch (app.curProcState) {
19561                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19562                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19563                            // This process is a cached process holding activities...
19564                            // assign it the next cached value for that type, and then
19565                            // step that cached level.
19566                            app.curRawAdj = curCachedAdj;
19567                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19568                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19569                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19570                                    + ")");
19571                            if (curCachedAdj != nextCachedAdj) {
19572                                stepCached++;
19573                                if (stepCached >= cachedFactor) {
19574                                    stepCached = 0;
19575                                    curCachedAdj = nextCachedAdj;
19576                                    nextCachedAdj += 2;
19577                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19578                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19579                                    }
19580                                }
19581                            }
19582                            break;
19583                        default:
19584                            // For everything else, assign next empty cached process
19585                            // level and bump that up.  Note that this means that
19586                            // long-running services that have dropped down to the
19587                            // cached level will be treated as empty (since their process
19588                            // state is still as a service), which is what we want.
19589                            app.curRawAdj = curEmptyAdj;
19590                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19591                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19592                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19593                                    + ")");
19594                            if (curEmptyAdj != nextEmptyAdj) {
19595                                stepEmpty++;
19596                                if (stepEmpty >= emptyFactor) {
19597                                    stepEmpty = 0;
19598                                    curEmptyAdj = nextEmptyAdj;
19599                                    nextEmptyAdj += 2;
19600                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19601                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19602                                    }
19603                                }
19604                            }
19605                            break;
19606                    }
19607                }
19608
19609                applyOomAdjLocked(app, true, now, nowElapsed);
19610
19611                // Count the number of process types.
19612                switch (app.curProcState) {
19613                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19614                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19615                        mNumCachedHiddenProcs++;
19616                        numCached++;
19617                        if (numCached > cachedProcessLimit) {
19618                            app.kill("cached #" + numCached, true);
19619                        }
19620                        break;
19621                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19622                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19623                                && app.lastActivityTime < oldTime) {
19624                            app.kill("empty for "
19625                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19626                                    / 1000) + "s", true);
19627                        } else {
19628                            numEmpty++;
19629                            if (numEmpty > emptyProcessLimit) {
19630                                app.kill("empty #" + numEmpty, true);
19631                            }
19632                        }
19633                        break;
19634                    default:
19635                        mNumNonCachedProcs++;
19636                        break;
19637                }
19638
19639                if (app.isolated && app.services.size() <= 0) {
19640                    // If this is an isolated process, and there are no
19641                    // services running in it, then the process is no longer
19642                    // needed.  We agressively kill these because we can by
19643                    // definition not re-use the same process again, and it is
19644                    // good to avoid having whatever code was running in them
19645                    // left sitting around after no longer needed.
19646                    app.kill("isolated not needed", true);
19647                } else {
19648                    // Keeping this process, update its uid.
19649                    final UidRecord uidRec = app.uidRecord;
19650                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
19651                        uidRec.curProcState = app.curProcState;
19652                    }
19653                }
19654
19655                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19656                        && !app.killedByAm) {
19657                    numTrimming++;
19658                }
19659            }
19660        }
19661
19662        mNumServiceProcs = mNewNumServiceProcs;
19663
19664        // Now determine the memory trimming level of background processes.
19665        // Unfortunately we need to start at the back of the list to do this
19666        // properly.  We only do this if the number of background apps we
19667        // are managing to keep around is less than half the maximum we desire;
19668        // if we are keeping a good number around, we'll let them use whatever
19669        // memory they want.
19670        final int numCachedAndEmpty = numCached + numEmpty;
19671        int memFactor;
19672        if (numCached <= ProcessList.TRIM_CACHED_APPS
19673                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19674            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19675                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19676            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19677                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19678            } else {
19679                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19680            }
19681        } else {
19682            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19683        }
19684        // We always allow the memory level to go up (better).  We only allow it to go
19685        // down if we are in a state where that is allowed, *and* the total number of processes
19686        // has gone down since last time.
19687        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19688                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19689                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19690        if (memFactor > mLastMemoryLevel) {
19691            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19692                memFactor = mLastMemoryLevel;
19693                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19694            }
19695        }
19696        mLastMemoryLevel = memFactor;
19697        mLastNumProcesses = mLruProcesses.size();
19698        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19699        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19700        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19701            if (mLowRamStartTime == 0) {
19702                mLowRamStartTime = now;
19703            }
19704            int step = 0;
19705            int fgTrimLevel;
19706            switch (memFactor) {
19707                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19708                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19709                    break;
19710                case ProcessStats.ADJ_MEM_FACTOR_LOW:
19711                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19712                    break;
19713                default:
19714                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19715                    break;
19716            }
19717            int factor = numTrimming/3;
19718            int minFactor = 2;
19719            if (mHomeProcess != null) minFactor++;
19720            if (mPreviousProcess != null) minFactor++;
19721            if (factor < minFactor) factor = minFactor;
19722            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19723            for (int i=N-1; i>=0; i--) {
19724                ProcessRecord app = mLruProcesses.get(i);
19725                if (allChanged || app.procStateChanged) {
19726                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19727                    app.procStateChanged = false;
19728                }
19729                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19730                        && !app.killedByAm) {
19731                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
19732                        try {
19733                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19734                                    "Trimming memory of " + app.processName + " to " + curLevel);
19735                            app.thread.scheduleTrimMemory(curLevel);
19736                        } catch (RemoteException e) {
19737                        }
19738                        if (false) {
19739                            // For now we won't do this; our memory trimming seems
19740                            // to be good enough at this point that destroying
19741                            // activities causes more harm than good.
19742                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19743                                    && app != mHomeProcess && app != mPreviousProcess) {
19744                                // Need to do this on its own message because the stack may not
19745                                // be in a consistent state at this point.
19746                                // For these apps we will also finish their activities
19747                                // to help them free memory.
19748                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19749                            }
19750                        }
19751                    }
19752                    app.trimMemoryLevel = curLevel;
19753                    step++;
19754                    if (step >= factor) {
19755                        step = 0;
19756                        switch (curLevel) {
19757                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19758                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19759                                break;
19760                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19761                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19762                                break;
19763                        }
19764                    }
19765                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19766                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19767                            && app.thread != null) {
19768                        try {
19769                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19770                                    "Trimming memory of heavy-weight " + app.processName
19771                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19772                            app.thread.scheduleTrimMemory(
19773                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19774                        } catch (RemoteException e) {
19775                        }
19776                    }
19777                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19778                } else {
19779                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19780                            || app.systemNoUi) && app.pendingUiClean) {
19781                        // If this application is now in the background and it
19782                        // had done UI, then give it the special trim level to
19783                        // have it free UI resources.
19784                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19785                        if (app.trimMemoryLevel < level && app.thread != null) {
19786                            try {
19787                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19788                                        "Trimming memory of bg-ui " + app.processName
19789                                        + " to " + level);
19790                                app.thread.scheduleTrimMemory(level);
19791                            } catch (RemoteException e) {
19792                            }
19793                        }
19794                        app.pendingUiClean = false;
19795                    }
19796                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19797                        try {
19798                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19799                                    "Trimming memory of fg " + app.processName
19800                                    + " to " + fgTrimLevel);
19801                            app.thread.scheduleTrimMemory(fgTrimLevel);
19802                        } catch (RemoteException e) {
19803                        }
19804                    }
19805                    app.trimMemoryLevel = fgTrimLevel;
19806                }
19807            }
19808        } else {
19809            if (mLowRamStartTime != 0) {
19810                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19811                mLowRamStartTime = 0;
19812            }
19813            for (int i=N-1; i>=0; i--) {
19814                ProcessRecord app = mLruProcesses.get(i);
19815                if (allChanged || app.procStateChanged) {
19816                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19817                    app.procStateChanged = false;
19818                }
19819                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19820                        || app.systemNoUi) && app.pendingUiClean) {
19821                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19822                            && app.thread != null) {
19823                        try {
19824                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19825                                    "Trimming memory of ui hidden " + app.processName
19826                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19827                            app.thread.scheduleTrimMemory(
19828                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19829                        } catch (RemoteException e) {
19830                        }
19831                    }
19832                    app.pendingUiClean = false;
19833                }
19834                app.trimMemoryLevel = 0;
19835            }
19836        }
19837
19838        if (mAlwaysFinishActivities) {
19839            // Need to do this on its own message because the stack may not
19840            // be in a consistent state at this point.
19841            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19842        }
19843
19844        if (allChanged) {
19845            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19846        }
19847
19848        // Update from any uid changes.
19849        for (int i=mActiveUids.size()-1; i>=0; i--) {
19850            final UidRecord uidRec = mActiveUids.valueAt(i);
19851            int uidChange = UidRecord.CHANGE_PROCSTATE;
19852            if (uidRec.setProcState != uidRec.curProcState) {
19853                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19854                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19855                        + " to " + uidRec.curProcState);
19856                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
19857                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
19858                        uidRec.lastBackgroundTime = nowElapsed;
19859                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
19860                            // Note: the background settle time is in elapsed realtime, while
19861                            // the handler time base is uptime.  All this means is that we may
19862                            // stop background uids later than we had intended, but that only
19863                            // happens because the device was sleeping so we are okay anyway.
19864                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
19865                        }
19866                    }
19867                } else {
19868                    if (uidRec.idle) {
19869                        uidChange = UidRecord.CHANGE_ACTIVE;
19870                        uidRec.idle = false;
19871                    }
19872                    uidRec.lastBackgroundTime = 0;
19873                }
19874                uidRec.setProcState = uidRec.curProcState;
19875                enqueueUidChangeLocked(uidRec, -1, uidChange);
19876            }
19877        }
19878
19879        if (mProcessStats.shouldWriteNowLocked(now)) {
19880            mHandler.post(new Runnable() {
19881                @Override public void run() {
19882                    synchronized (ActivityManagerService.this) {
19883                        mProcessStats.writeStateAsyncLocked();
19884                    }
19885                }
19886            });
19887        }
19888
19889        if (DEBUG_OOM_ADJ) {
19890            final long duration = SystemClock.uptimeMillis() - now;
19891            if (false) {
19892                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19893                        new RuntimeException("here").fillInStackTrace());
19894            } else {
19895                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19896            }
19897        }
19898    }
19899
19900    final void idleUids() {
19901        synchronized (this) {
19902            final long nowElapsed = SystemClock.elapsedRealtime();
19903            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
19904            long nextTime = 0;
19905            for (int i=mActiveUids.size()-1; i>=0; i--) {
19906                final UidRecord uidRec = mActiveUids.valueAt(i);
19907                final long bgTime = uidRec.lastBackgroundTime;
19908                if (bgTime > 0 && !uidRec.idle) {
19909                    if (bgTime <= maxBgTime) {
19910                        uidRec.idle = true;
19911                        doStopUidLocked(uidRec.uid, uidRec);
19912                    } else {
19913                        if (nextTime == 0 || nextTime > bgTime) {
19914                            nextTime = bgTime;
19915                        }
19916                    }
19917                }
19918            }
19919            if (nextTime > 0) {
19920                mHandler.removeMessages(IDLE_UIDS_MSG);
19921                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
19922                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
19923            }
19924        }
19925    }
19926
19927    final void runInBackgroundDisabled(int uid) {
19928        synchronized (this) {
19929            UidRecord uidRec = mActiveUids.get(uid);
19930            if (uidRec != null) {
19931                // This uid is actually running...  should it be considered background now?
19932                if (uidRec.idle) {
19933                    doStopUidLocked(uidRec.uid, uidRec);
19934                }
19935            } else {
19936                // This uid isn't actually running...  still send a report about it being "stopped".
19937                doStopUidLocked(uid, null);
19938            }
19939        }
19940    }
19941
19942    final void doStopUidLocked(int uid, final UidRecord uidRec) {
19943        mServices.stopInBackgroundLocked(uid);
19944        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
19945    }
19946
19947    final void trimApplications() {
19948        synchronized (this) {
19949            int i;
19950
19951            // First remove any unused application processes whose package
19952            // has been removed.
19953            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19954                final ProcessRecord app = mRemovedProcesses.get(i);
19955                if (app.activities.size() == 0
19956                        && app.curReceiver == null && app.services.size() == 0) {
19957                    Slog.i(
19958                        TAG, "Exiting empty application process "
19959                        + app.processName + " ("
19960                        + (app.thread != null ? app.thread.asBinder() : null)
19961                        + ")\n");
19962                    if (app.pid > 0 && app.pid != MY_PID) {
19963                        app.kill("empty", false);
19964                    } else {
19965                        try {
19966                            app.thread.scheduleExit();
19967                        } catch (Exception e) {
19968                            // Ignore exceptions.
19969                        }
19970                    }
19971                    cleanUpApplicationRecordLocked(app, false, true, -1);
19972                    mRemovedProcesses.remove(i);
19973
19974                    if (app.persistent) {
19975                        addAppLocked(app.info, false, null /* ABI override */);
19976                    }
19977                }
19978            }
19979
19980            // Now update the oom adj for all processes.
19981            updateOomAdjLocked();
19982        }
19983    }
19984
19985    /** This method sends the specified signal to each of the persistent apps */
19986    public void signalPersistentProcesses(int sig) throws RemoteException {
19987        if (sig != Process.SIGNAL_USR1) {
19988            throw new SecurityException("Only SIGNAL_USR1 is allowed");
19989        }
19990
19991        synchronized (this) {
19992            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19993                    != PackageManager.PERMISSION_GRANTED) {
19994                throw new SecurityException("Requires permission "
19995                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19996            }
19997
19998            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19999                ProcessRecord r = mLruProcesses.get(i);
20000                if (r.thread != null && r.persistent) {
20001                    Process.sendSignal(r.pid, sig);
20002                }
20003            }
20004        }
20005    }
20006
20007    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20008        if (proc == null || proc == mProfileProc) {
20009            proc = mProfileProc;
20010            profileType = mProfileType;
20011            clearProfilerLocked();
20012        }
20013        if (proc == null) {
20014            return;
20015        }
20016        try {
20017            proc.thread.profilerControl(false, null, profileType);
20018        } catch (RemoteException e) {
20019            throw new IllegalStateException("Process disappeared");
20020        }
20021    }
20022
20023    private void clearProfilerLocked() {
20024        if (mProfileFd != null) {
20025            try {
20026                mProfileFd.close();
20027            } catch (IOException e) {
20028            }
20029        }
20030        mProfileApp = null;
20031        mProfileProc = null;
20032        mProfileFile = null;
20033        mProfileType = 0;
20034        mAutoStopProfiler = false;
20035        mSamplingInterval = 0;
20036    }
20037
20038    public boolean profileControl(String process, int userId, boolean start,
20039            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20040
20041        try {
20042            synchronized (this) {
20043                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20044                // its own permission.
20045                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20046                        != PackageManager.PERMISSION_GRANTED) {
20047                    throw new SecurityException("Requires permission "
20048                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20049                }
20050
20051                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20052                    throw new IllegalArgumentException("null profile info or fd");
20053                }
20054
20055                ProcessRecord proc = null;
20056                if (process != null) {
20057                    proc = findProcessLocked(process, userId, "profileControl");
20058                }
20059
20060                if (start && (proc == null || proc.thread == null)) {
20061                    throw new IllegalArgumentException("Unknown process: " + process);
20062                }
20063
20064                if (start) {
20065                    stopProfilerLocked(null, 0);
20066                    setProfileApp(proc.info, proc.processName, profilerInfo);
20067                    mProfileProc = proc;
20068                    mProfileType = profileType;
20069                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20070                    try {
20071                        fd = fd.dup();
20072                    } catch (IOException e) {
20073                        fd = null;
20074                    }
20075                    profilerInfo.profileFd = fd;
20076                    proc.thread.profilerControl(start, profilerInfo, profileType);
20077                    fd = null;
20078                    mProfileFd = null;
20079                } else {
20080                    stopProfilerLocked(proc, profileType);
20081                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20082                        try {
20083                            profilerInfo.profileFd.close();
20084                        } catch (IOException e) {
20085                        }
20086                    }
20087                }
20088
20089                return true;
20090            }
20091        } catch (RemoteException e) {
20092            throw new IllegalStateException("Process disappeared");
20093        } finally {
20094            if (profilerInfo != null && profilerInfo.profileFd != null) {
20095                try {
20096                    profilerInfo.profileFd.close();
20097                } catch (IOException e) {
20098                }
20099            }
20100        }
20101    }
20102
20103    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20104        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20105                userId, true, ALLOW_FULL_ONLY, callName, null);
20106        ProcessRecord proc = null;
20107        try {
20108            int pid = Integer.parseInt(process);
20109            synchronized (mPidsSelfLocked) {
20110                proc = mPidsSelfLocked.get(pid);
20111            }
20112        } catch (NumberFormatException e) {
20113        }
20114
20115        if (proc == null) {
20116            ArrayMap<String, SparseArray<ProcessRecord>> all
20117                    = mProcessNames.getMap();
20118            SparseArray<ProcessRecord> procs = all.get(process);
20119            if (procs != null && procs.size() > 0) {
20120                proc = procs.valueAt(0);
20121                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20122                    for (int i=1; i<procs.size(); i++) {
20123                        ProcessRecord thisProc = procs.valueAt(i);
20124                        if (thisProc.userId == userId) {
20125                            proc = thisProc;
20126                            break;
20127                        }
20128                    }
20129                }
20130            }
20131        }
20132
20133        return proc;
20134    }
20135
20136    public boolean dumpHeap(String process, int userId, boolean managed,
20137            String path, ParcelFileDescriptor fd) throws RemoteException {
20138
20139        try {
20140            synchronized (this) {
20141                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20142                // its own permission (same as profileControl).
20143                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20144                        != PackageManager.PERMISSION_GRANTED) {
20145                    throw new SecurityException("Requires permission "
20146                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20147                }
20148
20149                if (fd == null) {
20150                    throw new IllegalArgumentException("null fd");
20151                }
20152
20153                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20154                if (proc == null || proc.thread == null) {
20155                    throw new IllegalArgumentException("Unknown process: " + process);
20156                }
20157
20158                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20159                if (!isDebuggable) {
20160                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20161                        throw new SecurityException("Process not debuggable: " + proc);
20162                    }
20163                }
20164
20165                proc.thread.dumpHeap(managed, path, fd);
20166                fd = null;
20167                return true;
20168            }
20169        } catch (RemoteException e) {
20170            throw new IllegalStateException("Process disappeared");
20171        } finally {
20172            if (fd != null) {
20173                try {
20174                    fd.close();
20175                } catch (IOException e) {
20176                }
20177            }
20178        }
20179    }
20180
20181    @Override
20182    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20183            String reportPackage) {
20184        if (processName != null) {
20185            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20186                    "setDumpHeapDebugLimit()");
20187        } else {
20188            synchronized (mPidsSelfLocked) {
20189                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20190                if (proc == null) {
20191                    throw new SecurityException("No process found for calling pid "
20192                            + Binder.getCallingPid());
20193                }
20194                if (!Build.IS_DEBUGGABLE
20195                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20196                    throw new SecurityException("Not running a debuggable build");
20197                }
20198                processName = proc.processName;
20199                uid = proc.uid;
20200                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20201                    throw new SecurityException("Package " + reportPackage + " is not running in "
20202                            + proc);
20203                }
20204            }
20205        }
20206        synchronized (this) {
20207            if (maxMemSize > 0) {
20208                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20209            } else {
20210                if (uid != 0) {
20211                    mMemWatchProcesses.remove(processName, uid);
20212                } else {
20213                    mMemWatchProcesses.getMap().remove(processName);
20214                }
20215            }
20216        }
20217    }
20218
20219    @Override
20220    public void dumpHeapFinished(String path) {
20221        synchronized (this) {
20222            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20223                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20224                        + " does not match last pid " + mMemWatchDumpPid);
20225                return;
20226            }
20227            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20228                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20229                        + " does not match last path " + mMemWatchDumpFile);
20230                return;
20231            }
20232            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20233            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20234        }
20235    }
20236
20237    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20238    public void monitor() {
20239        synchronized (this) { }
20240    }
20241
20242    void onCoreSettingsChange(Bundle settings) {
20243        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20244            ProcessRecord processRecord = mLruProcesses.get(i);
20245            try {
20246                if (processRecord.thread != null) {
20247                    processRecord.thread.setCoreSettings(settings);
20248                }
20249            } catch (RemoteException re) {
20250                /* ignore */
20251            }
20252        }
20253    }
20254
20255    // Multi-user methods
20256
20257    /**
20258     * Start user, if its not already running, but don't bring it to foreground.
20259     */
20260    @Override
20261    public boolean startUserInBackground(final int userId) {
20262        return mUserController.startUser(userId, /* foreground */ false);
20263    }
20264
20265    @Override
20266    public boolean unlockUser(int userId, byte[] token) {
20267        return mUserController.unlockUser(userId, token);
20268    }
20269
20270    @Override
20271    public boolean switchUser(final int targetUserId) {
20272        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20273        UserInfo currentUserInfo;
20274        UserInfo targetUserInfo;
20275        synchronized (this) {
20276            int currentUserId = mUserController.getCurrentUserIdLocked();
20277            currentUserInfo = mUserController.getUserInfo(currentUserId);
20278            targetUserInfo = mUserController.getUserInfo(targetUserId);
20279            if (targetUserInfo == null) {
20280                Slog.w(TAG, "No user info for user #" + targetUserId);
20281                return false;
20282            }
20283            if (targetUserInfo.isManagedProfile()) {
20284                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20285                return false;
20286            }
20287            mUserController.setTargetUserIdLocked(targetUserId);
20288        }
20289        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20290        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20291        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20292        return true;
20293    }
20294
20295    void scheduleStartProfilesLocked() {
20296        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20297            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20298                    DateUtils.SECOND_IN_MILLIS);
20299        }
20300    }
20301
20302    @Override
20303    public int stopUser(final int userId, final IStopUserCallback callback) {
20304        return mUserController.stopUser(userId, callback);
20305    }
20306
20307    void onUserRemovedLocked(int userId) {
20308        mRecentTasks.removeTasksForUserLocked(userId);
20309    }
20310
20311    @Override
20312    public UserInfo getCurrentUser() {
20313        return mUserController.getCurrentUser();
20314    }
20315
20316    @Override
20317    public boolean isUserRunning(int userId, int flags) {
20318        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20319                != PackageManager.PERMISSION_GRANTED) {
20320            String msg = "Permission Denial: isUserRunning() from pid="
20321                    + Binder.getCallingPid()
20322                    + ", uid=" + Binder.getCallingUid()
20323                    + " requires " + INTERACT_ACROSS_USERS;
20324            Slog.w(TAG, msg);
20325            throw new SecurityException(msg);
20326        }
20327        synchronized (this) {
20328            return mUserController.isUserRunningLocked(userId, flags);
20329        }
20330    }
20331
20332    @Override
20333    public int[] getRunningUserIds() {
20334        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20335                != PackageManager.PERMISSION_GRANTED) {
20336            String msg = "Permission Denial: isUserRunning() from pid="
20337                    + Binder.getCallingPid()
20338                    + ", uid=" + Binder.getCallingUid()
20339                    + " requires " + INTERACT_ACROSS_USERS;
20340            Slog.w(TAG, msg);
20341            throw new SecurityException(msg);
20342        }
20343        synchronized (this) {
20344            return mUserController.getStartedUserArrayLocked();
20345        }
20346    }
20347
20348    @Override
20349    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20350        mUserController.registerUserSwitchObserver(observer);
20351    }
20352
20353    @Override
20354    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20355        mUserController.unregisterUserSwitchObserver(observer);
20356    }
20357
20358    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20359        if (info == null) return null;
20360        ApplicationInfo newInfo = new ApplicationInfo(info);
20361        newInfo.initForUser(userId);
20362        return newInfo;
20363    }
20364
20365    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20366        if (aInfo == null
20367                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20368            return aInfo;
20369        }
20370
20371        ActivityInfo info = new ActivityInfo(aInfo);
20372        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20373        return info;
20374    }
20375
20376    private boolean processSanityChecksLocked(ProcessRecord process) {
20377        if (process == null || process.thread == null) {
20378            return false;
20379        }
20380
20381        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20382        if (!isDebuggable) {
20383            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20384                return false;
20385            }
20386        }
20387
20388        return true;
20389    }
20390
20391    public boolean startBinderTracking() throws RemoteException {
20392        synchronized (this) {
20393            mBinderTransactionTrackingEnabled = true;
20394            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20395            // permission (same as profileControl).
20396            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20397                    != PackageManager.PERMISSION_GRANTED) {
20398                throw new SecurityException("Requires permission "
20399                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20400            }
20401
20402            for (int i = 0; i < mLruProcesses.size(); i++) {
20403                ProcessRecord process = mLruProcesses.get(i);
20404                if (!processSanityChecksLocked(process)) {
20405                    continue;
20406                }
20407                try {
20408                    process.thread.startBinderTracking();
20409                } catch (RemoteException e) {
20410                    Log.v(TAG, "Process disappared");
20411                }
20412            }
20413            return true;
20414        }
20415    }
20416
20417    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20418        try {
20419            synchronized (this) {
20420                mBinderTransactionTrackingEnabled = false;
20421                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20422                // permission (same as profileControl).
20423                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20424                        != PackageManager.PERMISSION_GRANTED) {
20425                    throw new SecurityException("Requires permission "
20426                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20427                }
20428
20429                if (fd == null) {
20430                    throw new IllegalArgumentException("null fd");
20431                }
20432
20433                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20434                pw.println("Binder transaction traces for all processes.\n");
20435                for (ProcessRecord process : mLruProcesses) {
20436                    if (!processSanityChecksLocked(process)) {
20437                        continue;
20438                    }
20439
20440                    pw.println("Traces for process: " + process.processName);
20441                    pw.flush();
20442                    try {
20443                        TransferPipe tp = new TransferPipe();
20444                        try {
20445                            process.thread.stopBinderTrackingAndDump(
20446                                    tp.getWriteFd().getFileDescriptor());
20447                            tp.go(fd.getFileDescriptor());
20448                        } finally {
20449                            tp.kill();
20450                        }
20451                    } catch (IOException e) {
20452                        pw.println("Failure while dumping IPC traces from " + process +
20453                                ".  Exception: " + e);
20454                        pw.flush();
20455                    } catch (RemoteException e) {
20456                        pw.println("Got a RemoteException while dumping IPC traces from " +
20457                                process + ".  Exception: " + e);
20458                        pw.flush();
20459                    }
20460                }
20461                fd = null;
20462                return true;
20463            }
20464        } finally {
20465            if (fd != null) {
20466                try {
20467                    fd.close();
20468                } catch (IOException e) {
20469                }
20470            }
20471        }
20472    }
20473
20474    void stopReportingCrashesLocked(ProcessRecord proc) {
20475        if (mAppsNotReportingCrashes == null) {
20476            mAppsNotReportingCrashes = new ArraySet<>();
20477        }
20478        mAppsNotReportingCrashes.add(proc.info.packageName);
20479    }
20480
20481    private final class LocalService extends ActivityManagerInternal {
20482        @Override
20483        public void onWakefulnessChanged(int wakefulness) {
20484            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20485        }
20486
20487        @Override
20488        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20489                String processName, String abiOverride, int uid, Runnable crashHandler) {
20490            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20491                    processName, abiOverride, uid, crashHandler);
20492        }
20493
20494        @Override
20495        public SleepToken acquireSleepToken(String tag) {
20496            Preconditions.checkNotNull(tag);
20497
20498            synchronized (ActivityManagerService.this) {
20499                SleepTokenImpl token = new SleepTokenImpl(tag);
20500                mSleepTokens.add(token);
20501                updateSleepIfNeededLocked();
20502                return token;
20503            }
20504        }
20505
20506        @Override
20507        public ComponentName getHomeActivityForUser(int userId) {
20508            synchronized (ActivityManagerService.this) {
20509                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20510                return homeActivity == null ? null : homeActivity.realActivity;
20511            }
20512        }
20513
20514        @Override
20515        public void onUserRemoved(int userId) {
20516            synchronized (ActivityManagerService.this) {
20517                ActivityManagerService.this.onUserRemovedLocked(userId);
20518            }
20519        }
20520    }
20521
20522    private final class SleepTokenImpl extends SleepToken {
20523        private final String mTag;
20524        private final long mAcquireTime;
20525
20526        public SleepTokenImpl(String tag) {
20527            mTag = tag;
20528            mAcquireTime = SystemClock.uptimeMillis();
20529        }
20530
20531        @Override
20532        public void release() {
20533            synchronized (ActivityManagerService.this) {
20534                if (mSleepTokens.remove(this)) {
20535                    updateSleepIfNeededLocked();
20536                }
20537            }
20538        }
20539
20540        @Override
20541        public String toString() {
20542            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20543        }
20544    }
20545
20546    /**
20547     * An implementation of IAppTask, that allows an app to manage its own tasks via
20548     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20549     * only the process that calls getAppTasks() can call the AppTask methods.
20550     */
20551    class AppTaskImpl extends IAppTask.Stub {
20552        private int mTaskId;
20553        private int mCallingUid;
20554
20555        public AppTaskImpl(int taskId, int callingUid) {
20556            mTaskId = taskId;
20557            mCallingUid = callingUid;
20558        }
20559
20560        private void checkCaller() {
20561            if (mCallingUid != Binder.getCallingUid()) {
20562                throw new SecurityException("Caller " + mCallingUid
20563                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20564            }
20565        }
20566
20567        @Override
20568        public void finishAndRemoveTask() {
20569            checkCaller();
20570
20571            synchronized (ActivityManagerService.this) {
20572                long origId = Binder.clearCallingIdentity();
20573                try {
20574                    // We remove the task from recents to preserve backwards
20575                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
20576                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20577                    }
20578                } finally {
20579                    Binder.restoreCallingIdentity(origId);
20580                }
20581            }
20582        }
20583
20584        @Override
20585        public ActivityManager.RecentTaskInfo getTaskInfo() {
20586            checkCaller();
20587
20588            synchronized (ActivityManagerService.this) {
20589                long origId = Binder.clearCallingIdentity();
20590                try {
20591                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20592                    if (tr == null) {
20593                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20594                    }
20595                    return createRecentTaskInfoFromTaskRecord(tr);
20596                } finally {
20597                    Binder.restoreCallingIdentity(origId);
20598                }
20599            }
20600        }
20601
20602        @Override
20603        public void moveToFront() {
20604            checkCaller();
20605            // Will bring task to front if it already has a root activity.
20606            startActivityFromRecentsInner(mTaskId, INVALID_STACK_ID, null);
20607        }
20608
20609        @Override
20610        public int startActivity(IBinder whoThread, String callingPackage,
20611                Intent intent, String resolvedType, Bundle bOptions) {
20612            checkCaller();
20613
20614            int callingUser = UserHandle.getCallingUserId();
20615            TaskRecord tr;
20616            IApplicationThread appThread;
20617            synchronized (ActivityManagerService.this) {
20618                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20619                if (tr == null) {
20620                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20621                }
20622                appThread = ApplicationThreadNative.asInterface(whoThread);
20623                if (appThread == null) {
20624                    throw new IllegalArgumentException("Bad app thread " + appThread);
20625                }
20626            }
20627            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20628                    resolvedType, null, null, null, null, 0, 0, null, null,
20629                    null, bOptions, false, callingUser, null, tr);
20630        }
20631
20632        @Override
20633        public void setExcludeFromRecents(boolean exclude) {
20634            checkCaller();
20635
20636            synchronized (ActivityManagerService.this) {
20637                long origId = Binder.clearCallingIdentity();
20638                try {
20639                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20640                    if (tr == null) {
20641                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20642                    }
20643                    Intent intent = tr.getBaseIntent();
20644                    if (exclude) {
20645                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20646                    } else {
20647                        intent.setFlags(intent.getFlags()
20648                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20649                    }
20650                } finally {
20651                    Binder.restoreCallingIdentity(origId);
20652                }
20653            }
20654        }
20655    }
20656}
20657