OSDN Git Service

DO NOT MERGE. KEY_INTENT shouldn't grant permissions. am: 1f2a5d3622 -s ours am...
[android-x86/frameworks-base.git] / services / core / java / com / android / server / am / ActivityManagerService.java
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
17 package com.android.server.am;
18
19 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24 import static com.android.internal.util.XmlUtils.readIntAttribute;
25 import static com.android.internal.util.XmlUtils.readLongAttribute;
26 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27 import static com.android.internal.util.XmlUtils.writeIntAttribute;
28 import static com.android.internal.util.XmlUtils.writeLongAttribute;
29 import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30 import static com.android.server.am.ActivityManagerDebugConfig.*;
31 import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
32 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
33 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
34 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
35 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
36 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
37 import static org.xmlpull.v1.XmlPullParser.START_TAG;
38
39 import android.Manifest;
40 import android.app.AppOpsManager;
41 import android.app.ApplicationThreadNative;
42 import android.app.BroadcastOptions;
43 import android.app.IActivityContainer;
44 import android.app.IActivityContainerCallback;
45 import android.app.IAppTask;
46 import android.app.ITaskStackListener;
47 import android.app.ProfilerInfo;
48 import android.app.assist.AssistContent;
49 import android.app.assist.AssistStructure;
50 import android.app.usage.UsageEvents;
51 import android.app.usage.UsageStatsManagerInternal;
52 import android.appwidget.AppWidgetManager;
53 import android.content.pm.PermissionInfo;
54 import android.content.res.Resources;
55 import android.graphics.Bitmap;
56 import android.graphics.Point;
57 import android.graphics.Rect;
58 import android.os.BatteryStats;
59 import android.os.PersistableBundle;
60 import android.os.PowerManager;
61 import android.os.Trace;
62 import android.os.TransactionTooLargeException;
63 import android.os.WorkSource;
64 import android.os.storage.IMountService;
65 import android.os.storage.MountServiceInternal;
66 import android.os.storage.StorageManager;
67 import android.service.voice.IVoiceInteractionSession;
68 import android.service.voice.VoiceInteractionSession;
69 import android.util.ArrayMap;
70 import android.util.ArraySet;
71 import android.util.DebugUtils;
72 import android.util.SparseIntArray;
73 import android.view.Display;
74
75 import com.android.internal.R;
76 import com.android.internal.annotations.GuardedBy;
77 import com.android.internal.app.AssistUtils;
78 import com.android.internal.app.DumpHeapActivity;
79 import com.android.internal.app.IAppOpsService;
80 import com.android.internal.app.IVoiceInteractor;
81 import com.android.internal.app.ProcessMap;
82 import com.android.internal.app.ProcessStats;
83 import com.android.internal.os.BackgroundThread;
84 import com.android.internal.os.BatteryStatsImpl;
85 import com.android.internal.os.IResultReceiver;
86 import com.android.internal.os.ProcessCpuTracker;
87 import com.android.internal.os.TransferPipe;
88 import com.android.internal.os.Zygote;
89 import com.android.internal.util.ArrayUtils;
90 import com.android.internal.util.FastPrintWriter;
91 import com.android.internal.util.FastXmlSerializer;
92 import com.android.internal.util.MemInfoReader;
93 import com.android.internal.util.Preconditions;
94 import com.android.server.AppOpsService;
95 import com.android.server.AttributeCache;
96 import com.android.server.DeviceIdleController;
97 import com.android.server.IntentResolver;
98 import com.android.server.LocalServices;
99 import com.android.server.ServiceThread;
100 import com.android.server.SystemService;
101 import com.android.server.SystemServiceManager;
102 import com.android.server.Watchdog;
103 import com.android.server.am.ActivityStack.ActivityState;
104 import com.android.server.firewall.IntentFirewall;
105 import com.android.server.pm.Installer;
106 import com.android.server.pm.UserManagerService;
107 import com.android.server.statusbar.StatusBarManagerInternal;
108 import com.android.server.wm.AppTransition;
109 import com.android.server.wm.WindowManagerService;
110 import com.google.android.collect.Lists;
111 import com.google.android.collect.Maps;
112
113 import libcore.io.IoUtils;
114 import libcore.util.EmptyArray;
115
116 import org.xmlpull.v1.XmlPullParser;
117 import org.xmlpull.v1.XmlPullParserException;
118 import org.xmlpull.v1.XmlSerializer;
119
120 import android.app.Activity;
121 import android.app.ActivityManager;
122 import android.app.ActivityManager.RunningTaskInfo;
123 import android.app.ActivityManager.StackInfo;
124 import android.app.ActivityManagerInternal;
125 import android.app.ActivityManagerInternal.SleepToken;
126 import android.app.ActivityManagerNative;
127 import android.app.ActivityOptions;
128 import android.app.ActivityThread;
129 import android.app.AlertDialog;
130 import android.app.AppGlobals;
131 import android.app.ApplicationErrorReport;
132 import android.app.Dialog;
133 import android.app.IActivityController;
134 import android.app.IApplicationThread;
135 import android.app.IInstrumentationWatcher;
136 import android.app.INotificationManager;
137 import android.app.IProcessObserver;
138 import android.app.IServiceConnection;
139 import android.app.IStopUserCallback;
140 import android.app.IUidObserver;
141 import android.app.IUiAutomationConnection;
142 import android.app.IUserSwitchObserver;
143 import android.app.Instrumentation;
144 import android.app.Notification;
145 import android.app.NotificationManager;
146 import android.app.PendingIntent;
147 import android.app.backup.IBackupManager;
148 import android.app.admin.DevicePolicyManager;
149 import android.content.ActivityNotFoundException;
150 import android.content.BroadcastReceiver;
151 import android.content.ClipData;
152 import android.content.ComponentCallbacks2;
153 import android.content.ComponentName;
154 import android.content.ContentProvider;
155 import android.content.ContentResolver;
156 import android.content.Context;
157 import android.content.DialogInterface;
158 import android.content.IContentProvider;
159 import android.content.IIntentReceiver;
160 import android.content.IIntentSender;
161 import android.content.Intent;
162 import android.content.IntentFilter;
163 import android.content.IntentSender;
164 import android.content.pm.ActivityInfo;
165 import android.content.pm.ApplicationInfo;
166 import android.content.pm.ConfigurationInfo;
167 import android.content.pm.IPackageDataObserver;
168 import android.content.pm.IPackageManager;
169 import android.content.pm.InstrumentationInfo;
170 import android.content.pm.PackageInfo;
171 import android.content.pm.PackageManager;
172 import android.content.pm.ParceledListSlice;
173 import android.content.pm.UserInfo;
174 import android.content.pm.PackageManager.NameNotFoundException;
175 import android.content.pm.PathPermission;
176 import android.content.pm.ProviderInfo;
177 import android.content.pm.ResolveInfo;
178 import android.content.pm.ServiceInfo;
179 import android.content.res.CompatibilityInfo;
180 import android.content.res.Configuration;
181 import android.net.Proxy;
182 import android.net.ProxyInfo;
183 import android.net.Uri;
184 import android.os.Binder;
185 import android.os.Build;
186 import android.os.Bundle;
187 import android.os.Debug;
188 import android.os.DropBoxManager;
189 import android.os.Environment;
190 import android.os.FactoryTest;
191 import android.os.FileObserver;
192 import android.os.FileUtils;
193 import android.os.Handler;
194 import android.os.IBinder;
195 import android.os.IPermissionController;
196 import android.os.IProcessInfoService;
197 import android.os.IRemoteCallback;
198 import android.os.IUserManager;
199 import android.os.Looper;
200 import android.os.Message;
201 import android.os.Parcel;
202 import android.os.ParcelFileDescriptor;
203 import android.os.PowerManagerInternal;
204 import android.os.Process;
205 import android.os.RemoteCallbackList;
206 import android.os.RemoteException;
207 import android.os.SELinux;
208 import android.os.ServiceManager;
209 import android.os.StrictMode;
210 import android.os.SystemClock;
211 import android.os.SystemProperties;
212 import android.os.UpdateLock;
213 import android.os.UserHandle;
214 import android.os.UserManager;
215 import android.provider.Downloads;
216 import android.provider.Settings;
217 import android.telecom.TelecomManager;
218 import android.text.format.DateUtils;
219 import android.text.format.Time;
220 import android.util.AtomicFile;
221 import android.util.EventLog;
222 import android.util.Log;
223 import android.util.Pair;
224 import android.util.PrintWriterPrinter;
225 import android.util.Slog;
226 import android.util.SparseArray;
227 import android.util.TimeUtils;
228 import android.util.Xml;
229 import android.view.Gravity;
230 import android.view.LayoutInflater;
231 import android.view.View;
232 import android.view.WindowManager;
233
234 import dalvik.system.VMRuntime;
235
236 import java.io.BufferedInputStream;
237 import java.io.BufferedOutputStream;
238 import java.io.DataInputStream;
239 import java.io.DataOutputStream;
240 import java.io.File;
241 import java.io.FileDescriptor;
242 import java.io.FileInputStream;
243 import java.io.FileNotFoundException;
244 import java.io.FileOutputStream;
245 import java.io.IOException;
246 import java.io.InputStreamReader;
247 import java.io.PrintWriter;
248 import java.io.StringWriter;
249 import java.lang.ref.WeakReference;
250 import java.nio.charset.StandardCharsets;
251 import java.util.ArrayList;
252 import java.util.Arrays;
253 import java.util.Collections;
254 import java.util.Comparator;
255 import java.util.HashMap;
256 import java.util.HashSet;
257 import java.util.Iterator;
258 import java.util.List;
259 import java.util.Locale;
260 import java.util.Map;
261 import java.util.Set;
262 import java.util.concurrent.atomic.AtomicBoolean;
263 import java.util.concurrent.atomic.AtomicLong;
264
265 public final class ActivityManagerService extends ActivityManagerNative
266         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
267
268     // File that stores last updated system version and called preboot receivers
269     static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
270
271     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
272     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
273     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
274     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
275     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
276     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
277     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
278     private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
279     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
280     private static final String TAG_LRU = TAG + POSTFIX_LRU;
281     private static final String TAG_MU = TAG + POSTFIX_MU;
282     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
283     private static final String TAG_POWER = TAG + POSTFIX_POWER;
284     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
285     private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
286     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
287     private static final String TAG_PSS = TAG + POSTFIX_PSS;
288     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
289     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
290     private static final String TAG_STACK = TAG + POSTFIX_STACK;
291     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
292     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
293     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
294     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
295     private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
296
297     /** Control over CPU and battery monitoring */
298     // write battery stats every 30 minutes.
299     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
300     static final boolean MONITOR_CPU_USAGE = true;
301     // don't sample cpu less than every 5 seconds.
302     static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
303     // wait possibly forever for next cpu sample.
304     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
305     static final boolean MONITOR_THREAD_CPU_USAGE = false;
306
307     // The flags that are set for all calls we make to the package manager.
308     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
309
310     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
311
312     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
313
314     // Amount of time after a call to stopAppSwitches() during which we will
315     // prevent further untrusted switches from happening.
316     static final long APP_SWITCH_DELAY_TIME = 5*1000;
317
318     // How long we wait for a launched process to attach to the activity manager
319     // before we decide it's never going to come up for real.
320     static final int PROC_START_TIMEOUT = 10*1000;
321     // How long we wait for an attached process to publish its content providers
322     // before we decide it must be hung.
323     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
324
325     // How long we will retain processes hosting content providers in the "last activity"
326     // state before allowing them to drop down to the regular cached LRU list.  This is
327     // to avoid thrashing of provider processes under low memory situations.
328     static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
329
330     // How long we wait for a launched process to attach to the activity manager
331     // before we decide it's never going to come up for real, when the process was
332     // started with a wrapper for instrumentation (such as Valgrind) because it
333     // could take much longer than usual.
334     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
335
336     // How long to wait after going idle before forcing apps to GC.
337     static final int GC_TIMEOUT = 5*1000;
338
339     // The minimum amount of time between successive GC requests for a process.
340     static final int GC_MIN_INTERVAL = 60*1000;
341
342     // The minimum amount of time between successive PSS requests for a process.
343     static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
344
345     // The minimum amount of time between successive PSS requests for a process
346     // when the request is due to the memory state being lowered.
347     static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
348
349     // The rate at which we check for apps using excessive power -- 15 mins.
350     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
351
352     // The minimum sample duration we will allow before deciding we have
353     // enough data on wake locks to start killing things.
354     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
355
356     // The minimum sample duration we will allow before deciding we have
357     // enough data on CPU usage to start killing things.
358     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
359
360     // How long we allow a receiver to run before giving up on it.
361     static final int BROADCAST_FG_TIMEOUT = 10*1000;
362     static final int BROADCAST_BG_TIMEOUT = 60*1000;
363
364     // How long we wait until we timeout on key dispatching.
365     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
366
367     // How long we wait until we timeout on key dispatching during instrumentation.
368     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
369
370     // Amount of time we wait for observers to handle a user switch before
371     // giving up on them and unfreezing the screen.
372     static final int USER_SWITCH_TIMEOUT = 2*1000;
373
374     // This is the amount of time an app needs to be running a foreground service before
375     // we will consider it to be doing interaction for usage stats.
376     static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
377
378     // Maximum amount of time we will allow to elapse before re-reporting usage stats
379     // interaction with foreground processes.
380     static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
381
382     // Maximum number of users we allow to be running at a time.
383     static final int MAX_RUNNING_USERS = 3;
384
385     // How long to wait in getAssistContextExtras for the activity and foreground services
386     // to respond with the result.
387     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
388
389     // How long top wait when going through the modern assist (which doesn't need to block
390     // on getting this result before starting to launch its UI).
391     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
392
393     // Maximum number of persisted Uri grants a package is allowed
394     static final int MAX_PERSISTED_URI_GRANTS = 128;
395
396     static final int MY_PID = Process.myPid();
397
398     static final String[] EMPTY_STRING_ARRAY = new String[0];
399
400     // How many bytes to write into the dropbox log before truncating
401     static final int DROPBOX_MAX_SIZE = 256 * 1024;
402
403     // Access modes for handleIncomingUser.
404     static final int ALLOW_NON_FULL = 0;
405     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
406     static final int ALLOW_FULL_ONLY = 2;
407
408     static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
409
410     // Delay in notifying task stack change listeners (in millis)
411     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
412
413     // Necessary ApplicationInfo flags to mark an app as persistent
414     private static final int PERSISTENT_MASK =
415             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
416
417
418     // Delay to disable app launch boost
419     static final int APP_BOOST_MESSAGE_DELAY = 3000;
420     // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
421     static final int APP_BOOST_TIMEOUT = 2500;
422
423     private static native int nativeMigrateToBoost();
424     private static native int nativeMigrateFromBoost();
425     private boolean mIsBoosted = false;
426     private long mBoostStartTime = 0;
427
428     /** All system services */
429     SystemServiceManager mSystemServiceManager;
430
431     private Installer mInstaller;
432
433     /** Run all ActivityStacks through this */
434     ActivityStackSupervisor mStackSupervisor;
435
436     /** Task stack change listeners. */
437     private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
438             new RemoteCallbackList<ITaskStackListener>();
439
440     public IntentFirewall mIntentFirewall;
441
442     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
443     // default actuion automatically.  Important for devices without direct input
444     // devices.
445     private boolean mShowDialogs = true;
446
447     BroadcastQueue mFgBroadcastQueue;
448     BroadcastQueue mBgBroadcastQueue;
449     // Convenient for easy iteration over the queues. Foreground is first
450     // so that dispatch of foreground broadcasts gets precedence.
451     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
452
453     BroadcastQueue broadcastQueueForIntent(Intent intent) {
454         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
455         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
456                 "Broadcast intent " + intent + " on "
457                 + (isFg ? "foreground" : "background") + " queue");
458         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
459     }
460
461     /**
462      * Activity we have told the window manager to have key focus.
463      */
464     ActivityRecord mFocusedActivity = null;
465
466     /**
467      * User id of the last activity mFocusedActivity was set to.
468      */
469     private int mLastFocusedUserId;
470
471     /**
472      * If non-null, we are tracking the time the user spends in the currently focused app.
473      */
474     private AppTimeTracker mCurAppTimeTracker;
475
476     /**
477      * List of intents that were used to start the most recent tasks.
478      */
479     private final RecentTasks mRecentTasks;
480
481     /**
482      * For addAppTask: cached of the last activity component that was added.
483      */
484     ComponentName mLastAddedTaskComponent;
485
486     /**
487      * For addAppTask: cached of the last activity uid that was added.
488      */
489     int mLastAddedTaskUid;
490
491     /**
492      * For addAppTask: cached of the last ActivityInfo that was added.
493      */
494     ActivityInfo mLastAddedTaskActivity;
495
496     /**
497      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
498      */
499     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
500
501     /**
502      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
503      */
504     String mDeviceOwnerName;
505
506     public class PendingAssistExtras extends Binder implements Runnable {
507         public final ActivityRecord activity;
508         public final Bundle extras;
509         public final Intent intent;
510         public final String hint;
511         public final IResultReceiver receiver;
512         public final int userHandle;
513         public boolean haveResult = false;
514         public Bundle result = null;
515         public AssistStructure structure = null;
516         public AssistContent content = null;
517         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
518                 String _hint, IResultReceiver _receiver, int _userHandle) {
519             activity = _activity;
520             extras = _extras;
521             intent = _intent;
522             hint = _hint;
523             receiver = _receiver;
524             userHandle = _userHandle;
525         }
526         @Override
527         public void run() {
528             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
529             synchronized (this) {
530                 haveResult = true;
531                 notifyAll();
532             }
533             pendingAssistExtrasTimedOut(this);
534         }
535     }
536
537     final ArrayList<PendingAssistExtras> mPendingAssistExtras
538             = new ArrayList<PendingAssistExtras>();
539
540     /**
541      * Process management.
542      */
543     final ProcessList mProcessList = new ProcessList();
544
545     /**
546      * All of the applications we currently have running organized by name.
547      * The keys are strings of the application package name (as
548      * returned by the package manager), and the keys are ApplicationRecord
549      * objects.
550      */
551     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
552
553     /**
554      * Tracking long-term execution of processes to look for abuse and other
555      * bad app behavior.
556      */
557     final ProcessStatsService mProcessStats;
558
559     /**
560      * The currently running isolated processes.
561      */
562     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
563
564     /**
565      * Counter for assigning isolated process uids, to avoid frequently reusing the
566      * same ones.
567      */
568     int mNextIsolatedProcessUid = 0;
569
570     /**
571      * The currently running heavy-weight process, if any.
572      */
573     ProcessRecord mHeavyWeightProcess = null;
574
575     /**
576      * The last time that various processes have crashed.
577      */
578     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
579
580     /**
581      * Information about a process that is currently marked as bad.
582      */
583     static final class BadProcessInfo {
584         BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
585             this.time = time;
586             this.shortMsg = shortMsg;
587             this.longMsg = longMsg;
588             this.stack = stack;
589         }
590
591         final long time;
592         final String shortMsg;
593         final String longMsg;
594         final String stack;
595     }
596
597     /**
598      * Set of applications that we consider to be bad, and will reject
599      * incoming broadcasts from (which the user has no control over).
600      * Processes are added to this set when they have crashed twice within
601      * a minimum amount of time; they are removed from it when they are
602      * later restarted (hopefully due to some user action).  The value is the
603      * time it was added to the list.
604      */
605     final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
606
607     /**
608      * All of the processes we currently have running organized by pid.
609      * The keys are the pid running the application.
610      *
611      * <p>NOTE: This object is protected by its own lock, NOT the global
612      * activity manager lock!
613      */
614     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
615
616     /**
617      * All of the processes that have been forced to be foreground.  The key
618      * is the pid of the caller who requested it (we hold a death
619      * link on it).
620      */
621     abstract class ForegroundToken implements IBinder.DeathRecipient {
622         int pid;
623         IBinder token;
624     }
625     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
626
627     /**
628      * List of records for processes that someone had tried to start before the
629      * system was ready.  We don't start them at that point, but ensure they
630      * are started by the time booting is complete.
631      */
632     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
633
634     /**
635      * List of persistent applications that are in the process
636      * of being started.
637      */
638     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
639
640     /**
641      * Processes that are being forcibly torn down.
642      */
643     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
644
645     /**
646      * List of running applications, sorted by recent usage.
647      * The first entry in the list is the least recently used.
648      */
649     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
650
651     /**
652      * Where in mLruProcesses that the processes hosting activities start.
653      */
654     int mLruProcessActivityStart = 0;
655
656     /**
657      * Where in mLruProcesses that the processes hosting services start.
658      * This is after (lower index) than mLruProcessesActivityStart.
659      */
660     int mLruProcessServiceStart = 0;
661
662     /**
663      * List of processes that should gc as soon as things are idle.
664      */
665     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
666
667     /**
668      * Processes we want to collect PSS data from.
669      */
670     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
671
672     /**
673      * Last time we requested PSS data of all processes.
674      */
675     long mLastFullPssTime = SystemClock.uptimeMillis();
676
677     /**
678      * If set, the next time we collect PSS data we should do a full collection
679      * with data from native processes and the kernel.
680      */
681     boolean mFullPssPending = false;
682
683     /**
684      * This is the process holding what we currently consider to be
685      * the "home" activity.
686      */
687     ProcessRecord mHomeProcess;
688
689     /**
690      * This is the process holding the activity the user last visited that
691      * is in a different process from the one they are currently in.
692      */
693     ProcessRecord mPreviousProcess;
694
695     /**
696      * The time at which the previous process was last visible.
697      */
698     long mPreviousProcessVisibleTime;
699
700     /**
701      * Track all uids that have actively running processes.
702      */
703     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
704
705     /**
706      * Which users have been started, so are allowed to run code.
707      */
708     final SparseArray<UserState> mStartedUsers = new SparseArray<>();
709
710     /**
711      * LRU list of history of current users.  Most recently current is at the end.
712      */
713     final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
714
715     /**
716      * Constant array of the users that are currently started.
717      */
718     int[] mStartedUserArray = new int[] { 0 };
719
720     /**
721      * Registered observers of the user switching mechanics.
722      */
723     final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
724             = new RemoteCallbackList<IUserSwitchObserver>();
725
726     /**
727      * Currently active user switch.
728      */
729     Object mCurUserSwitchCallback;
730
731     /**
732      * Packages that the user has asked to have run in screen size
733      * compatibility mode instead of filling the screen.
734      */
735     final CompatModePackages mCompatModePackages;
736
737     /**
738      * Set of IntentSenderRecord objects that are currently active.
739      */
740     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
741             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
742
743     /**
744      * Fingerprints (hashCode()) of stack traces that we've
745      * already logged DropBox entries for.  Guarded by itself.  If
746      * something (rogue user app) forces this over
747      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
748      */
749     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
750     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
751
752     /**
753      * Strict Mode background batched logging state.
754      *
755      * The string buffer is guarded by itself, and its lock is also
756      * used to determine if another batched write is already
757      * in-flight.
758      */
759     private final StringBuilder mStrictModeBuffer = new StringBuilder();
760
761     /**
762      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
763      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
764      */
765     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
766
767     /**
768      * Resolver for broadcast intents to registered receivers.
769      * Holds BroadcastFilter (subclass of IntentFilter).
770      */
771     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
772             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
773         @Override
774         protected boolean allowFilterResult(
775                 BroadcastFilter filter, List<BroadcastFilter> dest) {
776             IBinder target = filter.receiverList.receiver.asBinder();
777             for (int i = dest.size() - 1; i >= 0; i--) {
778                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
779                     return false;
780                 }
781             }
782             return true;
783         }
784
785         @Override
786         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
787             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
788                     || userId == filter.owningUserId) {
789                 return super.newResult(filter, match, userId);
790             }
791             return null;
792         }
793
794         @Override
795         protected BroadcastFilter[] newArray(int size) {
796             return new BroadcastFilter[size];
797         }
798
799         @Override
800         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
801             return packageName.equals(filter.packageName);
802         }
803     };
804
805     /**
806      * State of all active sticky broadcasts per user.  Keys are the action of the
807      * sticky Intent, values are an ArrayList of all broadcasted intents with
808      * that action (which should usually be one).  The SparseArray is keyed
809      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
810      * for stickies that are sent to all users.
811      */
812     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
813             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
814
815     final ActiveServices mServices;
816
817     final static class Association {
818         final int mSourceUid;
819         final String mSourceProcess;
820         final int mTargetUid;
821         final ComponentName mTargetComponent;
822         final String mTargetProcess;
823
824         int mCount;
825         long mTime;
826
827         int mNesting;
828         long mStartTime;
829
830         Association(int sourceUid, String sourceProcess, int targetUid,
831                 ComponentName targetComponent, String targetProcess) {
832             mSourceUid = sourceUid;
833             mSourceProcess = sourceProcess;
834             mTargetUid = targetUid;
835             mTargetComponent = targetComponent;
836             mTargetProcess = targetProcess;
837         }
838     }
839
840     /**
841      * When service association tracking is enabled, this is all of the associations we
842      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
843      * -> association data.
844      */
845     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
846             mAssociations = new SparseArray<>();
847     boolean mTrackingAssociations;
848
849     /**
850      * Backup/restore process management
851      */
852     String mBackupAppName = null;
853     BackupRecord mBackupTarget = null;
854
855     final ProviderMap mProviderMap;
856
857     /**
858      * List of content providers who have clients waiting for them.  The
859      * application is currently being launched and the provider will be
860      * removed from this list once it is published.
861      */
862     final ArrayList<ContentProviderRecord> mLaunchingProviders
863             = new ArrayList<ContentProviderRecord>();
864
865     /**
866      * File storing persisted {@link #mGrantedUriPermissions}.
867      */
868     private final AtomicFile mGrantFile;
869
870     /** XML constants used in {@link #mGrantFile} */
871     private static final String TAG_URI_GRANTS = "uri-grants";
872     private static final String TAG_URI_GRANT = "uri-grant";
873     private static final String ATTR_USER_HANDLE = "userHandle";
874     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
875     private static final String ATTR_TARGET_USER_ID = "targetUserId";
876     private static final String ATTR_SOURCE_PKG = "sourcePkg";
877     private static final String ATTR_TARGET_PKG = "targetPkg";
878     private static final String ATTR_URI = "uri";
879     private static final String ATTR_MODE_FLAGS = "modeFlags";
880     private static final String ATTR_CREATED_TIME = "createdTime";
881     private static final String ATTR_PREFIX = "prefix";
882
883     /**
884      * Global set of specific {@link Uri} permissions that have been granted.
885      * This optimized lookup structure maps from {@link UriPermission#targetUid}
886      * to {@link UriPermission#uri} to {@link UriPermission}.
887      */
888     @GuardedBy("this")
889     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
890             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
891
892     public static class GrantUri {
893         public final int sourceUserId;
894         public final Uri uri;
895         public boolean prefix;
896
897         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
898             this.sourceUserId = sourceUserId;
899             this.uri = uri;
900             this.prefix = prefix;
901         }
902
903         @Override
904         public int hashCode() {
905             int hashCode = 1;
906             hashCode = 31 * hashCode + sourceUserId;
907             hashCode = 31 * hashCode + uri.hashCode();
908             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
909             return hashCode;
910         }
911
912         @Override
913         public boolean equals(Object o) {
914             if (o instanceof GrantUri) {
915                 GrantUri other = (GrantUri) o;
916                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
917                         && prefix == other.prefix;
918             }
919             return false;
920         }
921
922         @Override
923         public String toString() {
924             String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
925             if (prefix) result += " [prefix]";
926             return result;
927         }
928
929         public String toSafeString() {
930             String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
931             if (prefix) result += " [prefix]";
932             return result;
933         }
934
935         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
936             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
937                     ContentProvider.getUriWithoutUserId(uri), false);
938         }
939     }
940
941     CoreSettingsObserver mCoreSettingsObserver;
942
943     /**
944      * Thread-local storage used to carry caller permissions over through
945      * indirect content-provider access.
946      */
947     private class Identity {
948         public final IBinder token;
949         public final int pid;
950         public final int uid;
951
952         Identity(IBinder _token, int _pid, int _uid) {
953             token = _token;
954             pid = _pid;
955             uid = _uid;
956         }
957     }
958
959     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
960
961     /**
962      * All information we have collected about the runtime performance of
963      * any user id that can impact battery performance.
964      */
965     final BatteryStatsService mBatteryStatsService;
966
967     /**
968      * Information about component usage
969      */
970     UsageStatsManagerInternal mUsageStatsService;
971
972     /**
973      * Access to DeviceIdleController service.
974      */
975     DeviceIdleController.LocalService mLocalDeviceIdleController;
976
977     /**
978      * Information about and control over application operations
979      */
980     final AppOpsService mAppOpsService;
981
982     /**
983      * Save recent tasks information across reboots.
984      */
985     final TaskPersister mTaskPersister;
986
987     /**
988      * Current configuration information.  HistoryRecord objects are given
989      * a reference to this object to indicate which configuration they are
990      * currently running in, so this object must be kept immutable.
991      */
992     Configuration mConfiguration = new Configuration();
993
994     /**
995      * Current sequencing integer of the configuration, for skipping old
996      * configurations.
997      */
998     int mConfigurationSeq = 0;
999
1000     /**
1001      * Hardware-reported OpenGLES version.
1002      */
1003     final int GL_ES_VERSION;
1004
1005     /**
1006      * List of initialization arguments to pass to all processes when binding applications to them.
1007      * For example, references to the commonly used services.
1008      */
1009     HashMap<String, IBinder> mAppBindArgs;
1010     HashMap<String, IBinder> mIsolatedAppBindArgs;
1011
1012     /**
1013      * Temporary to avoid allocations.  Protected by main lock.
1014      */
1015     final StringBuilder mStringBuilder = new StringBuilder(256);
1016
1017     /**
1018      * Used to control how we initialize the service.
1019      */
1020     ComponentName mTopComponent;
1021     String mTopAction = Intent.ACTION_MAIN;
1022     String mTopData;
1023     boolean mProcessesReady = false;
1024     boolean mSystemReady = false;
1025     boolean mBooting = false;
1026     boolean mCallFinishBooting = false;
1027     boolean mBootAnimationComplete = false;
1028     boolean mWaitingUpdate = false;
1029     boolean mDidUpdate = false;
1030     boolean mOnBattery = false;
1031     boolean mLaunchWarningShown = false;
1032
1033     Context mContext;
1034
1035     int mFactoryTest;
1036
1037     boolean mCheckedForSetup;
1038
1039     /**
1040      * The time at which we will allow normal application switches again,
1041      * after a call to {@link #stopAppSwitches()}.
1042      */
1043     long mAppSwitchesAllowedTime;
1044
1045     /**
1046      * This is set to true after the first switch after mAppSwitchesAllowedTime
1047      * is set; any switches after that will clear the time.
1048      */
1049     boolean mDidAppSwitch;
1050
1051     /**
1052      * Last time (in realtime) at which we checked for power usage.
1053      */
1054     long mLastPowerCheckRealtime;
1055
1056     /**
1057      * Last time (in uptime) at which we checked for power usage.
1058      */
1059     long mLastPowerCheckUptime;
1060
1061     /**
1062      * Set while we are wanting to sleep, to prevent any
1063      * activities from being started/resumed.
1064      */
1065     private boolean mSleeping = false;
1066
1067     /**
1068      * The process state used for processes that are running the top activities.
1069      * This changes between TOP and TOP_SLEEPING to following mSleeping.
1070      */
1071     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1072
1073     /**
1074      * Set while we are running a voice interaction.  This overrides
1075      * sleeping while it is active.
1076      */
1077     private IVoiceInteractionSession mRunningVoice;
1078
1079     /**
1080      * For some direct access we need to power manager.
1081      */
1082     PowerManagerInternal mLocalPowerManager;
1083
1084     /**
1085      * We want to hold a wake lock while running a voice interaction session, since
1086      * this may happen with the screen off and we need to keep the CPU running to
1087      * be able to continue to interact with the user.
1088      */
1089     PowerManager.WakeLock mVoiceWakeLock;
1090
1091     /**
1092      * State of external calls telling us if the device is awake or asleep.
1093      */
1094     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1095
1096     /**
1097      * A list of tokens that cause the top activity to be put to sleep.
1098      * They are used by components that may hide and block interaction with underlying
1099      * activities.
1100      */
1101     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1102
1103     static final int LOCK_SCREEN_HIDDEN = 0;
1104     static final int LOCK_SCREEN_LEAVING = 1;
1105     static final int LOCK_SCREEN_SHOWN = 2;
1106     /**
1107      * State of external call telling us if the lock screen is shown.
1108      */
1109     int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1110
1111     /**
1112      * Set if we are shutting down the system, similar to sleeping.
1113      */
1114     boolean mShuttingDown = false;
1115
1116     /**
1117      * Current sequence id for oom_adj computation traversal.
1118      */
1119     int mAdjSeq = 0;
1120
1121     /**
1122      * Current sequence id for process LRU updating.
1123      */
1124     int mLruSeq = 0;
1125
1126     /**
1127      * Keep track of the non-cached/empty process we last found, to help
1128      * determine how to distribute cached/empty processes next time.
1129      */
1130     int mNumNonCachedProcs = 0;
1131
1132     /**
1133      * Keep track of the number of cached hidden procs, to balance oom adj
1134      * distribution between those and empty procs.
1135      */
1136     int mNumCachedHiddenProcs = 0;
1137
1138     /**
1139      * Keep track of the number of service processes we last found, to
1140      * determine on the next iteration which should be B services.
1141      */
1142     int mNumServiceProcs = 0;
1143     int mNewNumAServiceProcs = 0;
1144     int mNewNumServiceProcs = 0;
1145
1146     /**
1147      * Allow the current computed overall memory level of the system to go down?
1148      * This is set to false when we are killing processes for reasons other than
1149      * memory management, so that the now smaller process list will not be taken as
1150      * an indication that memory is tighter.
1151      */
1152     boolean mAllowLowerMemLevel = false;
1153
1154     /**
1155      * The last computed memory level, for holding when we are in a state that
1156      * processes are going away for other reasons.
1157      */
1158     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1159
1160     /**
1161      * The last total number of process we have, to determine if changes actually look
1162      * like a shrinking number of process due to lower RAM.
1163      */
1164     int mLastNumProcesses;
1165
1166     /**
1167      * The uptime of the last time we performed idle maintenance.
1168      */
1169     long mLastIdleTime = SystemClock.uptimeMillis();
1170
1171     /**
1172      * Total time spent with RAM that has been added in the past since the last idle time.
1173      */
1174     long mLowRamTimeSinceLastIdle = 0;
1175
1176     /**
1177      * If RAM is currently low, when that horrible situation started.
1178      */
1179     long mLowRamStartTime = 0;
1180
1181     /**
1182      * For reporting to battery stats the current top application.
1183      */
1184     private String mCurResumedPackage = null;
1185     private int mCurResumedUid = -1;
1186
1187     /**
1188      * For reporting to battery stats the apps currently running foreground
1189      * service.  The ProcessMap is package/uid tuples; each of these contain
1190      * an array of the currently foreground processes.
1191      */
1192     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1193             = new ProcessMap<ArrayList<ProcessRecord>>();
1194
1195     /**
1196      * This is set if we had to do a delayed dexopt of an app before launching
1197      * it, to increase the ANR timeouts in that case.
1198      */
1199     boolean mDidDexOpt;
1200
1201     /**
1202      * Set if the systemServer made a call to enterSafeMode.
1203      */
1204     boolean mSafeMode;
1205
1206     /**
1207      * If true, we are running under a test environment so will sample PSS from processes
1208      * much more rapidly to try to collect better data when the tests are rapidly
1209      * running through apps.
1210      */
1211     boolean mTestPssMode = false;
1212
1213     String mDebugApp = null;
1214     boolean mWaitForDebugger = false;
1215     boolean mDebugTransient = false;
1216     String mOrigDebugApp = null;
1217     boolean mOrigWaitForDebugger = false;
1218     boolean mAlwaysFinishActivities = false;
1219     IActivityController mController = null;
1220     String mProfileApp = null;
1221     ProcessRecord mProfileProc = null;
1222     String mProfileFile;
1223     ParcelFileDescriptor mProfileFd;
1224     int mSamplingInterval = 0;
1225     boolean mAutoStopProfiler = false;
1226     int mProfileType = 0;
1227     String mOpenGlTraceApp = null;
1228     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1229     String mMemWatchDumpProcName;
1230     String mMemWatchDumpFile;
1231     int mMemWatchDumpPid;
1232     int mMemWatchDumpUid;
1233
1234     final long[] mTmpLong = new long[1];
1235
1236     static final class ProcessChangeItem {
1237         static final int CHANGE_ACTIVITIES = 1<<0;
1238         static final int CHANGE_PROCESS_STATE = 1<<1;
1239         int changes;
1240         int uid;
1241         int pid;
1242         int processState;
1243         boolean foregroundActivities;
1244     }
1245
1246     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1247     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1248
1249     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1250     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1251
1252     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1253     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1254
1255     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1256     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1257
1258     /**
1259      * Runtime CPU use collection thread.  This object's lock is used to
1260      * perform synchronization with the thread (notifying it to run).
1261      */
1262     final Thread mProcessCpuThread;
1263
1264     /**
1265      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1266      * Must acquire this object's lock when accessing it.
1267      * NOTE: this lock will be held while doing long operations (trawling
1268      * through all processes in /proc), so it should never be acquired by
1269      * any critical paths such as when holding the main activity manager lock.
1270      */
1271     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1272             MONITOR_THREAD_CPU_USAGE);
1273     final AtomicLong mLastCpuTime = new AtomicLong(0);
1274     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1275
1276     long mLastWriteTime = 0;
1277
1278     /**
1279      * Used to retain an update lock when the foreground activity is in
1280      * immersive mode.
1281      */
1282     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1283
1284     /**
1285      * Set to true after the system has finished booting.
1286      */
1287     boolean mBooted = false;
1288
1289     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1290     int mProcessLimitOverride = -1;
1291
1292     WindowManagerService mWindowManager;
1293
1294     final ActivityThread mSystemThread;
1295
1296     // Holds the current foreground user's id
1297     int mCurrentUserId = 0;
1298     // Holds the target user's id during a user switch
1299     int mTargetUserId = UserHandle.USER_NULL;
1300     // If there are multiple profiles for the current user, their ids are here
1301     // Currently only the primary user can have managed profiles
1302     int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1303
1304     /**
1305      * Mapping from each known user ID to the profile group ID it is associated with.
1306      */
1307     SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1308
1309     private UserManagerService mUserManager;
1310
1311     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1312         final ProcessRecord mApp;
1313         final int mPid;
1314         final IApplicationThread mAppThread;
1315
1316         AppDeathRecipient(ProcessRecord app, int pid,
1317                 IApplicationThread thread) {
1318             if (DEBUG_ALL) Slog.v(
1319                 TAG, "New death recipient " + this
1320                 + " for thread " + thread.asBinder());
1321             mApp = app;
1322             mPid = pid;
1323             mAppThread = thread;
1324         }
1325
1326         @Override
1327         public void binderDied() {
1328             if (DEBUG_ALL) Slog.v(
1329                 TAG, "Death received in " + this
1330                 + " for thread " + mAppThread.asBinder());
1331             synchronized(ActivityManagerService.this) {
1332                 appDiedLocked(mApp, mPid, mAppThread, true);
1333             }
1334         }
1335     }
1336
1337     static final int SHOW_ERROR_MSG = 1;
1338     static final int SHOW_NOT_RESPONDING_MSG = 2;
1339     static final int SHOW_FACTORY_ERROR_MSG = 3;
1340     static final int UPDATE_CONFIGURATION_MSG = 4;
1341     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1342     static final int WAIT_FOR_DEBUGGER_MSG = 6;
1343     static final int SERVICE_TIMEOUT_MSG = 12;
1344     static final int UPDATE_TIME_ZONE = 13;
1345     static final int SHOW_UID_ERROR_MSG = 14;
1346     static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1347     static final int PROC_START_TIMEOUT_MSG = 20;
1348     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1349     static final int KILL_APPLICATION_MSG = 22;
1350     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1351     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1352     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1353     static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1354     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1355     static final int CLEAR_DNS_CACHE_MSG = 28;
1356     static final int UPDATE_HTTP_PROXY_MSG = 29;
1357     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1358     static final int DISPATCH_PROCESSES_CHANGED = 31;
1359     static final int DISPATCH_PROCESS_DIED = 32;
1360     static final int REPORT_MEM_USAGE_MSG = 33;
1361     static final int REPORT_USER_SWITCH_MSG = 34;
1362     static final int CONTINUE_USER_SWITCH_MSG = 35;
1363     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1364     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1365     static final int PERSIST_URI_GRANTS_MSG = 38;
1366     static final int REQUEST_ALL_PSS_MSG = 39;
1367     static final int START_PROFILES_MSG = 40;
1368     static final int UPDATE_TIME = 41;
1369     static final int SYSTEM_USER_START_MSG = 42;
1370     static final int SYSTEM_USER_CURRENT_MSG = 43;
1371     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1372     static final int FINISH_BOOTING_MSG = 45;
1373     static final int START_USER_SWITCH_MSG = 46;
1374     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1375     static final int DISMISS_DIALOG_MSG = 48;
1376     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1377     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1378     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1379     static final int DELETE_DUMPHEAP_MSG = 52;
1380     static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1381     static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1382     static final int REPORT_TIME_TRACKER_MSG = 55;
1383     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1384     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1385     static final int APP_BOOST_DEACTIVATE_MSG = 58;
1386     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1387
1388     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1389     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1390     static final int FIRST_COMPAT_MODE_MSG = 300;
1391     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1392
1393     CompatModeDialog mCompatModeDialog;
1394     long mLastMemUsageReportTime = 0;
1395
1396     /**
1397      * Flag whether the current user is a "monkey", i.e. whether
1398      * the UI is driven by a UI automation tool.
1399      */
1400     private boolean mUserIsMonkey;
1401
1402     /** Flag whether the device has a Recents UI */
1403     boolean mHasRecents;
1404
1405     /** The dimensions of the thumbnails in the Recents UI. */
1406     int mThumbnailWidth;
1407     int mThumbnailHeight;
1408
1409     final ServiceThread mHandlerThread;
1410     final MainHandler mHandler;
1411     final UiHandler mUiHandler;
1412
1413     final class UiHandler extends Handler {
1414         public UiHandler() {
1415             super(com.android.server.UiThread.get().getLooper(), null, true);
1416         }
1417
1418         @Override
1419         public void handleMessage(Message msg) {
1420             switch (msg.what) {
1421             case SHOW_ERROR_MSG: {
1422                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1423                 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1424                         Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1425                 synchronized (ActivityManagerService.this) {
1426                     ProcessRecord proc = (ProcessRecord)data.get("app");
1427                     AppErrorResult res = (AppErrorResult) data.get("result");
1428                     if (proc != null && proc.crashDialog != null) {
1429                         Slog.e(TAG, "App already has crash dialog: " + proc);
1430                         if (res != null) {
1431                             res.set(0);
1432                         }
1433                         return;
1434                     }
1435                     boolean isBackground = (UserHandle.getAppId(proc.uid)
1436                             >= Process.FIRST_APPLICATION_UID
1437                             && proc.pid != MY_PID);
1438                     for (int userId : mCurrentProfileIds) {
1439                         isBackground &= (proc.userId != userId);
1440                     }
1441                     if (isBackground && !showBackground) {
1442                         Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1443                         if (res != null) {
1444                             res.set(0);
1445                         }
1446                         return;
1447                     }
1448                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1449                         Dialog d = new AppErrorDialog(mContext,
1450                                 ActivityManagerService.this, res, proc);
1451                         d.show();
1452                         proc.crashDialog = d;
1453                     } else {
1454                         // The device is asleep, so just pretend that the user
1455                         // saw a crash dialog and hit "force quit".
1456                         if (res != null) {
1457                             res.set(0);
1458                         }
1459                     }
1460                 }
1461
1462                 ensureBootCompleted();
1463             } break;
1464             case SHOW_NOT_RESPONDING_MSG: {
1465                 synchronized (ActivityManagerService.this) {
1466                     HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1467                     ProcessRecord proc = (ProcessRecord)data.get("app");
1468                     if (proc != null && proc.anrDialog != null) {
1469                         Slog.e(TAG, "App already has anr dialog: " + proc);
1470                         return;
1471                     }
1472
1473                     Intent intent = new Intent("android.intent.action.ANR");
1474                     if (!mProcessesReady) {
1475                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1476                                 | Intent.FLAG_RECEIVER_FOREGROUND);
1477                     }
1478                     broadcastIntentLocked(null, null, intent,
1479                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1480                             null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1481
1482                     if (mShowDialogs) {
1483                         Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1484                                 mContext, proc, (ActivityRecord)data.get("activity"),
1485                                 msg.arg1 != 0);
1486                         d.show();
1487                         proc.anrDialog = d;
1488                     } else {
1489                         // Just kill the app if there is no dialog to be shown.
1490                         killAppAtUsersRequest(proc, null);
1491                     }
1492                 }
1493
1494                 ensureBootCompleted();
1495             } break;
1496             case SHOW_STRICT_MODE_VIOLATION_MSG: {
1497                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1498                 synchronized (ActivityManagerService.this) {
1499                     ProcessRecord proc = (ProcessRecord) data.get("app");
1500                     if (proc == null) {
1501                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1502                         break;
1503                     }
1504                     if (proc.crashDialog != null) {
1505                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1506                         return;
1507                     }
1508                     AppErrorResult res = (AppErrorResult) data.get("result");
1509                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1510                         Dialog d = new StrictModeViolationDialog(mContext,
1511                                 ActivityManagerService.this, res, proc);
1512                         d.show();
1513                         proc.crashDialog = d;
1514                     } else {
1515                         // The device is asleep, so just pretend that the user
1516                         // saw a crash dialog and hit "force quit".
1517                         res.set(0);
1518                     }
1519                 }
1520                 ensureBootCompleted();
1521             } break;
1522             case SHOW_FACTORY_ERROR_MSG: {
1523                 Dialog d = new FactoryErrorDialog(
1524                     mContext, msg.getData().getCharSequence("msg"));
1525                 d.show();
1526                 ensureBootCompleted();
1527             } break;
1528             case WAIT_FOR_DEBUGGER_MSG: {
1529                 synchronized (ActivityManagerService.this) {
1530                     ProcessRecord app = (ProcessRecord)msg.obj;
1531                     if (msg.arg1 != 0) {
1532                         if (!app.waitedForDebugger) {
1533                             Dialog d = new AppWaitingForDebuggerDialog(
1534                                     ActivityManagerService.this,
1535                                     mContext, app);
1536                             app.waitDialog = d;
1537                             app.waitedForDebugger = true;
1538                             d.show();
1539                         }
1540                     } else {
1541                         if (app.waitDialog != null) {
1542                             app.waitDialog.dismiss();
1543                             app.waitDialog = null;
1544                         }
1545                     }
1546                 }
1547             } break;
1548             case SHOW_UID_ERROR_MSG: {
1549                 if (mShowDialogs) {
1550                     AlertDialog d = new BaseErrorDialog(mContext);
1551                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1552                     d.setCancelable(false);
1553                     d.setTitle(mContext.getText(R.string.android_system_label));
1554                     d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1555                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1556                             obtainMessage(DISMISS_DIALOG_MSG, d));
1557                     d.show();
1558                 }
1559             } break;
1560             case SHOW_FINGERPRINT_ERROR_MSG: {
1561                 if (mShowDialogs) {
1562                     AlertDialog d = new BaseErrorDialog(mContext);
1563                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1564                     d.setCancelable(false);
1565                     d.setTitle(mContext.getText(R.string.android_system_label));
1566                     d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1567                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1568                             obtainMessage(DISMISS_DIALOG_MSG, d));
1569                     d.show();
1570                 }
1571             } break;
1572             case SHOW_COMPAT_MODE_DIALOG_MSG: {
1573                 synchronized (ActivityManagerService.this) {
1574                     ActivityRecord ar = (ActivityRecord) msg.obj;
1575                     if (mCompatModeDialog != null) {
1576                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1577                                 ar.info.applicationInfo.packageName)) {
1578                             return;
1579                         }
1580                         mCompatModeDialog.dismiss();
1581                         mCompatModeDialog = null;
1582                     }
1583                     if (ar != null && false) {
1584                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1585                                 ar.packageName)) {
1586                             int mode = mCompatModePackages.computeCompatModeLocked(
1587                                     ar.info.applicationInfo);
1588                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1589                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1590                                 mCompatModeDialog = new CompatModeDialog(
1591                                         ActivityManagerService.this, mContext,
1592                                         ar.info.applicationInfo);
1593                                 mCompatModeDialog.show();
1594                             }
1595                         }
1596                     }
1597                 }
1598                 break;
1599             }
1600             case START_USER_SWITCH_MSG: {
1601                 showUserSwitchDialog(msg.arg1, (String) msg.obj);
1602                 break;
1603             }
1604             case DISMISS_DIALOG_MSG: {
1605                 final Dialog d = (Dialog) msg.obj;
1606                 d.dismiss();
1607                 break;
1608             }
1609             case DISPATCH_PROCESSES_CHANGED: {
1610                 dispatchProcessesChanged();
1611                 break;
1612             }
1613             case DISPATCH_PROCESS_DIED: {
1614                 final int pid = msg.arg1;
1615                 final int uid = msg.arg2;
1616                 dispatchProcessDied(pid, uid);
1617                 break;
1618             }
1619             case DISPATCH_UIDS_CHANGED_MSG: {
1620                 dispatchUidsChanged();
1621             } break;
1622             }
1623         }
1624     }
1625
1626     final class MainHandler extends Handler {
1627         public MainHandler(Looper looper) {
1628             super(looper, null, true);
1629         }
1630
1631         @Override
1632         public void handleMessage(Message msg) {
1633             switch (msg.what) {
1634             case UPDATE_CONFIGURATION_MSG: {
1635                 final ContentResolver resolver = mContext.getContentResolver();
1636                 Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1637             } break;
1638             case GC_BACKGROUND_PROCESSES_MSG: {
1639                 synchronized (ActivityManagerService.this) {
1640                     performAppGcsIfAppropriateLocked();
1641                 }
1642             } break;
1643             case SERVICE_TIMEOUT_MSG: {
1644                 if (mDidDexOpt) {
1645                     mDidDexOpt = false;
1646                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1647                     nmsg.obj = msg.obj;
1648                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1649                     return;
1650                 }
1651                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1652             } break;
1653             case UPDATE_TIME_ZONE: {
1654                 synchronized (ActivityManagerService.this) {
1655                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1656                         ProcessRecord r = mLruProcesses.get(i);
1657                         if (r.thread != null) {
1658                             try {
1659                                 r.thread.updateTimeZone();
1660                             } catch (RemoteException ex) {
1661                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1662                             }
1663                         }
1664                     }
1665                 }
1666             } break;
1667             case CLEAR_DNS_CACHE_MSG: {
1668                 synchronized (ActivityManagerService.this) {
1669                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1670                         ProcessRecord r = mLruProcesses.get(i);
1671                         if (r.thread != null) {
1672                             try {
1673                                 r.thread.clearDnsCache();
1674                             } catch (RemoteException ex) {
1675                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1676                             }
1677                         }
1678                     }
1679                 }
1680             } break;
1681             case UPDATE_HTTP_PROXY_MSG: {
1682                 ProxyInfo proxy = (ProxyInfo)msg.obj;
1683                 String host = "";
1684                 String port = "";
1685                 String exclList = "";
1686                 Uri pacFileUrl = Uri.EMPTY;
1687                 if (proxy != null) {
1688                     host = proxy.getHost();
1689                     port = Integer.toString(proxy.getPort());
1690                     exclList = proxy.getExclusionListAsString();
1691                     pacFileUrl = proxy.getPacFileUrl();
1692                 }
1693                 synchronized (ActivityManagerService.this) {
1694                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1695                         ProcessRecord r = mLruProcesses.get(i);
1696                         if (r.thread != null) {
1697                             try {
1698                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1699                             } catch (RemoteException ex) {
1700                                 Slog.w(TAG, "Failed to update http proxy for: " +
1701                                         r.info.processName);
1702                             }
1703                         }
1704                     }
1705                 }
1706             } break;
1707             case PROC_START_TIMEOUT_MSG: {
1708                 if (mDidDexOpt) {
1709                     mDidDexOpt = false;
1710                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1711                     nmsg.obj = msg.obj;
1712                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1713                     return;
1714                 }
1715                 ProcessRecord app = (ProcessRecord)msg.obj;
1716                 synchronized (ActivityManagerService.this) {
1717                     processStartTimedOutLocked(app);
1718                 }
1719             } break;
1720             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1721                 ProcessRecord app = (ProcessRecord)msg.obj;
1722                 synchronized (ActivityManagerService.this) {
1723                     processContentProviderPublishTimedOutLocked(app);
1724                 }
1725             } break;
1726             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1727                 synchronized (ActivityManagerService.this) {
1728                     mStackSupervisor.doPendingActivityLaunchesLocked(true);
1729                 }
1730             } break;
1731             case KILL_APPLICATION_MSG: {
1732                 synchronized (ActivityManagerService.this) {
1733                     int appid = msg.arg1;
1734                     boolean restart = (msg.arg2 == 1);
1735                     Bundle bundle = (Bundle)msg.obj;
1736                     String pkg = bundle.getString("pkg");
1737                     String reason = bundle.getString("reason");
1738                     forceStopPackageLocked(pkg, appid, restart, false, true, false,
1739                             false, UserHandle.USER_ALL, reason);
1740                 }
1741             } break;
1742             case FINALIZE_PENDING_INTENT_MSG: {
1743                 ((PendingIntentRecord)msg.obj).completeFinalize();
1744             } break;
1745             case POST_HEAVY_NOTIFICATION_MSG: {
1746                 INotificationManager inm = NotificationManager.getService();
1747                 if (inm == null) {
1748                     return;
1749                 }
1750
1751                 ActivityRecord root = (ActivityRecord)msg.obj;
1752                 ProcessRecord process = root.app;
1753                 if (process == null) {
1754                     return;
1755                 }
1756
1757                 try {
1758                     Context context = mContext.createPackageContext(process.info.packageName, 0);
1759                     String text = mContext.getString(R.string.heavy_weight_notification,
1760                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
1761                     Notification notification = new Notification.Builder(context)
1762                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1763                             .setWhen(0)
1764                             .setOngoing(true)
1765                             .setTicker(text)
1766                             .setColor(mContext.getColor(
1767                                     com.android.internal.R.color.system_notification_accent_color))
1768                             .setContentTitle(text)
1769                             .setContentText(
1770                                     mContext.getText(R.string.heavy_weight_notification_detail))
1771                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1772                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1773                                     new UserHandle(root.userId)))
1774                             .build();
1775                     try {
1776                         int[] outId = new int[1];
1777                         inm.enqueueNotificationWithTag("android", "android", null,
1778                                 R.string.heavy_weight_notification,
1779                                 notification, outId, root.userId);
1780                     } catch (RuntimeException e) {
1781                         Slog.w(ActivityManagerService.TAG,
1782                                 "Error showing notification for heavy-weight app", e);
1783                     } catch (RemoteException e) {
1784                     }
1785                 } catch (NameNotFoundException e) {
1786                     Slog.w(TAG, "Unable to create context for heavy notification", e);
1787                 }
1788             } break;
1789             case CANCEL_HEAVY_NOTIFICATION_MSG: {
1790                 INotificationManager inm = NotificationManager.getService();
1791                 if (inm == null) {
1792                     return;
1793                 }
1794                 try {
1795                     inm.cancelNotificationWithTag("android", null,
1796                             R.string.heavy_weight_notification,  msg.arg1);
1797                 } catch (RuntimeException e) {
1798                     Slog.w(ActivityManagerService.TAG,
1799                             "Error canceling notification for service", e);
1800                 } catch (RemoteException e) {
1801                 }
1802             } break;
1803             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1804                 synchronized (ActivityManagerService.this) {
1805                     checkExcessivePowerUsageLocked(true);
1806                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1807                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1808                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1809                 }
1810             } break;
1811             case REPORT_MEM_USAGE_MSG: {
1812                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1813                 Thread thread = new Thread() {
1814                     @Override public void run() {
1815                         reportMemUsage(memInfos);
1816                     }
1817                 };
1818                 thread.start();
1819                 break;
1820             }
1821             case REPORT_USER_SWITCH_MSG: {
1822                 dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1823                 break;
1824             }
1825             case CONTINUE_USER_SWITCH_MSG: {
1826                 continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1827                 break;
1828             }
1829             case USER_SWITCH_TIMEOUT_MSG: {
1830                 timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1831                 break;
1832             }
1833             case IMMERSIVE_MODE_LOCK_MSG: {
1834                 final boolean nextState = (msg.arg1 != 0);
1835                 if (mUpdateLock.isHeld() != nextState) {
1836                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1837                             "Applying new update lock state '" + nextState
1838                             + "' for " + (ActivityRecord)msg.obj);
1839                     if (nextState) {
1840                         mUpdateLock.acquire();
1841                     } else {
1842                         mUpdateLock.release();
1843                     }
1844                 }
1845                 break;
1846             }
1847             case PERSIST_URI_GRANTS_MSG: {
1848                 writeGrantedUriPermissions();
1849                 break;
1850             }
1851             case REQUEST_ALL_PSS_MSG: {
1852                 synchronized (ActivityManagerService.this) {
1853                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1854                 }
1855                 break;
1856             }
1857             case START_PROFILES_MSG: {
1858                 synchronized (ActivityManagerService.this) {
1859                     startProfilesLocked();
1860                 }
1861                 break;
1862             }
1863             case UPDATE_TIME: {
1864                 synchronized (ActivityManagerService.this) {
1865                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1866                         ProcessRecord r = mLruProcesses.get(i);
1867                         if (r.thread != null) {
1868                             try {
1869                                 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1870                             } catch (RemoteException ex) {
1871                                 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1872                             }
1873                         }
1874                     }
1875                 }
1876                 break;
1877             }
1878             case SYSTEM_USER_START_MSG: {
1879                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1880                         Integer.toString(msg.arg1), msg.arg1);
1881                 mSystemServiceManager.startUser(msg.arg1);
1882                 break;
1883             }
1884             case SYSTEM_USER_CURRENT_MSG: {
1885                 mBatteryStatsService.noteEvent(
1886                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1887                         Integer.toString(msg.arg2), msg.arg2);
1888                 mBatteryStatsService.noteEvent(
1889                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1890                         Integer.toString(msg.arg1), msg.arg1);
1891                 mSystemServiceManager.switchUser(msg.arg1);
1892                 break;
1893             }
1894             case ENTER_ANIMATION_COMPLETE_MSG: {
1895                 synchronized (ActivityManagerService.this) {
1896                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1897                     if (r != null && r.app != null && r.app.thread != null) {
1898                         try {
1899                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1900                         } catch (RemoteException e) {
1901                         }
1902                     }
1903                 }
1904                 break;
1905             }
1906             case FINISH_BOOTING_MSG: {
1907                 if (msg.arg1 != 0) {
1908                     finishBooting();
1909                 }
1910                 if (msg.arg2 != 0) {
1911                     enableScreenAfterBoot();
1912                 }
1913                 break;
1914             }
1915             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1916                 try {
1917                     Locale l = (Locale) msg.obj;
1918                     IBinder service = ServiceManager.getService("mount");
1919                     IMountService mountService = IMountService.Stub.asInterface(service);
1920                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1921                     mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1922                 } catch (RemoteException e) {
1923                     Log.e(TAG, "Error storing locale for decryption UI", e);
1924                 }
1925                 break;
1926             }
1927             case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1928                 synchronized (ActivityManagerService.this) {
1929                     int i = mTaskStackListeners.beginBroadcast();
1930                     while (i > 0) {
1931                         i--;
1932                         try {
1933                             // Make a one-way callback to the listener
1934                             mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1935                         } catch (RemoteException e){
1936                             // Handled by the RemoteCallbackList
1937                         }
1938                     }
1939                     mTaskStackListeners.finishBroadcast();
1940                 }
1941                 break;
1942             }
1943             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1944                 final int uid = msg.arg1;
1945                 final byte[] firstPacket = (byte[]) msg.obj;
1946
1947                 synchronized (mPidsSelfLocked) {
1948                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1949                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1950                         if (p.uid == uid) {
1951                             try {
1952                                 p.thread.notifyCleartextNetwork(firstPacket);
1953                             } catch (RemoteException ignored) {
1954                             }
1955                         }
1956                     }
1957                 }
1958                 break;
1959             }
1960             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1961                 final String procName;
1962                 final int uid;
1963                 final long memLimit;
1964                 final String reportPackage;
1965                 synchronized (ActivityManagerService.this) {
1966                     procName = mMemWatchDumpProcName;
1967                     uid = mMemWatchDumpUid;
1968                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1969                     if (val == null) {
1970                         val = mMemWatchProcesses.get(procName, 0);
1971                     }
1972                     if (val != null) {
1973                         memLimit = val.first;
1974                         reportPackage = val.second;
1975                     } else {
1976                         memLimit = 0;
1977                         reportPackage = null;
1978                     }
1979                 }
1980                 if (procName == null) {
1981                     return;
1982                 }
1983
1984                 if (DEBUG_PSS) Slog.d(TAG_PSS,
1985                         "Showing dump heap notification from " + procName + "/" + uid);
1986
1987                 INotificationManager inm = NotificationManager.getService();
1988                 if (inm == null) {
1989                     return;
1990                 }
1991
1992                 String text = mContext.getString(R.string.dump_heap_notification, procName);
1993
1994
1995                 Intent deleteIntent = new Intent();
1996                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1997                 Intent intent = new Intent();
1998                 intent.setClassName("android", DumpHeapActivity.class.getName());
1999                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2000                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2001                 if (reportPackage != null) {
2002                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2003                 }
2004                 int userId = UserHandle.getUserId(uid);
2005                 Notification notification = new Notification.Builder(mContext)
2006                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2007                         .setWhen(0)
2008                         .setOngoing(true)
2009                         .setAutoCancel(true)
2010                         .setTicker(text)
2011                         .setColor(mContext.getColor(
2012                                 com.android.internal.R.color.system_notification_accent_color))
2013                         .setContentTitle(text)
2014                         .setContentText(
2015                                 mContext.getText(R.string.dump_heap_notification_detail))
2016                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2017                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2018                                 new UserHandle(userId)))
2019                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2020                                 deleteIntent, 0, UserHandle.OWNER))
2021                         .build();
2022
2023                 try {
2024                     int[] outId = new int[1];
2025                     inm.enqueueNotificationWithTag("android", "android", null,
2026                             R.string.dump_heap_notification,
2027                             notification, outId, userId);
2028                 } catch (RuntimeException e) {
2029                     Slog.w(ActivityManagerService.TAG,
2030                             "Error showing notification for dump heap", e);
2031                 } catch (RemoteException e) {
2032                 }
2033             } break;
2034             case DELETE_DUMPHEAP_MSG: {
2035                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2036                         DumpHeapActivity.JAVA_URI,
2037                         Intent.FLAG_GRANT_READ_URI_PERMISSION
2038                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2039                         UserHandle.myUserId());
2040                 synchronized (ActivityManagerService.this) {
2041                     mMemWatchDumpFile = null;
2042                     mMemWatchDumpProcName = null;
2043                     mMemWatchDumpPid = -1;
2044                     mMemWatchDumpUid = -1;
2045                 }
2046             } break;
2047             case FOREGROUND_PROFILE_CHANGED_MSG: {
2048                 dispatchForegroundProfileChanged(msg.arg1);
2049             } break;
2050             case REPORT_TIME_TRACKER_MSG: {
2051                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2052                 tracker.deliverResult(mContext);
2053             } break;
2054             case REPORT_USER_SWITCH_COMPLETE_MSG: {
2055                 dispatchUserSwitchComplete(msg.arg1);
2056             } break;
2057             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2058                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2059                 try {
2060                     connection.shutdown();
2061                 } catch (RemoteException e) {
2062                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
2063                 }
2064                 // Only a UiAutomation can set this flag and now that
2065                 // it is finished we make sure it is reset to its default.
2066                 mUserIsMonkey = false;
2067             } break;
2068             case APP_BOOST_DEACTIVATE_MSG : {
2069                 synchronized(ActivityManagerService.this) {
2070                     if (mIsBoosted) {
2071                         if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2072                             nativeMigrateFromBoost();
2073                             mIsBoosted = false;
2074                             mBoostStartTime = 0;
2075                         } else {
2076                             Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2077                             mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2078                         }
2079                     }
2080                 }
2081             } break;
2082             }
2083         }
2084     };
2085
2086     static final int COLLECT_PSS_BG_MSG = 1;
2087
2088     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2089         @Override
2090         public void handleMessage(Message msg) {
2091             switch (msg.what) {
2092             case COLLECT_PSS_BG_MSG: {
2093                 long start = SystemClock.uptimeMillis();
2094                 MemInfoReader memInfo = null;
2095                 synchronized (ActivityManagerService.this) {
2096                     if (mFullPssPending) {
2097                         mFullPssPending = false;
2098                         memInfo = new MemInfoReader();
2099                     }
2100                 }
2101                 if (memInfo != null) {
2102                     updateCpuStatsNow();
2103                     long nativeTotalPss = 0;
2104                     synchronized (mProcessCpuTracker) {
2105                         final int N = mProcessCpuTracker.countStats();
2106                         for (int j=0; j<N; j++) {
2107                             ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2108                             if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2109                                 // This is definitely an application process; skip it.
2110                                 continue;
2111                             }
2112                             synchronized (mPidsSelfLocked) {
2113                                 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2114                                     // This is one of our own processes; skip it.
2115                                     continue;
2116                                 }
2117                             }
2118                             nativeTotalPss += Debug.getPss(st.pid, null, null);
2119                         }
2120                     }
2121                     memInfo.readMemInfo();
2122                     synchronized (ActivityManagerService.this) {
2123                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2124                                 + (SystemClock.uptimeMillis()-start) + "ms");
2125                         final long cachedKb = memInfo.getCachedSizeKb();
2126                         final long freeKb = memInfo.getFreeSizeKb();
2127                         final long zramKb = memInfo.getZramTotalSizeKb();
2128                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2129                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2130                                 kernelKb*1024, nativeTotalPss*1024);
2131                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2132                                 nativeTotalPss);
2133                     }
2134                 }
2135
2136                 int num = 0;
2137                 long[] tmp = new long[1];
2138                 do {
2139                     ProcessRecord proc;
2140                     int procState;
2141                     int pid;
2142                     long lastPssTime;
2143                     synchronized (ActivityManagerService.this) {
2144                         if (mPendingPssProcesses.size() <= 0) {
2145                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2146                                     "Collected PSS of " + num + " processes in "
2147                                     + (SystemClock.uptimeMillis() - start) + "ms");
2148                             mPendingPssProcesses.clear();
2149                             return;
2150                         }
2151                         proc = mPendingPssProcesses.remove(0);
2152                         procState = proc.pssProcState;
2153                         lastPssTime = proc.lastPssTime;
2154                         if (proc.thread != null && procState == proc.setProcState
2155                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2156                                         < SystemClock.uptimeMillis()) {
2157                             pid = proc.pid;
2158                         } else {
2159                             proc = null;
2160                             pid = 0;
2161                         }
2162                     }
2163                     if (proc != null) {
2164                         long pss = Debug.getPss(pid, tmp, null);
2165                         synchronized (ActivityManagerService.this) {
2166                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2167                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2168                                 num++;
2169                                 recordPssSampleLocked(proc, procState, pss, tmp[0],
2170                                         SystemClock.uptimeMillis());
2171                             }
2172                         }
2173                     }
2174                 } while (true);
2175             }
2176             }
2177         }
2178     };
2179
2180     public void setSystemProcess() {
2181         try {
2182             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2183             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2184             ServiceManager.addService("meminfo", new MemBinder(this));
2185             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2186             ServiceManager.addService("dbinfo", new DbBinder(this));
2187             if (MONITOR_CPU_USAGE) {
2188                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2189             }
2190             ServiceManager.addService("permission", new PermissionController(this));
2191             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2192
2193             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2194                     "android", STOCK_PM_FLAGS);
2195             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2196
2197             synchronized (this) {
2198                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2199                 app.persistent = true;
2200                 app.pid = MY_PID;
2201                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2202                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2203                 synchronized (mPidsSelfLocked) {
2204                     mPidsSelfLocked.put(app.pid, app);
2205                 }
2206                 updateLruProcessLocked(app, false, null);
2207                 updateOomAdjLocked();
2208             }
2209         } catch (PackageManager.NameNotFoundException e) {
2210             throw new RuntimeException(
2211                     "Unable to find android system package", e);
2212         }
2213     }
2214
2215     public void setWindowManager(WindowManagerService wm) {
2216         mWindowManager = wm;
2217         mStackSupervisor.setWindowManager(wm);
2218     }
2219
2220     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2221         mUsageStatsService = usageStatsManager;
2222     }
2223
2224     public void startObservingNativeCrashes() {
2225         final NativeCrashListener ncl = new NativeCrashListener(this);
2226         ncl.start();
2227     }
2228
2229     public IAppOpsService getAppOpsService() {
2230         return mAppOpsService;
2231     }
2232
2233     static class MemBinder extends Binder {
2234         ActivityManagerService mActivityManagerService;
2235         MemBinder(ActivityManagerService activityManagerService) {
2236             mActivityManagerService = activityManagerService;
2237         }
2238
2239         @Override
2240         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2241             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2242                     != PackageManager.PERMISSION_GRANTED) {
2243                 pw.println("Permission Denial: can't dump meminfo from from pid="
2244                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2245                         + " without permission " + android.Manifest.permission.DUMP);
2246                 return;
2247             }
2248
2249             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2250         }
2251     }
2252
2253     static class GraphicsBinder extends Binder {
2254         ActivityManagerService mActivityManagerService;
2255         GraphicsBinder(ActivityManagerService activityManagerService) {
2256             mActivityManagerService = activityManagerService;
2257         }
2258
2259         @Override
2260         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2261             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2262                     != PackageManager.PERMISSION_GRANTED) {
2263                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2264                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2265                         + " without permission " + android.Manifest.permission.DUMP);
2266                 return;
2267             }
2268
2269             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2270         }
2271     }
2272
2273     static class DbBinder extends Binder {
2274         ActivityManagerService mActivityManagerService;
2275         DbBinder(ActivityManagerService activityManagerService) {
2276             mActivityManagerService = activityManagerService;
2277         }
2278
2279         @Override
2280         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2281             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2282                     != PackageManager.PERMISSION_GRANTED) {
2283                 pw.println("Permission Denial: can't dump dbinfo from from pid="
2284                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2285                         + " without permission " + android.Manifest.permission.DUMP);
2286                 return;
2287             }
2288
2289             mActivityManagerService.dumpDbInfo(fd, pw, args);
2290         }
2291     }
2292
2293     static class CpuBinder extends Binder {
2294         ActivityManagerService mActivityManagerService;
2295         CpuBinder(ActivityManagerService activityManagerService) {
2296             mActivityManagerService = activityManagerService;
2297         }
2298
2299         @Override
2300         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2301             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2302                     != PackageManager.PERMISSION_GRANTED) {
2303                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2304                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2305                         + " without permission " + android.Manifest.permission.DUMP);
2306                 return;
2307             }
2308
2309             synchronized (mActivityManagerService.mProcessCpuTracker) {
2310                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2311                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2312                         SystemClock.uptimeMillis()));
2313             }
2314         }
2315     }
2316
2317     public static final class Lifecycle extends SystemService {
2318         private final ActivityManagerService mService;
2319
2320         public Lifecycle(Context context) {
2321             super(context);
2322             mService = new ActivityManagerService(context);
2323         }
2324
2325         @Override
2326         public void onStart() {
2327             mService.start();
2328         }
2329
2330         public ActivityManagerService getService() {
2331             return mService;
2332         }
2333     }
2334
2335     // Note: This method is invoked on the main thread but may need to attach various
2336     // handlers to other threads.  So take care to be explicit about the looper.
2337     public ActivityManagerService(Context systemContext) {
2338         mContext = systemContext;
2339         mFactoryTest = FactoryTest.getMode();
2340         mSystemThread = ActivityThread.currentActivityThread();
2341
2342         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2343
2344         mHandlerThread = new ServiceThread(TAG,
2345                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2346         mHandlerThread.start();
2347         mHandler = new MainHandler(mHandlerThread.getLooper());
2348         mUiHandler = new UiHandler();
2349
2350         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2351                 "foreground", BROADCAST_FG_TIMEOUT, false);
2352         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2353                 "background", BROADCAST_BG_TIMEOUT, true);
2354         mBroadcastQueues[0] = mFgBroadcastQueue;
2355         mBroadcastQueues[1] = mBgBroadcastQueue;
2356
2357         mServices = new ActiveServices(this);
2358         mProviderMap = new ProviderMap(this);
2359
2360         // TODO: Move creation of battery stats service outside of activity manager service.
2361         File dataDir = Environment.getDataDirectory();
2362         File systemDir = new File(dataDir, "system");
2363         systemDir.mkdirs();
2364         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2365         mBatteryStatsService.getActiveStatistics().readLocked();
2366         mBatteryStatsService.scheduleWriteToDisk();
2367         mOnBattery = DEBUG_POWER ? true
2368                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2369         mBatteryStatsService.getActiveStatistics().setCallback(this);
2370
2371         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2372
2373         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2374
2375         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2376
2377         // User 0 is the first and only user that runs at boot.
2378         mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
2379         mUserLru.add(UserHandle.USER_OWNER);
2380         updateStartedUserArrayLocked();
2381
2382         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2383             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2384
2385         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2386
2387         mConfiguration.setToDefaults();
2388         mConfiguration.setLocale(Locale.getDefault());
2389
2390         mConfigurationSeq = mConfiguration.seq = 1;
2391         mProcessCpuTracker.init();
2392
2393         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2394         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2395         mRecentTasks = new RecentTasks(this);
2396         mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2397         mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2398
2399         mProcessCpuThread = new Thread("CpuTracker") {
2400             @Override
2401             public void run() {
2402                 while (true) {
2403                     try {
2404                         try {
2405                             synchronized(this) {
2406                                 final long now = SystemClock.uptimeMillis();
2407                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2408                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2409                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2410                                 //        + ", write delay=" + nextWriteDelay);
2411                                 if (nextWriteDelay < nextCpuDelay) {
2412                                     nextCpuDelay = nextWriteDelay;
2413                                 }
2414                                 if (nextCpuDelay > 0) {
2415                                     mProcessCpuMutexFree.set(true);
2416                                     this.wait(nextCpuDelay);
2417                                 }
2418                             }
2419                         } catch (InterruptedException e) {
2420                         }
2421                         updateCpuStatsNow();
2422                     } catch (Exception e) {
2423                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2424                     }
2425                 }
2426             }
2427         };
2428
2429         Watchdog.getInstance().addMonitor(this);
2430         Watchdog.getInstance().addThread(mHandler);
2431     }
2432
2433     public void setSystemServiceManager(SystemServiceManager mgr) {
2434         mSystemServiceManager = mgr;
2435     }
2436
2437     public void setInstaller(Installer installer) {
2438         mInstaller = installer;
2439     }
2440
2441     private void start() {
2442         Process.removeAllProcessGroups();
2443         mProcessCpuThread.start();
2444
2445         mBatteryStatsService.publish(mContext);
2446         mAppOpsService.publish(mContext);
2447         Slog.d("AppOps", "AppOpsService published");
2448         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2449     }
2450
2451     public void initPowerManagement() {
2452         mStackSupervisor.initPowerManagement();
2453         mBatteryStatsService.initPowerManagement();
2454         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2455         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2456         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2457         mVoiceWakeLock.setReferenceCounted(false);
2458     }
2459
2460     @Override
2461     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2462             throws RemoteException {
2463         if (code == SYSPROPS_TRANSACTION) {
2464             // We need to tell all apps about the system property change.
2465             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2466             synchronized(this) {
2467                 final int NP = mProcessNames.getMap().size();
2468                 for (int ip=0; ip<NP; ip++) {
2469                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2470                     final int NA = apps.size();
2471                     for (int ia=0; ia<NA; ia++) {
2472                         ProcessRecord app = apps.valueAt(ia);
2473                         if (app.thread != null) {
2474                             procs.add(app.thread.asBinder());
2475                         }
2476                     }
2477                 }
2478             }
2479
2480             int N = procs.size();
2481             for (int i=0; i<N; i++) {
2482                 Parcel data2 = Parcel.obtain();
2483                 try {
2484                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2485                 } catch (RemoteException e) {
2486                 }
2487                 data2.recycle();
2488             }
2489         }
2490         try {
2491             return super.onTransact(code, data, reply, flags);
2492         } catch (RuntimeException e) {
2493             // The activity manager only throws security exceptions, so let's
2494             // log all others.
2495             if (!(e instanceof SecurityException)) {
2496                 Slog.wtf(TAG, "Activity Manager Crash", e);
2497             }
2498             throw e;
2499         }
2500     }
2501
2502     void updateCpuStats() {
2503         final long now = SystemClock.uptimeMillis();
2504         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2505             return;
2506         }
2507         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2508             synchronized (mProcessCpuThread) {
2509                 mProcessCpuThread.notify();
2510             }
2511         }
2512     }
2513
2514     void updateCpuStatsNow() {
2515         synchronized (mProcessCpuTracker) {
2516             mProcessCpuMutexFree.set(false);
2517             final long now = SystemClock.uptimeMillis();
2518             boolean haveNewCpuStats = false;
2519
2520             if (MONITOR_CPU_USAGE &&
2521                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2522                 mLastCpuTime.set(now);
2523                 mProcessCpuTracker.update();
2524                 if (mProcessCpuTracker.hasGoodLastStats()) {
2525                     haveNewCpuStats = true;
2526                     //Slog.i(TAG, mProcessCpu.printCurrentState());
2527                     //Slog.i(TAG, "Total CPU usage: "
2528                     //        + mProcessCpu.getTotalCpuPercent() + "%");
2529
2530                     // Slog the cpu usage if the property is set.
2531                     if ("true".equals(SystemProperties.get("events.cpu"))) {
2532                         int user = mProcessCpuTracker.getLastUserTime();
2533                         int system = mProcessCpuTracker.getLastSystemTime();
2534                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
2535                         int irq = mProcessCpuTracker.getLastIrqTime();
2536                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2537                         int idle = mProcessCpuTracker.getLastIdleTime();
2538
2539                         int total = user + system + iowait + irq + softIrq + idle;
2540                         if (total == 0) total = 1;
2541
2542                         EventLog.writeEvent(EventLogTags.CPU,
2543                                 ((user+system+iowait+irq+softIrq) * 100) / total,
2544                                 (user * 100) / total,
2545                                 (system * 100) / total,
2546                                 (iowait * 100) / total,
2547                                 (irq * 100) / total,
2548                                 (softIrq * 100) / total);
2549                     }
2550                 }
2551             }
2552
2553             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2554             synchronized(bstats) {
2555                 synchronized(mPidsSelfLocked) {
2556                     if (haveNewCpuStats) {
2557                         if (bstats.startAddingCpuLocked()) {
2558                             int totalUTime = 0;
2559                             int totalSTime = 0;
2560                             final int N = mProcessCpuTracker.countStats();
2561                             for (int i=0; i<N; i++) {
2562                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2563                                 if (!st.working) {
2564                                     continue;
2565                                 }
2566                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2567                                 totalUTime += st.rel_utime;
2568                                 totalSTime += st.rel_stime;
2569                                 if (pr != null) {
2570                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2571                                     if (ps == null || !ps.isActive()) {
2572                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2573                                                 pr.info.uid, pr.processName);
2574                                     }
2575                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2576                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
2577                                 } else {
2578                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2579                                     if (ps == null || !ps.isActive()) {
2580                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
2581                                                 bstats.mapUid(st.uid), st.name);
2582                                     }
2583                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2584                                 }
2585                             }
2586                             final int userTime = mProcessCpuTracker.getLastUserTime();
2587                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
2588                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2589                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
2590                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2591                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
2592                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2593                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2594                         }
2595                     }
2596                 }
2597
2598                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2599                     mLastWriteTime = now;
2600                     mBatteryStatsService.scheduleWriteToDisk();
2601                 }
2602             }
2603         }
2604     }
2605
2606     @Override
2607     public void batteryNeedsCpuUpdate() {
2608         updateCpuStatsNow();
2609     }
2610
2611     @Override
2612     public void batteryPowerChanged(boolean onBattery) {
2613         // When plugging in, update the CPU stats first before changing
2614         // the plug state.
2615         updateCpuStatsNow();
2616         synchronized (this) {
2617             synchronized(mPidsSelfLocked) {
2618                 mOnBattery = DEBUG_POWER ? true : onBattery;
2619             }
2620         }
2621     }
2622
2623     @Override
2624     public void batterySendBroadcast(Intent intent) {
2625         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2626                 AppOpsManager.OP_NONE, null, false, false,
2627                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2628     }
2629
2630     /**
2631      * Initialize the application bind args. These are passed to each
2632      * process when the bindApplication() IPC is sent to the process. They're
2633      * lazily setup to make sure the services are running when they're asked for.
2634      */
2635     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2636         // Isolated processes won't get this optimization, so that we don't
2637         // violate the rules about which services they have access to.
2638         if (isolated) {
2639             if (mIsolatedAppBindArgs == null) {
2640                 mIsolatedAppBindArgs = new HashMap<>();
2641                 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2642             }
2643             return mIsolatedAppBindArgs;
2644         }
2645
2646         if (mAppBindArgs == null) {
2647             mAppBindArgs = new HashMap<>();
2648
2649             // Setup the application init args
2650             mAppBindArgs.put("package", ServiceManager.getService("package"));
2651             mAppBindArgs.put("window", ServiceManager.getService("window"));
2652             mAppBindArgs.put(Context.ALARM_SERVICE,
2653                     ServiceManager.getService(Context.ALARM_SERVICE));
2654         }
2655         return mAppBindArgs;
2656     }
2657
2658     final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2659         if (r != null && mFocusedActivity != r) {
2660             if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2661             ActivityRecord last = mFocusedActivity;
2662             mFocusedActivity = r;
2663             if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2664                     && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2665                 if (mCurAppTimeTracker != r.appTimeTracker) {
2666                     // We are switching app tracking.  Complete the current one.
2667                     if (mCurAppTimeTracker != null) {
2668                         mCurAppTimeTracker.stop();
2669                         mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2670                                 mCurAppTimeTracker).sendToTarget();
2671                         mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2672                         mCurAppTimeTracker = null;
2673                     }
2674                     if (r.appTimeTracker != null) {
2675                         mCurAppTimeTracker = r.appTimeTracker;
2676                         startTimeTrackingFocusedActivityLocked();
2677                     }
2678                 } else {
2679                     startTimeTrackingFocusedActivityLocked();
2680                 }
2681             } else {
2682                 r.appTimeTracker = null;
2683             }
2684             if (r.task != null && r.task.voiceInteractor != null) {
2685                 startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2686             } else {
2687                 finishRunningVoiceLocked();
2688                 if (last != null && last.task.voiceSession != null) {
2689                     // We had been in a voice interaction session, but now focused has
2690                     // move to something different.  Just finish the session, we can't
2691                     // return to it and retain the proper state and synchronization with
2692                     // the voice interaction service.
2693                     finishVoiceTask(last.task.voiceSession);
2694                 }
2695             }
2696             if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2697                 mWindowManager.setFocusedApp(r.appToken, true);
2698             }
2699             applyUpdateLockStateLocked(r);
2700             if (mFocusedActivity.userId != mLastFocusedUserId) {
2701                 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2702                 mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2703                         mFocusedActivity.userId, 0));
2704                 mLastFocusedUserId = mFocusedActivity.userId;
2705             }
2706         }
2707         EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2708                 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2709                 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2710     }
2711
2712     final void clearFocusedActivity(ActivityRecord r) {
2713         if (mFocusedActivity == r) {
2714             ActivityStack stack = mStackSupervisor.getFocusedStack();
2715             if (stack != null) {
2716                 ActivityRecord top = stack.topActivity();
2717                 if (top != null && top.userId != mLastFocusedUserId) {
2718                     mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2719                     mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2720                                     top.userId, 0));
2721                     mLastFocusedUserId = top.userId;
2722                 }
2723             }
2724             mFocusedActivity = null;
2725             EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2726         }
2727     }
2728
2729     @Override
2730     public void setFocusedStack(int stackId) {
2731         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2732         synchronized (ActivityManagerService.this) {
2733             ActivityStack stack = mStackSupervisor.getStack(stackId);
2734             if (stack != null) {
2735                 ActivityRecord r = stack.topRunningActivityLocked(null);
2736                 if (r != null) {
2737                     setFocusedActivityLocked(r, "setFocusedStack");
2738                     mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2739                 }
2740             }
2741         }
2742     }
2743
2744     /** Sets the task stack listener that gets callbacks when a task stack changes. */
2745     @Override
2746     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2747         synchronized (ActivityManagerService.this) {
2748             if (listener != null) {
2749                 mTaskStackListeners.register(listener);
2750             }
2751         }
2752     }
2753
2754     @Override
2755     public void notifyActivityDrawn(IBinder token) {
2756         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2757         synchronized (this) {
2758             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2759             if (r != null) {
2760                 r.task.stack.notifyActivityDrawnLocked(r);
2761             }
2762         }
2763     }
2764
2765     final void applyUpdateLockStateLocked(ActivityRecord r) {
2766         // Modifications to the UpdateLock state are done on our handler, outside
2767         // the activity manager's locks.  The new state is determined based on the
2768         // state *now* of the relevant activity record.  The object is passed to
2769         // the handler solely for logging detail, not to be consulted/modified.
2770         final boolean nextState = r != null && r.immersive;
2771         mHandler.sendMessage(
2772                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2773     }
2774
2775     final void showAskCompatModeDialogLocked(ActivityRecord r) {
2776         Message msg = Message.obtain();
2777         msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2778         msg.obj = r.task.askedCompatMode ? null : r;
2779         mUiHandler.sendMessage(msg);
2780     }
2781
2782     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2783             String what, Object obj, ProcessRecord srcApp) {
2784         app.lastActivityTime = now;
2785
2786         if (app.activities.size() > 0) {
2787             // Don't want to touch dependent processes that are hosting activities.
2788             return index;
2789         }
2790
2791         int lrui = mLruProcesses.lastIndexOf(app);
2792         if (lrui < 0) {
2793             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2794                     + what + " " + obj + " from " + srcApp);
2795             return index;
2796         }
2797
2798         if (lrui >= index) {
2799             // Don't want to cause this to move dependent processes *back* in the
2800             // list as if they were less frequently used.
2801             return index;
2802         }
2803
2804         if (lrui >= mLruProcessActivityStart) {
2805             // Don't want to touch dependent processes that are hosting activities.
2806             return index;
2807         }
2808
2809         mLruProcesses.remove(lrui);
2810         if (index > 0) {
2811             index--;
2812         }
2813         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2814                 + " in LRU list: " + app);
2815         mLruProcesses.add(index, app);
2816         return index;
2817     }
2818
2819     private static void killProcessGroup(int uid, int pid) {
2820         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2821         Process.killProcessGroup(uid, pid);
2822         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2823     }
2824
2825     final void removeLruProcessLocked(ProcessRecord app) {
2826         int lrui = mLruProcesses.lastIndexOf(app);
2827         if (lrui >= 0) {
2828             if (!app.killed) {
2829                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2830                 Process.killProcessQuiet(app.pid);
2831                 killProcessGroup(app.uid, app.pid);
2832             }
2833             if (lrui <= mLruProcessActivityStart) {
2834                 mLruProcessActivityStart--;
2835             }
2836             if (lrui <= mLruProcessServiceStart) {
2837                 mLruProcessServiceStart--;
2838             }
2839             mLruProcesses.remove(lrui);
2840         }
2841     }
2842
2843     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2844             ProcessRecord client) {
2845         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2846                 || app.treatLikeActivity;
2847         final boolean hasService = false; // not impl yet. app.services.size() > 0;
2848         if (!activityChange && hasActivity) {
2849             // The process has activities, so we are only allowing activity-based adjustments
2850             // to move it.  It should be kept in the front of the list with other
2851             // processes that have activities, and we don't want those to change their
2852             // order except due to activity operations.
2853             return;
2854         }
2855
2856         mLruSeq++;
2857         final long now = SystemClock.uptimeMillis();
2858         app.lastActivityTime = now;
2859
2860         // First a quick reject: if the app is already at the position we will
2861         // put it, then there is nothing to do.
2862         if (hasActivity) {
2863             final int N = mLruProcesses.size();
2864             if (N > 0 && mLruProcesses.get(N-1) == app) {
2865                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2866                 return;
2867             }
2868         } else {
2869             if (mLruProcessServiceStart > 0
2870                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2871                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2872                 return;
2873             }
2874         }
2875
2876         int lrui = mLruProcesses.lastIndexOf(app);
2877
2878         if (app.persistent && lrui >= 0) {
2879             // We don't care about the position of persistent processes, as long as
2880             // they are in the list.
2881             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2882             return;
2883         }
2884
2885         /* In progress: compute new position first, so we can avoid doing work
2886            if the process is not actually going to move.  Not yet working.
2887         int addIndex;
2888         int nextIndex;
2889         boolean inActivity = false, inService = false;
2890         if (hasActivity) {
2891             // Process has activities, put it at the very tipsy-top.
2892             addIndex = mLruProcesses.size();
2893             nextIndex = mLruProcessServiceStart;
2894             inActivity = true;
2895         } else if (hasService) {
2896             // Process has services, put it at the top of the service list.
2897             addIndex = mLruProcessActivityStart;
2898             nextIndex = mLruProcessServiceStart;
2899             inActivity = true;
2900             inService = true;
2901         } else  {
2902             // Process not otherwise of interest, it goes to the top of the non-service area.
2903             addIndex = mLruProcessServiceStart;
2904             if (client != null) {
2905                 int clientIndex = mLruProcesses.lastIndexOf(client);
2906                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2907                         + app);
2908                 if (clientIndex >= 0 && addIndex > clientIndex) {
2909                     addIndex = clientIndex;
2910                 }
2911             }
2912             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2913         }
2914
2915         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2916                 + mLruProcessActivityStart + "): " + app);
2917         */
2918
2919         if (lrui >= 0) {
2920             if (lrui < mLruProcessActivityStart) {
2921                 mLruProcessActivityStart--;
2922             }
2923             if (lrui < mLruProcessServiceStart) {
2924                 mLruProcessServiceStart--;
2925             }
2926             /*
2927             if (addIndex > lrui) {
2928                 addIndex--;
2929             }
2930             if (nextIndex > lrui) {
2931                 nextIndex--;
2932             }
2933             */
2934             mLruProcesses.remove(lrui);
2935         }
2936
2937         /*
2938         mLruProcesses.add(addIndex, app);
2939         if (inActivity) {
2940             mLruProcessActivityStart++;
2941         }
2942         if (inService) {
2943             mLruProcessActivityStart++;
2944         }
2945         */
2946
2947         int nextIndex;
2948         if (hasActivity) {
2949             final int N = mLruProcesses.size();
2950             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2951                 // Process doesn't have activities, but has clients with
2952                 // activities...  move it up, but one below the top (the top
2953                 // should always have a real activity).
2954                 if (DEBUG_LRU) Slog.d(TAG_LRU,
2955                         "Adding to second-top of LRU activity list: " + app);
2956                 mLruProcesses.add(N - 1, app);
2957                 // To keep it from spamming the LRU list (by making a bunch of clients),
2958                 // we will push down any other entries owned by the app.
2959                 final int uid = app.info.uid;
2960                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2961                     ProcessRecord subProc = mLruProcesses.get(i);
2962                     if (subProc.info.uid == uid) {
2963                         // We want to push this one down the list.  If the process after
2964                         // it is for the same uid, however, don't do so, because we don't
2965                         // want them internally to be re-ordered.
2966                         if (mLruProcesses.get(i - 1).info.uid != uid) {
2967                             if (DEBUG_LRU) Slog.d(TAG_LRU,
2968                                     "Pushing uid " + uid + " swapping at " + i + ": "
2969                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2970                             ProcessRecord tmp = mLruProcesses.get(i);
2971                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
2972                             mLruProcesses.set(i - 1, tmp);
2973                             i--;
2974                         }
2975                     } else {
2976                         // A gap, we can stop here.
2977                         break;
2978                     }
2979                 }
2980             } else {
2981                 // Process has activities, put it at the very tipsy-top.
2982                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2983                 mLruProcesses.add(app);
2984             }
2985             nextIndex = mLruProcessServiceStart;
2986         } else if (hasService) {
2987             // Process has services, put it at the top of the service list.
2988             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2989             mLruProcesses.add(mLruProcessActivityStart, app);
2990             nextIndex = mLruProcessServiceStart;
2991             mLruProcessActivityStart++;
2992         } else  {
2993             // Process not otherwise of interest, it goes to the top of the non-service area.
2994             int index = mLruProcessServiceStart;
2995             if (client != null) {
2996                 // If there is a client, don't allow the process to be moved up higher
2997                 // in the list than that client.
2998                 int clientIndex = mLruProcesses.lastIndexOf(client);
2999                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3000                         + " when updating " + app);
3001                 if (clientIndex <= lrui) {
3002                     // Don't allow the client index restriction to push it down farther in the
3003                     // list than it already is.
3004                     clientIndex = lrui;
3005                 }
3006                 if (clientIndex >= 0 && index > clientIndex) {
3007                     index = clientIndex;
3008                 }
3009             }
3010             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3011             mLruProcesses.add(index, app);
3012             nextIndex = index-1;
3013             mLruProcessActivityStart++;
3014             mLruProcessServiceStart++;
3015         }
3016
3017         // If the app is currently using a content provider or service,
3018         // bump those processes as well.
3019         for (int j=app.connections.size()-1; j>=0; j--) {
3020             ConnectionRecord cr = app.connections.valueAt(j);
3021             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3022                     && cr.binding.service.app != null
3023                     && cr.binding.service.app.lruSeq != mLruSeq
3024                     && !cr.binding.service.app.persistent) {
3025                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3026                         "service connection", cr, app);
3027             }
3028         }
3029         for (int j=app.conProviders.size()-1; j>=0; j--) {
3030             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3031             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3032                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3033                         "provider reference", cpr, app);
3034             }
3035         }
3036     }
3037
3038     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3039         if (uid == Process.SYSTEM_UID) {
3040             // The system gets to run in any process.  If there are multiple
3041             // processes with the same uid, just pick the first (this
3042             // should never happen).
3043             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3044             if (procs == null) return null;
3045             final int procCount = procs.size();
3046             for (int i = 0; i < procCount; i++) {
3047                 final int procUid = procs.keyAt(i);
3048                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3049                     // Don't use an app process or different user process for system component.
3050                     continue;
3051                 }
3052                 return procs.valueAt(i);
3053             }
3054         }
3055         ProcessRecord proc = mProcessNames.get(processName, uid);
3056         if (false && proc != null && !keepIfLarge
3057                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3058                 && proc.lastCachedPss >= 4000) {
3059             // Turn this condition on to cause killing to happen regularly, for testing.
3060             if (proc.baseProcessTracker != null) {
3061                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3062             }
3063             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3064         } else if (proc != null && !keepIfLarge
3065                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3066                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3067             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3068             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3069                 if (proc.baseProcessTracker != null) {
3070                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3071                 }
3072                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3073             }
3074         }
3075         return proc;
3076     }
3077
3078     void ensurePackageDexOpt(String packageName) {
3079         IPackageManager pm = AppGlobals.getPackageManager();
3080         try {
3081             if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3082                 mDidDexOpt = true;
3083             }
3084         } catch (RemoteException e) {
3085         }
3086     }
3087
3088     boolean isNextTransitionForward() {
3089         int transit = mWindowManager.getPendingAppTransition();
3090         return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3091                 || transit == AppTransition.TRANSIT_TASK_OPEN
3092                 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3093     }
3094
3095     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3096             String processName, String abiOverride, int uid, Runnable crashHandler) {
3097         synchronized(this) {
3098             ApplicationInfo info = new ApplicationInfo();
3099             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3100             // For isolated processes, the former contains the parent's uid and the latter the
3101             // actual uid of the isolated process.
3102             // In the special case introduced by this method (which is, starting an isolated
3103             // process directly from the SystemServer without an actual parent app process) the
3104             // closest thing to a parent's uid is SYSTEM_UID.
3105             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3106             // the |isolated| logic in the ProcessRecord constructor.
3107             info.uid = Process.SYSTEM_UID;
3108             info.processName = processName;
3109             info.className = entryPoint;
3110             info.packageName = "android";
3111             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3112                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3113                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3114                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3115                     crashHandler);
3116             return proc != null ? proc.pid : 0;
3117         }
3118     }
3119
3120     final ProcessRecord startProcessLocked(String processName,
3121             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3122             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3123             boolean isolated, boolean keepIfLarge) {
3124         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3125                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3126                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3127                 null /* crashHandler */);
3128     }
3129
3130     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3131             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3132             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3133             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3134         long startTime = SystemClock.elapsedRealtime();
3135         ProcessRecord app;
3136         if (!isolated) {
3137             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3138             checkTime(startTime, "startProcess: after getProcessRecord");
3139
3140             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3141                 // If we are in the background, then check to see if this process
3142                 // is bad.  If so, we will just silently fail.
3143                 if (mBadProcesses.get(info.processName, info.uid) != null) {
3144                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3145                             + "/" + info.processName);
3146                     return null;
3147                 }
3148             } else {
3149                 // When the user is explicitly starting a process, then clear its
3150                 // crash count so that we won't make it bad until they see at
3151                 // least one crash dialog again, and make the process good again
3152                 // if it had been bad.
3153                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3154                         + "/" + info.processName);
3155                 mProcessCrashTimes.remove(info.processName, info.uid);
3156                 if (mBadProcesses.get(info.processName, info.uid) != null) {
3157                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3158                             UserHandle.getUserId(info.uid), info.uid,
3159                             info.processName);
3160                     mBadProcesses.remove(info.processName, info.uid);
3161                     if (app != null) {
3162                         app.bad = false;
3163                     }
3164                 }
3165             }
3166         } else {
3167             // If this is an isolated process, it can't re-use an existing process.
3168             app = null;
3169         }
3170
3171         // app launch boost for big.little configurations
3172         // use cpusets to migrate freshly launched tasks to big cores
3173         synchronized(ActivityManagerService.this) {
3174             nativeMigrateToBoost();
3175             mIsBoosted = true;
3176             mBoostStartTime = SystemClock.uptimeMillis();
3177             Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3178             mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3179         }
3180
3181         // We don't have to do anything more if:
3182         // (1) There is an existing application record; and
3183         // (2) The caller doesn't think it is dead, OR there is no thread
3184         //     object attached to it so we know it couldn't have crashed; and
3185         // (3) There is a pid assigned to it, so it is either starting or
3186         //     already running.
3187         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3188                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3189                 + " thread=" + (app != null ? app.thread : null)
3190                 + " pid=" + (app != null ? app.pid : -1));
3191         if (app != null && app.pid > 0) {
3192             if (!knownToBeDead || app.thread == null) {
3193                 // We already have the app running, or are waiting for it to
3194                 // come up (we have a pid but not yet its thread), so keep it.
3195                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3196                 // If this is a new package in the process, add the package to the list
3197                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3198                 checkTime(startTime, "startProcess: done, added package to proc");
3199                 return app;
3200             }
3201
3202             // An application record is attached to a previous process,
3203             // clean it up now.
3204             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3205             checkTime(startTime, "startProcess: bad proc running, killing");
3206             killProcessGroup(app.uid, app.pid);
3207             handleAppDiedLocked(app, true, true);
3208             checkTime(startTime, "startProcess: done killing old proc");
3209         }
3210
3211         String hostingNameStr = hostingName != null
3212                 ? hostingName.flattenToShortString() : null;
3213
3214         if (app == null) {
3215             checkTime(startTime, "startProcess: creating new process record");
3216             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3217             if (app == null) {
3218                 Slog.w(TAG, "Failed making new process record for "
3219                         + processName + "/" + info.uid + " isolated=" + isolated);
3220                 return null;
3221             }
3222             app.crashHandler = crashHandler;
3223             checkTime(startTime, "startProcess: done creating new process record");
3224         } else {
3225             // If this is a new package in the process, add the package to the list
3226             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3227             checkTime(startTime, "startProcess: added package to existing proc");
3228         }
3229
3230         // If the system is not ready yet, then hold off on starting this
3231         // process until it is.
3232         if (!mProcessesReady
3233                 && !isAllowedWhileBooting(info)
3234                 && !allowWhileBooting) {
3235             if (!mProcessesOnHold.contains(app)) {
3236                 mProcessesOnHold.add(app);
3237             }
3238             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3239                     "System not ready, putting on hold: " + app);
3240             checkTime(startTime, "startProcess: returning with proc on hold");
3241             return app;
3242         }
3243
3244         checkTime(startTime, "startProcess: stepping in to startProcess");
3245         startProcessLocked(
3246                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3247         checkTime(startTime, "startProcess: done starting proc!");
3248         return (app.pid != 0) ? app : null;
3249     }
3250
3251     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3252         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3253     }
3254
3255     private final void startProcessLocked(ProcessRecord app,
3256             String hostingType, String hostingNameStr) {
3257         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3258                 null /* entryPoint */, null /* entryPointArgs */);
3259     }
3260
3261     private final void startProcessLocked(ProcessRecord app, String hostingType,
3262             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3263         long startTime = SystemClock.elapsedRealtime();
3264         if (app.pid > 0 && app.pid != MY_PID) {
3265             checkTime(startTime, "startProcess: removing from pids map");
3266             synchronized (mPidsSelfLocked) {
3267                 mPidsSelfLocked.remove(app.pid);
3268                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3269             }
3270             checkTime(startTime, "startProcess: done removing from pids map");
3271             app.setPid(0);
3272         }
3273
3274         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3275                 "startProcessLocked removing on hold: " + app);
3276         mProcessesOnHold.remove(app);
3277
3278         checkTime(startTime, "startProcess: starting to update cpu stats");
3279         updateCpuStats();
3280         checkTime(startTime, "startProcess: done updating cpu stats");
3281
3282         try {
3283             try {
3284                 if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3285                     // This is caught below as if we had failed to fork zygote
3286                     throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3287                 }
3288             } catch (RemoteException e) {
3289                 throw e.rethrowAsRuntimeException();
3290             }
3291
3292             int uid = app.uid;
3293             int[] gids = null;
3294             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3295             if (!app.isolated) {
3296                 int[] permGids = null;
3297                 try {
3298                     checkTime(startTime, "startProcess: getting gids from package manager");
3299                     final IPackageManager pm = AppGlobals.getPackageManager();
3300                     permGids = pm.getPackageGids(app.info.packageName, app.userId);
3301                     MountServiceInternal mountServiceInternal = LocalServices.getService(
3302                             MountServiceInternal.class);
3303                     mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3304                             app.info.packageName);
3305                 } catch (RemoteException e) {
3306                     throw e.rethrowAsRuntimeException();
3307                 }
3308
3309                 /*
3310                  * Add shared application and profile GIDs so applications can share some
3311                  * resources like shared libraries and access user-wide resources
3312                  */
3313                 if (ArrayUtils.isEmpty(permGids)) {
3314                     gids = new int[2];
3315                 } else {
3316                     gids = new int[permGids.length + 2];
3317                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
3318                 }
3319                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3320                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3321             }
3322             checkTime(startTime, "startProcess: building args");
3323             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3324                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3325                         && mTopComponent != null
3326                         && app.processName.equals(mTopComponent.getPackageName())) {
3327                     uid = 0;
3328                 }
3329                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3330                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3331                     uid = 0;
3332                 }
3333             }
3334             int debugFlags = 0;
3335             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3336                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3337                 // Also turn on CheckJNI for debuggable apps. It's quite
3338                 // awkward to turn on otherwise.
3339                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3340             }
3341             // Run the app in safe mode if its manifest requests so or the
3342             // system is booted in safe mode.
3343             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3344                 mSafeMode == true) {
3345                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3346             }
3347             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3348                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3349             }
3350             String jitDebugProperty = SystemProperties.get("debug.usejit");
3351             if ("true".equals(jitDebugProperty)) {
3352                 debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3353             } else if (!"false".equals(jitDebugProperty)) {
3354                 // If we didn't force disable by setting false, defer to the dalvik vm options.
3355                 if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3356                     debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3357                 }
3358             }
3359             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3360             if ("true".equals(genDebugInfoProperty)) {
3361                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3362             }
3363             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3364                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3365             }
3366             if ("1".equals(SystemProperties.get("debug.assert"))) {
3367                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3368             }
3369
3370             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3371             if (requiredAbi == null) {
3372                 requiredAbi = Build.SUPPORTED_ABIS[0];
3373             }
3374
3375             String instructionSet = null;
3376             if (app.info.primaryCpuAbi != null) {
3377                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3378             }
3379
3380             app.gids = gids;
3381             app.requiredAbi = requiredAbi;
3382             app.instructionSet = instructionSet;
3383
3384             // Start the process.  It will either succeed and return a result containing
3385             // the PID of the new process, or else throw a RuntimeException.
3386             boolean isActivityProcess = (entryPoint == null);
3387             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3388             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3389                     app.processName);
3390             checkTime(startTime, "startProcess: asking zygote to start proc");
3391             Process.ProcessStartResult startResult = Process.start(entryPoint,
3392                     app.processName, uid, uid, gids, debugFlags, mountExternal,
3393                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3394                     app.info.dataDir, entryPointArgs);
3395             checkTime(startTime, "startProcess: returned from zygote!");
3396             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3397
3398             if (app.isolated) {
3399                 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3400             }
3401             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3402             checkTime(startTime, "startProcess: done updating battery stats");
3403
3404             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3405                     UserHandle.getUserId(uid), startResult.pid, uid,
3406                     app.processName, hostingType,
3407                     hostingNameStr != null ? hostingNameStr : "");
3408
3409             if (app.persistent) {
3410                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3411             }
3412
3413             checkTime(startTime, "startProcess: building log message");
3414             StringBuilder buf = mStringBuilder;
3415             buf.setLength(0);
3416             buf.append("Start proc ");
3417             buf.append(startResult.pid);
3418             buf.append(':');
3419             buf.append(app.processName);
3420             buf.append('/');
3421             UserHandle.formatUid(buf, uid);
3422             if (!isActivityProcess) {
3423                 buf.append(" [");
3424                 buf.append(entryPoint);
3425                 buf.append("]");
3426             }
3427             buf.append(" for ");
3428             buf.append(hostingType);
3429             if (hostingNameStr != null) {
3430                 buf.append(" ");
3431                 buf.append(hostingNameStr);
3432             }
3433             Slog.i(TAG, buf.toString());
3434             app.setPid(startResult.pid);
3435             app.usingWrapper = startResult.usingWrapper;
3436             app.removed = false;
3437             app.killed = false;
3438             app.killedByAm = false;
3439             checkTime(startTime, "startProcess: starting to update pids map");
3440             ProcessRecord oldApp;
3441             synchronized (mPidsSelfLocked) {
3442                 oldApp = mPidsSelfLocked.get(startResult.pid);
3443             }
3444             // If there is already an app occupying that pid that hasn't been cleaned up
3445             if (oldApp != null && !app.isolated) {
3446                 // Clean up anything relating to this pid first
3447                 Slog.w(TAG, "Reusing pid " + startResult.pid
3448                         + " while app is still mapped to it");
3449                 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3450                         true /*replacingPid*/);
3451             }
3452             synchronized (mPidsSelfLocked) {
3453                 this.mPidsSelfLocked.put(startResult.pid, app);
3454                 if (isActivityProcess) {
3455                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3456                     msg.obj = app;
3457                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3458                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3459                 }
3460             }
3461             checkTime(startTime, "startProcess: done updating pids map");
3462         } catch (RuntimeException e) {
3463             // XXX do better error recovery.
3464             app.setPid(0);
3465             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3466             if (app.isolated) {
3467                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3468             }
3469             Slog.e(TAG, "Failure starting process " + app.processName, e);
3470         }
3471     }
3472
3473     void updateUsageStats(ActivityRecord component, boolean resumed) {
3474         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3475                 "updateUsageStats: comp=" + component + "res=" + resumed);
3476         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3477         if (resumed) {
3478             if (mUsageStatsService != null) {
3479                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3480                         UsageEvents.Event.MOVE_TO_FOREGROUND);
3481             }
3482             synchronized (stats) {
3483                 stats.noteActivityResumedLocked(component.app.uid);
3484             }
3485         } else {
3486             if (mUsageStatsService != null) {
3487                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3488                         UsageEvents.Event.MOVE_TO_BACKGROUND);
3489             }
3490             synchronized (stats) {
3491                 stats.noteActivityPausedLocked(component.app.uid);
3492             }
3493         }
3494     }
3495
3496     Intent getHomeIntent() {
3497         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3498         intent.setComponent(mTopComponent);
3499         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3500             intent.addCategory(Intent.CATEGORY_HOME);
3501         }
3502         return intent;
3503     }
3504
3505     boolean startHomeActivityLocked(int userId, String reason) {
3506         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3507                 && mTopAction == null) {
3508             // We are running in factory test mode, but unable to find
3509             // the factory test app, so just sit around displaying the
3510             // error message and don't try to start anything.
3511             return false;
3512         }
3513         Intent intent = getHomeIntent();
3514         ActivityInfo aInfo =
3515             resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3516         if (aInfo != null) {
3517             intent.setComponent(new ComponentName(
3518                     aInfo.applicationInfo.packageName, aInfo.name));
3519             // Don't do this if the home app is currently being
3520             // instrumented.
3521             aInfo = new ActivityInfo(aInfo);
3522             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3523             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3524                     aInfo.applicationInfo.uid, true);
3525             if (app == null || app.instrumentationClass == null) {
3526                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3527                 mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3528             }
3529         }
3530
3531         return true;
3532     }
3533
3534     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3535         ActivityInfo ai = null;
3536         ComponentName comp = intent.getComponent();
3537         try {
3538             if (comp != null) {
3539                 // Factory test.
3540                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3541             } else {
3542                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3543                         intent,
3544                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3545                         flags, userId);
3546
3547                 if (info != null) {
3548                     ai = info.activityInfo;
3549                 }
3550             }
3551         } catch (RemoteException e) {
3552             // ignore
3553         }
3554
3555         return ai;
3556     }
3557
3558     /**
3559      * Starts the "new version setup screen" if appropriate.
3560      */
3561     void startSetupActivityLocked() {
3562         // Only do this once per boot.
3563         if (mCheckedForSetup) {
3564             return;
3565         }
3566
3567         // We will show this screen if the current one is a different
3568         // version than the last one shown, and we are not running in
3569         // low-level factory test mode.
3570         final ContentResolver resolver = mContext.getContentResolver();
3571         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3572                 Settings.Global.getInt(resolver,
3573                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3574             mCheckedForSetup = true;
3575
3576             // See if we should be showing the platform update setup UI.
3577             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3578             List<ResolveInfo> ris = mContext.getPackageManager()
3579                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3580
3581             // We don't allow third party apps to replace this.
3582             ResolveInfo ri = null;
3583             for (int i=0; ris != null && i<ris.size(); i++) {
3584                 if ((ris.get(i).activityInfo.applicationInfo.flags
3585                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
3586                     ri = ris.get(i);
3587                     break;
3588                 }
3589             }
3590
3591             if (ri != null) {
3592                 String vers = ri.activityInfo.metaData != null
3593                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3594                         : null;
3595                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3596                     vers = ri.activityInfo.applicationInfo.metaData.getString(
3597                             Intent.METADATA_SETUP_VERSION);
3598                 }
3599                 String lastVers = Settings.Secure.getString(
3600                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
3601                 if (vers != null && !vers.equals(lastVers)) {
3602                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3603                     intent.setComponent(new ComponentName(
3604                             ri.activityInfo.packageName, ri.activityInfo.name));
3605                     mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3606                             null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
3607                             null, null, null);
3608                 }
3609             }
3610         }
3611     }
3612
3613     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3614         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3615     }
3616
3617     void enforceNotIsolatedCaller(String caller) {
3618         if (UserHandle.isIsolated(Binder.getCallingUid())) {
3619             throw new SecurityException("Isolated process not allowed to call " + caller);
3620         }
3621     }
3622
3623     void enforceShellRestriction(String restriction, int userHandle) {
3624         if (Binder.getCallingUid() == Process.SHELL_UID) {
3625             if (userHandle < 0
3626                     || mUserManager.hasUserRestriction(restriction, userHandle)) {
3627                 throw new SecurityException("Shell does not have permission to access user "
3628                         + userHandle);
3629             }
3630         }
3631     }
3632
3633     @Override
3634     public int getFrontActivityScreenCompatMode() {
3635         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3636         synchronized (this) {
3637             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3638         }
3639     }
3640
3641     @Override
3642     public void setFrontActivityScreenCompatMode(int mode) {
3643         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3644                 "setFrontActivityScreenCompatMode");
3645         synchronized (this) {
3646             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3647         }
3648     }
3649
3650     @Override
3651     public int getPackageScreenCompatMode(String packageName) {
3652         enforceNotIsolatedCaller("getPackageScreenCompatMode");
3653         synchronized (this) {
3654             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3655         }
3656     }
3657
3658     @Override
3659     public void setPackageScreenCompatMode(String packageName, int mode) {
3660         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3661                 "setPackageScreenCompatMode");
3662         synchronized (this) {
3663             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3664         }
3665     }
3666
3667     @Override
3668     public boolean getPackageAskScreenCompat(String packageName) {
3669         enforceNotIsolatedCaller("getPackageAskScreenCompat");
3670         synchronized (this) {
3671             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3672         }
3673     }
3674
3675     @Override
3676     public void setPackageAskScreenCompat(String packageName, boolean ask) {
3677         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3678                 "setPackageAskScreenCompat");
3679         synchronized (this) {
3680             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3681         }
3682     }
3683
3684     private boolean hasUsageStatsPermission(String callingPackage) {
3685         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3686                 Binder.getCallingUid(), callingPackage);
3687         if (mode == AppOpsManager.MODE_DEFAULT) {
3688             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3689                     == PackageManager.PERMISSION_GRANTED;
3690         }
3691         return mode == AppOpsManager.MODE_ALLOWED;
3692     }
3693
3694     @Override
3695     public int getPackageProcessState(String packageName, String callingPackage) {
3696         if (!hasUsageStatsPermission(callingPackage)) {
3697             enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3698                     "getPackageProcessState");
3699         }
3700
3701         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3702         synchronized (this) {
3703             for (int i=mLruProcesses.size()-1; i>=0; i--) {
3704                 final ProcessRecord proc = mLruProcesses.get(i);
3705                 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3706                         || procState > proc.setProcState) {
3707                     boolean found = false;
3708                     for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3709                         if (proc.pkgList.keyAt(j).equals(packageName)) {
3710                             procState = proc.setProcState;
3711                             found = true;
3712                         }
3713                     }
3714                     if (proc.pkgDeps != null && !found) {
3715                         for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3716                             if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3717                                 procState = proc.setProcState;
3718                                 break;
3719                             }
3720                         }
3721                     }
3722                 }
3723             }
3724         }
3725         return procState;
3726     }
3727
3728     @Override
3729     public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3730         synchronized (this) {
3731             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3732             if (app == null) {
3733                 return false;
3734             }
3735             if (app.trimMemoryLevel < level && app.thread != null &&
3736                     (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3737                             app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3738                 try {
3739                     app.thread.scheduleTrimMemory(level);
3740                     app.trimMemoryLevel = level;
3741                     return true;
3742                 } catch (RemoteException e) {
3743                     // Fallthrough to failure case.
3744                 }
3745             }
3746         }
3747         return false;
3748     }
3749
3750     private void dispatchProcessesChanged() {
3751         int N;
3752         synchronized (this) {
3753             N = mPendingProcessChanges.size();
3754             if (mActiveProcessChanges.length < N) {
3755                 mActiveProcessChanges = new ProcessChangeItem[N];
3756             }
3757             mPendingProcessChanges.toArray(mActiveProcessChanges);
3758             mPendingProcessChanges.clear();
3759             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3760                     "*** Delivering " + N + " process changes");
3761         }
3762
3763         int i = mProcessObservers.beginBroadcast();
3764         while (i > 0) {
3765             i--;
3766             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3767             if (observer != null) {
3768                 try {
3769                     for (int j=0; j<N; j++) {
3770                         ProcessChangeItem item = mActiveProcessChanges[j];
3771                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3772                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3773                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3774                                     + item.uid + ": " + item.foregroundActivities);
3775                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
3776                                     item.foregroundActivities);
3777                         }
3778                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3779                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3780                                     "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3781                                     + ": " + item.processState);
3782                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3783                         }
3784                     }
3785                 } catch (RemoteException e) {
3786                 }
3787             }
3788         }
3789         mProcessObservers.finishBroadcast();
3790
3791         synchronized (this) {
3792             for (int j=0; j<N; j++) {
3793                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
3794             }
3795         }
3796     }
3797
3798     private void dispatchProcessDied(int pid, int uid) {
3799         int i = mProcessObservers.beginBroadcast();
3800         while (i > 0) {
3801             i--;
3802             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3803             if (observer != null) {
3804                 try {
3805                     observer.onProcessDied(pid, uid);
3806                 } catch (RemoteException e) {
3807                 }
3808             }
3809         }
3810         mProcessObservers.finishBroadcast();
3811     }
3812
3813     private void dispatchUidsChanged() {
3814         int N;
3815         synchronized (this) {
3816             N = mPendingUidChanges.size();
3817             if (mActiveUidChanges.length < N) {
3818                 mActiveUidChanges = new UidRecord.ChangeItem[N];
3819             }
3820             for (int i=0; i<N; i++) {
3821                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3822                 mActiveUidChanges[i] = change;
3823                 change.uidRecord.pendingChange = null;
3824                 change.uidRecord = null;
3825             }
3826             mPendingUidChanges.clear();
3827             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3828                     "*** Delivering " + N + " uid changes");
3829         }
3830
3831         if (mLocalPowerManager != null) {
3832             for (int j=0; j<N; j++) {
3833                 UidRecord.ChangeItem item = mActiveUidChanges[j];
3834                 if (item.gone) {
3835                     mLocalPowerManager.uidGone(item.uid);
3836                 } else {
3837                     mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3838                 }
3839             }
3840         }
3841
3842         int i = mUidObservers.beginBroadcast();
3843         while (i > 0) {
3844             i--;
3845             final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3846             if (observer != null) {
3847                 try {
3848                     for (int j=0; j<N; j++) {
3849                         UidRecord.ChangeItem item = mActiveUidChanges[j];
3850                         if (item.gone) {
3851                             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3852                                     "UID gone uid=" + item.uid);
3853                             observer.onUidGone(item.uid);
3854                         } else {
3855                             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3856                                     "UID CHANGED uid=" + item.uid
3857                                     + ": " + item.processState);
3858                             observer.onUidStateChanged(item.uid, item.processState);
3859                         }
3860                     }
3861                 } catch (RemoteException e) {
3862                 }
3863             }
3864         }
3865         mUidObservers.finishBroadcast();
3866
3867         synchronized (this) {
3868             for (int j=0; j<N; j++) {
3869                 mAvailUidChanges.add(mActiveUidChanges[j]);
3870             }
3871         }
3872     }
3873
3874     @Override
3875     public final int startActivity(IApplicationThread caller, String callingPackage,
3876             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3877             int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3878         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3879             resultWho, requestCode, startFlags, profilerInfo, options,
3880             UserHandle.getCallingUserId());
3881     }
3882
3883     @Override
3884     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3885             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3886             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3887         enforceNotIsolatedCaller("startActivity");
3888         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3889                 false, ALLOW_FULL_ONLY, "startActivity", null);
3890         // TODO: Switch to user app stacks here.
3891         return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3892                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3893                 profilerInfo, null, null, options, false, userId, null, null);
3894     }
3895
3896     @Override
3897     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3898             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3899             int startFlags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
3900             int userId) {
3901
3902         // This is very dangerous -- it allows you to perform a start activity (including
3903         // permission grants) as any app that may launch one of your own activities.  So
3904         // we will only allow this to be done from activities that are part of the core framework,
3905         // and then only when they are running as the system.
3906         final ActivityRecord sourceRecord;
3907         final int targetUid;
3908         final String targetPackage;
3909         synchronized (this) {
3910             if (resultTo == null) {
3911                 throw new SecurityException("Must be called from an activity");
3912             }
3913             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3914             if (sourceRecord == null) {
3915                 throw new SecurityException("Called with bad activity token: " + resultTo);
3916             }
3917             if (!sourceRecord.info.packageName.equals("android")) {
3918                 throw new SecurityException(
3919                         "Must be called from an activity that is declared in the android package");
3920             }
3921             if (sourceRecord.app == null) {
3922                 throw new SecurityException("Called without a process attached to activity");
3923             }
3924             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3925                 // This is still okay, as long as this activity is running under the
3926                 // uid of the original calling activity.
3927                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3928                     throw new SecurityException(
3929                             "Calling activity in uid " + sourceRecord.app.uid
3930                                     + " must be system uid or original calling uid "
3931                                     + sourceRecord.launchedFromUid);
3932                 }
3933             }
3934             if (ignoreTargetSecurity) {
3935                 if (intent.getComponent() == null) {
3936                     throw new SecurityException(
3937                             "Component must be specified with ignoreTargetSecurity");
3938                 }
3939                 if (intent.getSelector() != null) {
3940                     throw new SecurityException(
3941                             "Selector not allowed with ignoreTargetSecurity");
3942                 }
3943             }
3944             targetUid = sourceRecord.launchedFromUid;
3945             targetPackage = sourceRecord.launchedFromPackage;
3946         }
3947
3948         if (userId == UserHandle.USER_NULL) {
3949             userId = UserHandle.getUserId(sourceRecord.app.uid);
3950         }
3951
3952         // TODO: Switch to user app stacks here.
3953         try {
3954             int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3955                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3956                     null, null, options, ignoreTargetSecurity, userId, null, null);
3957             return ret;
3958         } catch (SecurityException e) {
3959             // XXX need to figure out how to propagate to original app.
3960             // A SecurityException here is generally actually a fault of the original
3961             // calling activity (such as a fairly granting permissions), so propagate it
3962             // back to them.
3963             /*
3964             StringBuilder msg = new StringBuilder();
3965             msg.append("While launching");
3966             msg.append(intent.toString());
3967             msg.append(": ");
3968             msg.append(e.getMessage());
3969             */
3970             throw e;
3971         }
3972     }
3973
3974     @Override
3975     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3976             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3977             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3978         enforceNotIsolatedCaller("startActivityAndWait");
3979         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3980                 false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3981         WaitResult res = new WaitResult();
3982         // TODO: Switch to user app stacks here.
3983         mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3984                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3985                 options, false, userId, null, null);
3986         return res;
3987     }
3988
3989     @Override
3990     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3991             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3992             int startFlags, Configuration config, Bundle options, int userId) {
3993         enforceNotIsolatedCaller("startActivityWithConfig");
3994         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3995                 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3996         // TODO: Switch to user app stacks here.
3997         int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3998                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3999                 null, null, config, options, false, userId, null, null);
4000         return ret;
4001     }
4002
4003     @Override
4004     public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4005             Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4006             int requestCode, int flagsMask, int flagsValues, Bundle options)
4007             throws TransactionTooLargeException {
4008         enforceNotIsolatedCaller("startActivityIntentSender");
4009         // Refuse possible leaked file descriptors
4010         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4011             throw new IllegalArgumentException("File descriptors passed in Intent");
4012         }
4013
4014         IIntentSender sender = intent.getTarget();
4015         if (!(sender instanceof PendingIntentRecord)) {
4016             throw new IllegalArgumentException("Bad PendingIntent object");
4017         }
4018
4019         PendingIntentRecord pir = (PendingIntentRecord)sender;
4020
4021         synchronized (this) {
4022             // If this is coming from the currently resumed activity, it is
4023             // effectively saying that app switches are allowed at this point.
4024             final ActivityStack stack = getFocusedStack();
4025             if (stack.mResumedActivity != null &&
4026                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4027                 mAppSwitchesAllowedTime = 0;
4028             }
4029         }
4030         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4031                 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
4032         return ret;
4033     }
4034
4035     @Override
4036     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4037             Intent intent, String resolvedType, IVoiceInteractionSession session,
4038             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4039             Bundle options, int userId) {
4040         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4041                 != PackageManager.PERMISSION_GRANTED) {
4042             String msg = "Permission Denial: startVoiceActivity() from pid="
4043                     + Binder.getCallingPid()
4044                     + ", uid=" + Binder.getCallingUid()
4045                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4046             Slog.w(TAG, msg);
4047             throw new SecurityException(msg);
4048         }
4049         if (session == null || interactor == null) {
4050             throw new NullPointerException("null session or interactor");
4051         }
4052         userId = handleIncomingUser(callingPid, callingUid, userId,
4053                 false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
4054         // TODO: Switch to user app stacks here.
4055         return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
4056                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4057                 null, options, false, userId, null, null);
4058     }
4059
4060     @Override
4061     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4062         synchronized (this) {
4063             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4064                 if (keepAwake) {
4065                     mVoiceWakeLock.acquire();
4066                 } else {
4067                     mVoiceWakeLock.release();
4068                 }
4069             }
4070         }
4071     }
4072
4073     @Override
4074     public boolean startNextMatchingActivity(IBinder callingActivity,
4075             Intent intent, Bundle options) {
4076         // Refuse possible leaked file descriptors
4077         if (intent != null && intent.hasFileDescriptors() == true) {
4078             throw new IllegalArgumentException("File descriptors passed in Intent");
4079         }
4080
4081         synchronized (this) {
4082             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4083             if (r == null) {
4084                 ActivityOptions.abort(options);
4085                 return false;
4086             }
4087             if (r.app == null || r.app.thread == null) {
4088                 // The caller is not running...  d'oh!
4089                 ActivityOptions.abort(options);
4090                 return false;
4091             }
4092             intent = new Intent(intent);
4093             // The caller is not allowed to change the data.
4094             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4095             // And we are resetting to find the next component...
4096             intent.setComponent(null);
4097
4098             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4099
4100             ActivityInfo aInfo = null;
4101             try {
4102                 List<ResolveInfo> resolves =
4103                     AppGlobals.getPackageManager().queryIntentActivities(
4104                             intent, r.resolvedType,
4105                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4106                             UserHandle.getCallingUserId());
4107
4108                 // Look for the original activity in the list...
4109                 final int N = resolves != null ? resolves.size() : 0;
4110                 for (int i=0; i<N; i++) {
4111                     ResolveInfo rInfo = resolves.get(i);
4112                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4113                             && rInfo.activityInfo.name.equals(r.info.name)) {
4114                         // We found the current one...  the next matching is
4115                         // after it.
4116                         i++;
4117                         if (i<N) {
4118                             aInfo = resolves.get(i).activityInfo;
4119                         }
4120                         if (debug) {
4121                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4122                                     + "/" + r.info.name);
4123                             Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
4124                                     + "/" + aInfo.name);
4125                         }
4126                         break;
4127                     }
4128                 }
4129             } catch (RemoteException e) {
4130             }
4131
4132             if (aInfo == null) {
4133                 // Nobody who is next!
4134                 ActivityOptions.abort(options);
4135                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4136                 return false;
4137             }
4138
4139             intent.setComponent(new ComponentName(
4140                     aInfo.applicationInfo.packageName, aInfo.name));
4141             intent.setFlags(intent.getFlags()&~(
4142                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4143                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4144                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4145                     Intent.FLAG_ACTIVITY_NEW_TASK));
4146
4147             // Okay now we need to start the new activity, replacing the
4148             // currently running activity.  This is a little tricky because
4149             // we want to start the new one as if the current one is finished,
4150             // but not finish the current one first so that there is no flicker.
4151             // And thus...
4152             final boolean wasFinishing = r.finishing;
4153             r.finishing = true;
4154
4155             // Propagate reply information over to the new activity.
4156             final ActivityRecord resultTo = r.resultTo;
4157             final String resultWho = r.resultWho;
4158             final int requestCode = r.requestCode;
4159             r.resultTo = null;
4160             if (resultTo != null) {
4161                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4162             }
4163
4164             final long origId = Binder.clearCallingIdentity();
4165             int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4166                     r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4167                     resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4168                     -1, r.launchedFromUid, 0, options, false, false, null, null, null);
4169             Binder.restoreCallingIdentity(origId);
4170
4171             r.finishing = wasFinishing;
4172             if (res != ActivityManager.START_SUCCESS) {
4173                 return false;
4174             }
4175             return true;
4176         }
4177     }
4178
4179     @Override
4180     public final int startActivityFromRecents(int taskId, Bundle options) {
4181         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4182             String msg = "Permission Denial: startActivityFromRecents called without " +
4183                     START_TASKS_FROM_RECENTS;
4184             Slog.w(TAG, msg);
4185             throw new SecurityException(msg);
4186         }
4187         return startActivityFromRecentsInner(taskId, options);
4188     }
4189
4190     final int startActivityFromRecentsInner(int taskId, Bundle options) {
4191         final TaskRecord task;
4192         final int callingUid;
4193         final String callingPackage;
4194         final Intent intent;
4195         final int userId;
4196         synchronized (this) {
4197             task = mStackSupervisor.anyTaskForIdLocked(taskId);
4198             if (task == null) {
4199                 throw new IllegalArgumentException("Task " + taskId + " not found.");
4200             }
4201             if (task.getRootActivity() != null) {
4202                 moveTaskToFrontLocked(task.taskId, 0, null);
4203                 return ActivityManager.START_TASK_TO_FRONT;
4204             }
4205             callingUid = task.mCallingUid;
4206             callingPackage = task.mCallingPackage;
4207             intent = task.intent;
4208             intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4209             userId = task.userId;
4210         }
4211         return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4212                 options, userId, null, task);
4213     }
4214
4215     final int startActivityInPackage(int uid, String callingPackage,
4216             Intent intent, String resolvedType, IBinder resultTo,
4217             String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4218             IActivityContainer container, TaskRecord inTask) {
4219
4220         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4221                 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4222
4223         // TODO: Switch to user app stacks here.
4224         int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4225                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4226                 null, null, null, options, false, userId, container, inTask);
4227         return ret;
4228     }
4229
4230     @Override
4231     public final int startActivities(IApplicationThread caller, String callingPackage,
4232             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4233             int userId) {
4234         enforceNotIsolatedCaller("startActivities");
4235         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4236                 false, ALLOW_FULL_ONLY, "startActivity", null);
4237         // TODO: Switch to user app stacks here.
4238         int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4239                 resolvedTypes, resultTo, options, userId);
4240         return ret;
4241     }
4242
4243     final int startActivitiesInPackage(int uid, String callingPackage,
4244             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4245             Bundle options, int userId) {
4246
4247         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4248                 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4249         // TODO: Switch to user app stacks here.
4250         int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4251                 resultTo, options, userId);
4252         return ret;
4253     }
4254
4255     @Override
4256     public void reportActivityFullyDrawn(IBinder token) {
4257         synchronized (this) {
4258             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4259             if (r == null) {
4260                 return;
4261             }
4262             r.reportFullyDrawnLocked();
4263         }
4264     }
4265
4266     @Override
4267     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4268         synchronized (this) {
4269             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4270             if (r == null) {
4271                 return;
4272             }
4273             if (r.task != null && r.task.mResizeable) {
4274                 // Fixed screen orientation isn't supported with resizeable activities.
4275                 return;
4276             }
4277             final long origId = Binder.clearCallingIdentity();
4278             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4279             Configuration config = mWindowManager.updateOrientationFromAppTokens(
4280                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4281             if (config != null) {
4282                 r.frozenBeforeDestroy = true;
4283                 if (!updateConfigurationLocked(config, r, false, false)) {
4284                     mStackSupervisor.resumeTopActivitiesLocked();
4285                 }
4286             }
4287             Binder.restoreCallingIdentity(origId);
4288         }
4289     }
4290
4291     @Override
4292     public int getRequestedOrientation(IBinder token) {
4293         synchronized (this) {
4294             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4295             if (r == null) {
4296                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4297             }
4298             return mWindowManager.getAppOrientation(r.appToken);
4299         }
4300     }
4301
4302     /**
4303      * This is the internal entry point for handling Activity.finish().
4304      *
4305      * @param token The Binder token referencing the Activity we want to finish.
4306      * @param resultCode Result code, if any, from this Activity.
4307      * @param resultData Result data (Intent), if any, from this Activity.
4308      * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4309      *            the root Activity in the task.
4310      *
4311      * @return Returns true if the activity successfully finished, or false if it is still running.
4312      */
4313     @Override
4314     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4315             boolean finishTask) {
4316         // Refuse possible leaked file descriptors
4317         if (resultData != null && resultData.hasFileDescriptors() == true) {
4318             throw new IllegalArgumentException("File descriptors passed in Intent");
4319         }
4320
4321         synchronized(this) {
4322             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4323             if (r == null) {
4324                 return true;
4325             }
4326             // Keep track of the root activity of the task before we finish it
4327             TaskRecord tr = r.task;
4328             ActivityRecord rootR = tr.getRootActivity();
4329             if (rootR == null) {
4330                 Slog.w(TAG, "Finishing task with all activities already finished");
4331             }
4332             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4333             // finish.
4334             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4335                     mStackSupervisor.isLastLockedTask(tr)) {
4336                 Slog.i(TAG, "Not finishing task in lock task mode");
4337                 mStackSupervisor.showLockTaskToast();
4338                 return false;
4339             }
4340             if (mController != null) {
4341                 // Find the first activity that is not finishing.
4342                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4343                 if (next != null) {
4344                     // ask watcher if this is allowed
4345                     boolean resumeOK = true;
4346                     try {
4347                         resumeOK = mController.activityResuming(next.packageName);
4348                     } catch (RemoteException e) {
4349                         mController = null;
4350                         Watchdog.getInstance().setActivityController(null);
4351                     }
4352
4353                     if (!resumeOK) {
4354                         Slog.i(TAG, "Not finishing activity because controller resumed");
4355                         return false;
4356                     }
4357                 }
4358             }
4359             final long origId = Binder.clearCallingIdentity();
4360             try {
4361                 boolean res;
4362                 if (finishTask && r == rootR) {
4363                     // If requested, remove the task that is associated to this activity only if it
4364                     // was the root activity in the task. The result code and data is ignored
4365                     // because we don't support returning them across task boundaries.
4366                     res = removeTaskByIdLocked(tr.taskId, false);
4367                     if (!res) {
4368                         Slog.i(TAG, "Removing task failed to finish activity");
4369                     }
4370                 } else {
4371                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
4372                             resultData, "app-request", true);
4373                     if (!res) {
4374                         Slog.i(TAG, "Failed to finish by app-request");
4375                     }
4376                 }
4377                 return res;
4378             } finally {
4379                 Binder.restoreCallingIdentity(origId);
4380             }
4381         }
4382     }
4383
4384     @Override
4385     public final void finishHeavyWeightApp() {
4386         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4387                 != PackageManager.PERMISSION_GRANTED) {
4388             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4389                     + Binder.getCallingPid()
4390                     + ", uid=" + Binder.getCallingUid()
4391                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4392             Slog.w(TAG, msg);
4393             throw new SecurityException(msg);
4394         }
4395
4396         synchronized(this) {
4397             if (mHeavyWeightProcess == null) {
4398                 return;
4399             }
4400
4401             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4402             for (int i = 0; i < activities.size(); i++) {
4403                 ActivityRecord r = activities.get(i);
4404                 if (!r.finishing && r.isInStackLocked()) {
4405                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4406                             null, "finish-heavy", true);
4407                 }
4408             }
4409
4410             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4411                     mHeavyWeightProcess.userId, 0));
4412             mHeavyWeightProcess = null;
4413         }
4414     }
4415
4416     @Override
4417     public void crashApplication(int uid, int initialPid, String packageName,
4418             String message) {
4419         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4420                 != PackageManager.PERMISSION_GRANTED) {
4421             String msg = "Permission Denial: crashApplication() from pid="
4422                     + Binder.getCallingPid()
4423                     + ", uid=" + Binder.getCallingUid()
4424                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4425             Slog.w(TAG, msg);
4426             throw new SecurityException(msg);
4427         }
4428
4429         synchronized(this) {
4430             ProcessRecord proc = null;
4431
4432             // Figure out which process to kill.  We don't trust that initialPid
4433             // still has any relation to current pids, so must scan through the
4434             // list.
4435             synchronized (mPidsSelfLocked) {
4436                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
4437                     ProcessRecord p = mPidsSelfLocked.valueAt(i);
4438                     if (p.uid != uid) {
4439                         continue;
4440                     }
4441                     if (p.pid == initialPid) {
4442                         proc = p;
4443                         break;
4444                     }
4445                     if (p.pkgList.containsKey(packageName)) {
4446                         proc = p;
4447                     }
4448                 }
4449             }
4450
4451             if (proc == null) {
4452                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4453                         + " initialPid=" + initialPid
4454                         + " packageName=" + packageName);
4455                 return;
4456             }
4457
4458             if (proc.thread != null) {
4459                 if (proc.pid == Process.myPid()) {
4460                     Log.w(TAG, "crashApplication: trying to crash self!");
4461                     return;
4462                 }
4463                 long ident = Binder.clearCallingIdentity();
4464                 try {
4465                     proc.thread.scheduleCrash(message);
4466                 } catch (RemoteException e) {
4467                 }
4468                 Binder.restoreCallingIdentity(ident);
4469             }
4470         }
4471     }
4472
4473     @Override
4474     public final void finishSubActivity(IBinder token, String resultWho,
4475             int requestCode) {
4476         synchronized(this) {
4477             final long origId = Binder.clearCallingIdentity();
4478             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4479             if (r != null) {
4480                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4481             }
4482             Binder.restoreCallingIdentity(origId);
4483         }
4484     }
4485
4486     @Override
4487     public boolean finishActivityAffinity(IBinder token) {
4488         synchronized(this) {
4489             final long origId = Binder.clearCallingIdentity();
4490             try {
4491                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4492                 if (r == null) {
4493                     return false;
4494                 }
4495
4496                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4497                 // can finish.
4498                 final TaskRecord task = r.task;
4499                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4500                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4501                     mStackSupervisor.showLockTaskToast();
4502                     return false;
4503                 }
4504                 return task.stack.finishActivityAffinityLocked(r);
4505             } finally {
4506                 Binder.restoreCallingIdentity(origId);
4507             }
4508         }
4509     }
4510
4511     @Override
4512     public void finishVoiceTask(IVoiceInteractionSession session) {
4513         synchronized(this) {
4514             final long origId = Binder.clearCallingIdentity();
4515             try {
4516                 mStackSupervisor.finishVoiceTask(session);
4517             } finally {
4518                 Binder.restoreCallingIdentity(origId);
4519             }
4520         }
4521
4522     }
4523
4524     @Override
4525     public boolean releaseActivityInstance(IBinder token) {
4526         synchronized(this) {
4527             final long origId = Binder.clearCallingIdentity();
4528             try {
4529                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4530                 if (r == null) {
4531                     return false;
4532                 }
4533                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4534             } finally {
4535                 Binder.restoreCallingIdentity(origId);
4536             }
4537         }
4538     }
4539
4540     @Override
4541     public void releaseSomeActivities(IApplicationThread appInt) {
4542         synchronized(this) {
4543             final long origId = Binder.clearCallingIdentity();
4544             try {
4545                 ProcessRecord app = getRecordForAppLocked(appInt);
4546                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4547             } finally {
4548                 Binder.restoreCallingIdentity(origId);
4549             }
4550         }
4551     }
4552
4553     @Override
4554     public boolean willActivityBeVisible(IBinder token) {
4555         synchronized(this) {
4556             ActivityStack stack = ActivityRecord.getStackLocked(token);
4557             if (stack != null) {
4558                 return stack.willActivityBeVisibleLocked(token);
4559             }
4560             return false;
4561         }
4562     }
4563
4564     @Override
4565     public void overridePendingTransition(IBinder token, String packageName,
4566             int enterAnim, int exitAnim) {
4567         synchronized(this) {
4568             ActivityRecord self = ActivityRecord.isInStackLocked(token);
4569             if (self == null) {
4570                 return;
4571             }
4572
4573             final long origId = Binder.clearCallingIdentity();
4574
4575             if (self.state == ActivityState.RESUMED
4576                     || self.state == ActivityState.PAUSING) {
4577                 mWindowManager.overridePendingAppTransition(packageName,
4578                         enterAnim, exitAnim, null);
4579             }
4580
4581             Binder.restoreCallingIdentity(origId);
4582         }
4583     }
4584
4585     /**
4586      * Main function for removing an existing process from the activity manager
4587      * as a result of that process going away.  Clears out all connections
4588      * to the process.
4589      */
4590     private final void handleAppDiedLocked(ProcessRecord app,
4591             boolean restarting, boolean allowRestart) {
4592         int pid = app.pid;
4593         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
4594                 false /*replacingPid*/);
4595         if (!kept && !restarting) {
4596             removeLruProcessLocked(app);
4597             if (pid > 0) {
4598                 ProcessList.remove(pid);
4599             }
4600         }
4601
4602         if (mProfileProc == app) {
4603             clearProfilerLocked();
4604         }
4605
4606         // Remove this application's activities from active lists.
4607         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4608
4609         app.activities.clear();
4610
4611         if (app.instrumentationClass != null) {
4612             Slog.w(TAG, "Crash of app " + app.processName
4613                   + " running instrumentation " + app.instrumentationClass);
4614             Bundle info = new Bundle();
4615             info.putString("shortMsg", "Process crashed.");
4616             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4617         }
4618
4619         if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4620             // If there was nothing to resume, and we are not already
4621             // restarting this process, but there is a visible activity that
4622             // is hosted by the process...  then make sure all visible
4623             // activities are running, taking care of restarting this
4624             // process.
4625             mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4626         }
4627     }
4628
4629     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4630         IBinder threadBinder = thread.asBinder();
4631         // Find the application record.
4632         for (int i=mLruProcesses.size()-1; i>=0; i--) {
4633             ProcessRecord rec = mLruProcesses.get(i);
4634             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4635                 return i;
4636             }
4637         }
4638         return -1;
4639     }
4640
4641     final ProcessRecord getRecordForAppLocked(
4642             IApplicationThread thread) {
4643         if (thread == null) {
4644             return null;
4645         }
4646
4647         int appIndex = getLRURecordIndexForAppLocked(thread);
4648         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4649     }
4650
4651     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4652         // If there are no longer any background processes running,
4653         // and the app that died was not running instrumentation,
4654         // then tell everyone we are now low on memory.
4655         boolean haveBg = false;
4656         for (int i=mLruProcesses.size()-1; i>=0; i--) {
4657             ProcessRecord rec = mLruProcesses.get(i);
4658             if (rec.thread != null
4659                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4660                 haveBg = true;
4661                 break;
4662             }
4663         }
4664
4665         if (!haveBg) {
4666             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4667             if (doReport) {
4668                 long now = SystemClock.uptimeMillis();
4669                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
4670                     doReport = false;
4671                 } else {
4672                     mLastMemUsageReportTime = now;
4673                 }
4674             }
4675             final ArrayList<ProcessMemInfo> memInfos
4676                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4677             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4678             long now = SystemClock.uptimeMillis();
4679             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4680                 ProcessRecord rec = mLruProcesses.get(i);
4681                 if (rec == dyingProc || rec.thread == null) {
4682                     continue;
4683                 }
4684                 if (doReport) {
4685                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4686                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
4687                 }
4688                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4689                     // The low memory report is overriding any current
4690                     // state for a GC request.  Make sure to do
4691                     // heavy/important/visible/foreground processes first.
4692                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4693                         rec.lastRequestedGc = 0;
4694                     } else {
4695                         rec.lastRequestedGc = rec.lastLowMemory;
4696                     }
4697                     rec.reportLowMemory = true;
4698                     rec.lastLowMemory = now;
4699                     mProcessesToGc.remove(rec);
4700                     addProcessToGcListLocked(rec);
4701                 }
4702             }
4703             if (doReport) {
4704                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4705                 mHandler.sendMessage(msg);
4706             }
4707             scheduleAppGcsLocked();
4708         }
4709     }
4710
4711     final void appDiedLocked(ProcessRecord app) {
4712        appDiedLocked(app, app.pid, app.thread, false);
4713     }
4714
4715     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4716             boolean fromBinderDied) {
4717         // First check if this ProcessRecord is actually active for the pid.
4718         synchronized (mPidsSelfLocked) {
4719             ProcessRecord curProc = mPidsSelfLocked.get(pid);
4720             if (curProc != app) {
4721                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4722                 return;
4723             }
4724         }
4725
4726         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4727         synchronized (stats) {
4728             stats.noteProcessDiedLocked(app.info.uid, pid);
4729         }
4730
4731         if (!app.killed) {
4732             if (!fromBinderDied) {
4733                 Process.killProcessQuiet(pid);
4734             }
4735             killProcessGroup(app.uid, pid);
4736             app.killed = true;
4737         }
4738
4739         // Clean up already done if the process has been re-started.
4740         if (app.pid == pid && app.thread != null &&
4741                 app.thread.asBinder() == thread.asBinder()) {
4742             boolean doLowMem = app.instrumentationClass == null;
4743             boolean doOomAdj = doLowMem;
4744             if (!app.killedByAm) {
4745                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4746                         + ") has died");
4747                 mAllowLowerMemLevel = true;
4748             } else {
4749                 // Note that we always want to do oom adj to update our state with the
4750                 // new number of procs.
4751                 mAllowLowerMemLevel = false;
4752                 doLowMem = false;
4753             }
4754             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4755             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4756                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4757             handleAppDiedLocked(app, false, true);
4758
4759             if (doOomAdj) {
4760                 updateOomAdjLocked();
4761             }
4762             if (doLowMem) {
4763                 doLowMemReportIfNeededLocked(app);
4764             }
4765         } else if (app.pid != pid) {
4766             // A new process has already been started.
4767             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4768                     + ") has died and restarted (pid " + app.pid + ").");
4769             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4770         } else if (DEBUG_PROCESSES) {
4771             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4772                     + thread.asBinder());
4773         }
4774     }
4775
4776     /**
4777      * If a stack trace dump file is configured, dump process stack traces.
4778      * @param clearTraces causes the dump file to be erased prior to the new
4779      *    traces being written, if true; when false, the new traces will be
4780      *    appended to any existing file content.
4781      * @param firstPids of dalvik VM processes to dump stack traces for first
4782      * @param lastPids of dalvik VM processes to dump stack traces for last
4783      * @param nativeProcs optional list of native process names to dump stack crawls
4784      * @return file containing stack traces, or null if no dump file is configured
4785      */
4786     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4787             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4788         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4789         if (tracesPath == null || tracesPath.length() == 0) {
4790             return null;
4791         }
4792
4793         File tracesFile = new File(tracesPath);
4794         try {
4795             File tracesDir = tracesFile.getParentFile();
4796             if (!tracesDir.exists()) {
4797                 tracesDir.mkdirs();
4798                 if (!SELinux.restorecon(tracesDir)) {
4799                     return null;
4800                 }
4801             }
4802             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4803
4804             if (clearTraces && tracesFile.exists()) tracesFile.delete();
4805             tracesFile.createNewFile();
4806             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4807         } catch (IOException e) {
4808             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4809             return null;
4810         }
4811
4812         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4813         return tracesFile;
4814     }
4815
4816     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4817             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4818         // Use a FileObserver to detect when traces finish writing.
4819         // The order of traces is considered important to maintain for legibility.
4820         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4821             @Override
4822             public synchronized void onEvent(int event, String path) { notify(); }
4823         };
4824
4825         try {
4826             observer.startWatching();
4827
4828             // First collect all of the stacks of the most important pids.
4829             if (firstPids != null) {
4830                 try {
4831                     int num = firstPids.size();
4832                     for (int i = 0; i < num; i++) {
4833                         synchronized (observer) {
4834                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4835                             observer.wait(200);  // Wait for write-close, give up after 200msec
4836                         }
4837                     }
4838                 } catch (InterruptedException e) {
4839                     Slog.wtf(TAG, e);
4840                 }
4841             }
4842
4843             // Next collect the stacks of the native pids
4844             if (nativeProcs != null) {
4845                 int[] pids = Process.getPidsForCommands(nativeProcs);
4846                 if (pids != null) {
4847                     for (int pid : pids) {
4848                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4849                     }
4850                 }
4851             }
4852
4853             // Lastly, measure CPU usage.
4854             if (processCpuTracker != null) {
4855                 processCpuTracker.init();
4856                 System.gc();
4857                 processCpuTracker.update();
4858                 try {
4859                     synchronized (processCpuTracker) {
4860                         processCpuTracker.wait(500); // measure over 1/2 second.
4861                     }
4862                 } catch (InterruptedException e) {
4863                 }
4864                 processCpuTracker.update();
4865
4866                 // We'll take the stack crawls of just the top apps using CPU.
4867                 final int N = processCpuTracker.countWorkingStats();
4868                 int numProcs = 0;
4869                 for (int i=0; i<N && numProcs<5; i++) {
4870                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4871                     if (lastPids.indexOfKey(stats.pid) >= 0) {
4872                         numProcs++;
4873                         try {
4874                             synchronized (observer) {
4875                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4876                                 observer.wait(200);  // Wait for write-close, give up after 200msec
4877                             }
4878                         } catch (InterruptedException e) {
4879                             Slog.wtf(TAG, e);
4880                         }
4881
4882                     }
4883                 }
4884             }
4885         } finally {
4886             observer.stopWatching();
4887         }
4888     }
4889
4890     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4891         if (true || IS_USER_BUILD) {
4892             return;
4893         }
4894         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4895         if (tracesPath == null || tracesPath.length() == 0) {
4896             return;
4897         }
4898
4899         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4900         StrictMode.allowThreadDiskWrites();
4901         try {
4902             final File tracesFile = new File(tracesPath);
4903             final File tracesDir = tracesFile.getParentFile();
4904             final File tracesTmp = new File(tracesDir, "__tmp__");
4905             try {
4906                 if (!tracesDir.exists()) {
4907                     tracesDir.mkdirs();
4908                     if (!SELinux.restorecon(tracesDir.getPath())) {
4909                         return;
4910                     }
4911                 }
4912                 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4913
4914                 if (tracesFile.exists()) {
4915                     tracesTmp.delete();
4916                     tracesFile.renameTo(tracesTmp);
4917                 }
4918                 StringBuilder sb = new StringBuilder();
4919                 Time tobj = new Time();
4920                 tobj.set(System.currentTimeMillis());
4921                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4922                 sb.append(": ");
4923                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4924                 sb.append(" since ");
4925                 sb.append(msg);
4926                 FileOutputStream fos = new FileOutputStream(tracesFile);
4927                 fos.write(sb.toString().getBytes());
4928                 if (app == null) {
4929                     fos.write("\n*** No application process!".getBytes());
4930                 }
4931                 fos.close();
4932                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4933             } catch (IOException e) {
4934                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4935                 return;
4936             }
4937
4938             if (app != null) {
4939                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
4940                 firstPids.add(app.pid);
4941                 dumpStackTraces(tracesPath, firstPids, null, null, null);
4942             }
4943
4944             File lastTracesFile = null;
4945             File curTracesFile = null;
4946             for (int i=9; i>=0; i--) {
4947                 String name = String.format(Locale.US, "slow%02d.txt", i);
4948                 curTracesFile = new File(tracesDir, name);
4949                 if (curTracesFile.exists()) {
4950                     if (lastTracesFile != null) {
4951                         curTracesFile.renameTo(lastTracesFile);
4952                     } else {
4953                         curTracesFile.delete();
4954                     }
4955                 }
4956                 lastTracesFile = curTracesFile;
4957             }
4958             tracesFile.renameTo(curTracesFile);
4959             if (tracesTmp.exists()) {
4960                 tracesTmp.renameTo(tracesFile);
4961             }
4962         } finally {
4963             StrictMode.setThreadPolicy(oldPolicy);
4964         }
4965     }
4966
4967     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4968             ActivityRecord parent, boolean aboveSystem, final String annotation) {
4969         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4970         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4971
4972         if (mController != null) {
4973             try {
4974                 // 0 == continue, -1 = kill process immediately
4975                 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4976                 if (res < 0 && app.pid != MY_PID) {
4977                     app.kill("anr", true);
4978                 }
4979             } catch (RemoteException e) {
4980                 mController = null;
4981                 Watchdog.getInstance().setActivityController(null);
4982             }
4983         }
4984
4985         long anrTime = SystemClock.uptimeMillis();
4986         if (MONITOR_CPU_USAGE) {
4987             updateCpuStatsNow();
4988         }
4989
4990         synchronized (this) {
4991             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4992             if (mShuttingDown) {
4993                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4994                 return;
4995             } else if (app.notResponding) {
4996                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4997                 return;
4998             } else if (app.crashing) {
4999                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5000                 return;
5001             }
5002
5003             // In case we come through here for the same app before completing
5004             // this one, mark as anring now so we will bail out.
5005             app.notResponding = true;
5006
5007             // Log the ANR to the event log.
5008             EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5009                     app.processName, app.info.flags, annotation);
5010
5011             // Dump thread traces as quickly as we can, starting with "interesting" processes.
5012             firstPids.add(app.pid);
5013
5014             int parentPid = app.pid;
5015             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5016             if (parentPid != app.pid) firstPids.add(parentPid);
5017
5018             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5019
5020             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5021                 ProcessRecord r = mLruProcesses.get(i);
5022                 if (r != null && r.thread != null) {
5023                     int pid = r.pid;
5024                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5025                         if (r.persistent) {
5026                             firstPids.add(pid);
5027                         } else {
5028                             lastPids.put(pid, Boolean.TRUE);
5029                         }
5030                     }
5031                 }
5032             }
5033         }
5034
5035         // Log the ANR to the main log.
5036         StringBuilder info = new StringBuilder();
5037         info.setLength(0);
5038         info.append("ANR in ").append(app.processName);
5039         if (activity != null && activity.shortComponentName != null) {
5040             info.append(" (").append(activity.shortComponentName).append(")");
5041         }
5042         info.append("\n");
5043         info.append("PID: ").append(app.pid).append("\n");
5044         if (annotation != null) {
5045             info.append("Reason: ").append(annotation).append("\n");
5046         }
5047         if (parent != null && parent != activity) {
5048             info.append("Parent: ").append(parent.shortComponentName).append("\n");
5049         }
5050
5051         final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5052
5053         File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5054                 NATIVE_STACKS_OF_INTEREST);
5055
5056         String cpuInfo = null;
5057         if (MONITOR_CPU_USAGE) {
5058             updateCpuStatsNow();
5059             synchronized (mProcessCpuTracker) {
5060                 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5061             }
5062             info.append(processCpuTracker.printCurrentLoad());
5063             info.append(cpuInfo);
5064         }
5065
5066         info.append(processCpuTracker.printCurrentState(anrTime));
5067
5068         Slog.e(TAG, info.toString());
5069         if (tracesFile == null) {
5070             // There is no trace file, so dump (only) the alleged culprit's threads to the log
5071             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5072         }
5073
5074         addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5075                 cpuInfo, tracesFile, null);
5076
5077         if (mController != null) {
5078             try {
5079                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5080                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5081                 if (res != 0) {
5082                     if (res < 0 && app.pid != MY_PID) {
5083                         app.kill("anr", true);
5084                     } else {
5085                         synchronized (this) {
5086                             mServices.scheduleServiceTimeoutLocked(app);
5087                         }
5088                     }
5089                     return;
5090                 }
5091             } catch (RemoteException e) {
5092                 mController = null;
5093                 Watchdog.getInstance().setActivityController(null);
5094             }
5095         }
5096
5097         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5098         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5099                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5100
5101         synchronized (this) {
5102             mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5103
5104             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5105                 app.kill("bg anr", true);
5106                 return;
5107             }
5108
5109             // Set the app's notResponding state, and look up the errorReportReceiver
5110             makeAppNotRespondingLocked(app,
5111                     activity != null ? activity.shortComponentName : null,
5112                     annotation != null ? "ANR " + annotation : "ANR",
5113                     info.toString());
5114
5115             // Bring up the infamous App Not Responding dialog
5116             Message msg = Message.obtain();
5117             HashMap<String, Object> map = new HashMap<String, Object>();
5118             msg.what = SHOW_NOT_RESPONDING_MSG;
5119             msg.obj = map;
5120             msg.arg1 = aboveSystem ? 1 : 0;
5121             map.put("app", app);
5122             if (activity != null) {
5123                 map.put("activity", activity);
5124             }
5125
5126             mUiHandler.sendMessage(msg);
5127         }
5128     }
5129
5130     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5131         if (!mLaunchWarningShown) {
5132             mLaunchWarningShown = true;
5133             mUiHandler.post(new Runnable() {
5134                 @Override
5135                 public void run() {
5136                     synchronized (ActivityManagerService.this) {
5137                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5138                         d.show();
5139                         mUiHandler.postDelayed(new Runnable() {
5140                             @Override
5141                             public void run() {
5142                                 synchronized (ActivityManagerService.this) {
5143                                     d.dismiss();
5144                                     mLaunchWarningShown = false;
5145                                 }
5146                             }
5147                         }, 4000);
5148                     }
5149                 }
5150             });
5151         }
5152     }
5153
5154     @Override
5155     public boolean clearApplicationUserData(final String packageName,
5156             final IPackageDataObserver observer, int userId) {
5157         enforceNotIsolatedCaller("clearApplicationUserData");
5158         if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5159             throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5160         }
5161         int uid = Binder.getCallingUid();
5162         int pid = Binder.getCallingPid();
5163         userId = handleIncomingUser(pid, uid,
5164                 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5165         long callingId = Binder.clearCallingIdentity();
5166         try {
5167             IPackageManager pm = AppGlobals.getPackageManager();
5168             int pkgUid = -1;
5169             synchronized(this) {
5170                 try {
5171                     pkgUid = pm.getPackageUid(packageName, userId);
5172                 } catch (RemoteException e) {
5173                 }
5174                 if (pkgUid == -1) {
5175                     Slog.w(TAG, "Invalid packageName: " + packageName);
5176                     if (observer != null) {
5177                         try {
5178                             observer.onRemoveCompleted(packageName, false);
5179                         } catch (RemoteException e) {
5180                             Slog.i(TAG, "Observer no longer exists.");
5181                         }
5182                     }
5183                     return false;
5184                 }
5185                 if (uid == pkgUid || checkComponentPermission(
5186                         android.Manifest.permission.CLEAR_APP_USER_DATA,
5187                         pid, uid, -1, true)
5188                         == PackageManager.PERMISSION_GRANTED) {
5189                     forceStopPackageLocked(packageName, pkgUid, "clear data");
5190                 } else {
5191                     throw new SecurityException("PID " + pid + " does not have permission "
5192                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5193                                     + " of package " + packageName);
5194                 }
5195
5196                 // Remove all tasks match the cleared application package and user
5197                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5198                     final TaskRecord tr = mRecentTasks.get(i);
5199                     final String taskPackageName =
5200                             tr.getBaseIntent().getComponent().getPackageName();
5201                     if (tr.userId != userId) continue;
5202                     if (!taskPackageName.equals(packageName)) continue;
5203                     removeTaskByIdLocked(tr.taskId, false);
5204                 }
5205             }
5206
5207             try {
5208                 // Clear application user data
5209                 pm.clearApplicationUserData(packageName, observer, userId);
5210
5211                 synchronized(this) {
5212                     // Remove all permissions granted from/to this package
5213                     removeUriPermissionsForPackageLocked(packageName, userId, true);
5214                 }
5215
5216                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5217                         Uri.fromParts("package", packageName, null));
5218                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
5219                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5220                         null, null, 0, null, null, null, null, false, false, userId);
5221             } catch (RemoteException e) {
5222             }
5223         } finally {
5224             Binder.restoreCallingIdentity(callingId);
5225         }
5226         return true;
5227     }
5228
5229     @Override
5230     public void killBackgroundProcesses(final String packageName, int userId) {
5231         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5232                 != PackageManager.PERMISSION_GRANTED &&
5233                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5234                         != PackageManager.PERMISSION_GRANTED) {
5235             String msg = "Permission Denial: killBackgroundProcesses() from pid="
5236                     + Binder.getCallingPid()
5237                     + ", uid=" + Binder.getCallingUid()
5238                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5239             Slog.w(TAG, msg);
5240             throw new SecurityException(msg);
5241         }
5242
5243         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5244                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5245         long callingId = Binder.clearCallingIdentity();
5246         try {
5247             IPackageManager pm = AppGlobals.getPackageManager();
5248             synchronized(this) {
5249                 int appId = -1;
5250                 try {
5251                     appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5252                 } catch (RemoteException e) {
5253                 }
5254                 if (appId == -1) {
5255                     Slog.w(TAG, "Invalid packageName: " + packageName);
5256                     return;
5257                 }
5258                 killPackageProcessesLocked(packageName, appId, userId,
5259                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5260             }
5261         } finally {
5262             Binder.restoreCallingIdentity(callingId);
5263         }
5264     }
5265
5266     @Override
5267     public void killAllBackgroundProcesses() {
5268         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5269                 != PackageManager.PERMISSION_GRANTED) {
5270             String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5271                     + Binder.getCallingPid()
5272                     + ", uid=" + Binder.getCallingUid()
5273                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5274             Slog.w(TAG, msg);
5275             throw new SecurityException(msg);
5276         }
5277
5278         long callingId = Binder.clearCallingIdentity();
5279         try {
5280             synchronized(this) {
5281                 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5282                 final int NP = mProcessNames.getMap().size();
5283                 for (int ip=0; ip<NP; ip++) {
5284                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5285                     final int NA = apps.size();
5286                     for (int ia=0; ia<NA; ia++) {
5287                         ProcessRecord app = apps.valueAt(ia);
5288                         if (app.persistent) {
5289                             // we don't kill persistent processes
5290                             continue;
5291                         }
5292                         if (app.removed) {
5293                             procs.add(app);
5294                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5295                             app.removed = true;
5296                             procs.add(app);
5297                         }
5298                     }
5299                 }
5300
5301                 int N = procs.size();
5302                 for (int i=0; i<N; i++) {
5303                     removeProcessLocked(procs.get(i), false, true, "kill all background");
5304                 }
5305                 mAllowLowerMemLevel = true;
5306                 updateOomAdjLocked();
5307                 doLowMemReportIfNeededLocked(null);
5308             }
5309         } finally {
5310             Binder.restoreCallingIdentity(callingId);
5311         }
5312     }
5313
5314     @Override
5315     public void forceStopPackage(final String packageName, int userId) {
5316         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5317                 != PackageManager.PERMISSION_GRANTED) {
5318             String msg = "Permission Denial: forceStopPackage() from pid="
5319                     + Binder.getCallingPid()
5320                     + ", uid=" + Binder.getCallingUid()
5321                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5322             Slog.w(TAG, msg);
5323             throw new SecurityException(msg);
5324         }
5325         final int callingPid = Binder.getCallingPid();
5326         userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5327                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5328         long callingId = Binder.clearCallingIdentity();
5329         try {
5330             IPackageManager pm = AppGlobals.getPackageManager();
5331             synchronized(this) {
5332                 int[] users = userId == UserHandle.USER_ALL
5333                         ? getUsersLocked() : new int[] { userId };
5334                 for (int user : users) {
5335                     int pkgUid = -1;
5336                     try {
5337                         pkgUid = pm.getPackageUid(packageName, user);
5338                     } catch (RemoteException e) {
5339                     }
5340                     if (pkgUid == -1) {
5341                         Slog.w(TAG, "Invalid packageName: " + packageName);
5342                         continue;
5343                     }
5344                     try {
5345                         pm.setPackageStoppedState(packageName, true, user);
5346                     } catch (RemoteException e) {
5347                     } catch (IllegalArgumentException e) {
5348                         Slog.w(TAG, "Failed trying to unstop package "
5349                                 + packageName + ": " + e);
5350                     }
5351                     if (isUserRunningLocked(user, false)) {
5352                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5353                     }
5354                 }
5355             }
5356         } finally {
5357             Binder.restoreCallingIdentity(callingId);
5358         }
5359     }
5360
5361     @Override
5362     public void addPackageDependency(String packageName) {
5363         synchronized (this) {
5364             int callingPid = Binder.getCallingPid();
5365             if (callingPid == Process.myPid()) {
5366                 //  Yeah, um, no.
5367                 return;
5368             }
5369             ProcessRecord proc;
5370             synchronized (mPidsSelfLocked) {
5371                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5372             }
5373             if (proc != null) {
5374                 if (proc.pkgDeps == null) {
5375                     proc.pkgDeps = new ArraySet<String>(1);
5376                 }
5377                 proc.pkgDeps.add(packageName);
5378             }
5379         }
5380     }
5381
5382     /*
5383      * The pkg name and app id have to be specified.
5384      */
5385     @Override
5386     public void killApplicationWithAppId(String pkg, int appid, String reason) {
5387         if (pkg == null) {
5388             return;
5389         }
5390         // Make sure the uid is valid.
5391         if (appid < 0) {
5392             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5393             return;
5394         }
5395         int callerUid = Binder.getCallingUid();
5396         // Only the system server can kill an application
5397         if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5398             // Post an aysnc message to kill the application
5399             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5400             msg.arg1 = appid;
5401             msg.arg2 = 0;
5402             Bundle bundle = new Bundle();
5403             bundle.putString("pkg", pkg);
5404             bundle.putString("reason", reason);
5405             msg.obj = bundle;
5406             mHandler.sendMessage(msg);
5407         } else {
5408             throw new SecurityException(callerUid + " cannot kill pkg: " +
5409                     pkg);
5410         }
5411     }
5412
5413     @Override
5414     public void closeSystemDialogs(String reason) {
5415         enforceNotIsolatedCaller("closeSystemDialogs");
5416
5417         final int pid = Binder.getCallingPid();
5418         final int uid = Binder.getCallingUid();
5419         final long origId = Binder.clearCallingIdentity();
5420         try {
5421             synchronized (this) {
5422                 // Only allow this from foreground processes, so that background
5423                 // applications can't abuse it to prevent system UI from being shown.
5424                 if (uid >= Process.FIRST_APPLICATION_UID) {
5425                     ProcessRecord proc;
5426                     synchronized (mPidsSelfLocked) {
5427                         proc = mPidsSelfLocked.get(pid);
5428                     }
5429                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5430                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5431                                 + " from background process " + proc);
5432                         return;
5433                     }
5434                 }
5435                 closeSystemDialogsLocked(reason);
5436             }
5437         } finally {
5438             Binder.restoreCallingIdentity(origId);
5439         }
5440     }
5441
5442     void closeSystemDialogsLocked(String reason) {
5443         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5444         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5445                 | Intent.FLAG_RECEIVER_FOREGROUND);
5446         if (reason != null) {
5447             intent.putExtra("reason", reason);
5448         }
5449         mWindowManager.closeSystemDialogs(reason);
5450
5451         mStackSupervisor.closeSystemDialogsLocked();
5452
5453         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5454                 AppOpsManager.OP_NONE, null, false, false,
5455                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5456     }
5457
5458     @Override
5459     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5460         enforceNotIsolatedCaller("getProcessMemoryInfo");
5461         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5462         for (int i=pids.length-1; i>=0; i--) {
5463             ProcessRecord proc;
5464             int oomAdj;
5465             synchronized (this) {
5466                 synchronized (mPidsSelfLocked) {
5467                     proc = mPidsSelfLocked.get(pids[i]);
5468                     oomAdj = proc != null ? proc.setAdj : 0;
5469                 }
5470             }
5471             infos[i] = new Debug.MemoryInfo();
5472             Debug.getMemoryInfo(pids[i], infos[i]);
5473             if (proc != null) {
5474                 synchronized (this) {
5475                     if (proc.thread != null && proc.setAdj == oomAdj) {
5476                         // Record this for posterity if the process has been stable.
5477                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5478                                 infos[i].getTotalUss(), false, proc.pkgList);
5479                     }
5480                 }
5481             }
5482         }
5483         return infos;
5484     }
5485
5486     @Override
5487     public long[] getProcessPss(int[] pids) {
5488         enforceNotIsolatedCaller("getProcessPss");
5489         long[] pss = new long[pids.length];
5490         for (int i=pids.length-1; i>=0; i--) {
5491             ProcessRecord proc;
5492             int oomAdj;
5493             synchronized (this) {
5494                 synchronized (mPidsSelfLocked) {
5495                     proc = mPidsSelfLocked.get(pids[i]);
5496                     oomAdj = proc != null ? proc.setAdj : 0;
5497                 }
5498             }
5499             long[] tmpUss = new long[1];
5500             pss[i] = Debug.getPss(pids[i], tmpUss, null);
5501             if (proc != null) {
5502                 synchronized (this) {
5503                     if (proc.thread != null && proc.setAdj == oomAdj) {
5504                         // Record this for posterity if the process has been stable.
5505                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5506                     }
5507                 }
5508             }
5509         }
5510         return pss;
5511     }
5512
5513     @Override
5514     public void killApplicationProcess(String processName, int uid) {
5515         if (processName == null) {
5516             return;
5517         }
5518
5519         int callerUid = Binder.getCallingUid();
5520         // Only the system server can kill an application
5521         if (callerUid == Process.SYSTEM_UID) {
5522             synchronized (this) {
5523                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5524                 if (app != null && app.thread != null) {
5525                     try {
5526                         app.thread.scheduleSuicide();
5527                     } catch (RemoteException e) {
5528                         // If the other end already died, then our work here is done.
5529                     }
5530                 } else {
5531                     Slog.w(TAG, "Process/uid not found attempting kill of "
5532                             + processName + " / " + uid);
5533                 }
5534             }
5535         } else {
5536             throw new SecurityException(callerUid + " cannot kill app process: " +
5537                     processName);
5538         }
5539     }
5540
5541     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5542         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5543                 false, true, false, false, UserHandle.getUserId(uid), reason);
5544         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5545                 Uri.fromParts("package", packageName, null));
5546         if (!mProcessesReady) {
5547             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5548                     | Intent.FLAG_RECEIVER_FOREGROUND);
5549         }
5550         intent.putExtra(Intent.EXTRA_UID, uid);
5551         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5552         broadcastIntentLocked(null, null, intent,
5553                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5554                 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5555     }
5556
5557     private void forceStopUserLocked(int userId, String reason) {
5558         forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5559         Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5560         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5561                 | Intent.FLAG_RECEIVER_FOREGROUND);
5562         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5563         broadcastIntentLocked(null, null, intent,
5564                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5565                 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5566     }
5567
5568     private final boolean killPackageProcessesLocked(String packageName, int appId,
5569             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5570             boolean doit, boolean evenPersistent, String reason) {
5571         ArrayList<ProcessRecord> procs = new ArrayList<>();
5572
5573         // Remove all processes this package may have touched: all with the
5574         // same UID (except for the system or root user), and all whose name
5575         // matches the package name.
5576         final int NP = mProcessNames.getMap().size();
5577         for (int ip=0; ip<NP; ip++) {
5578             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5579             final int NA = apps.size();
5580             for (int ia=0; ia<NA; ia++) {
5581                 ProcessRecord app = apps.valueAt(ia);
5582                 if (app.persistent && !evenPersistent) {
5583                     // we don't kill persistent processes
5584                     continue;
5585                 }
5586                 if (app.removed) {
5587                     if (doit) {
5588                         procs.add(app);
5589                     }
5590                     continue;
5591                 }
5592
5593                 // Skip process if it doesn't meet our oom adj requirement.
5594                 if (app.setAdj < minOomAdj) {
5595                     continue;
5596                 }
5597
5598                 // If no package is specified, we call all processes under the
5599                 // give user id.
5600                 if (packageName == null) {
5601                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
5602                         continue;
5603                     }
5604                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5605                         continue;
5606                     }
5607                 // Package has been specified, we want to hit all processes
5608                 // that match it.  We need to qualify this by the processes
5609                 // that are running under the specified app and user ID.
5610                 } else {
5611                     final boolean isDep = app.pkgDeps != null
5612                             && app.pkgDeps.contains(packageName);
5613                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5614                         continue;
5615                     }
5616                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
5617                         continue;
5618                     }
5619                     if (!app.pkgList.containsKey(packageName) && !isDep) {
5620                         continue;
5621                     }
5622                 }
5623
5624                 // Process has passed all conditions, kill it!
5625                 if (!doit) {
5626                     return true;
5627                 }
5628                 app.removed = true;
5629                 procs.add(app);
5630             }
5631         }
5632
5633         int N = procs.size();
5634         for (int i=0; i<N; i++) {
5635             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5636         }
5637         updateOomAdjLocked();
5638         return N > 0;
5639     }
5640
5641     private void cleanupDisabledPackageComponentsLocked(
5642             String packageName, int userId, boolean killProcess, String[] changedClasses) {
5643
5644         Set<String> disabledClasses = null;
5645         boolean packageDisabled = false;
5646         IPackageManager pm = AppGlobals.getPackageManager();
5647
5648         if (changedClasses == null) {
5649             // Nothing changed...
5650             return;
5651         }
5652
5653         // Determine enable/disable state of the package and its components.
5654         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5655         for (int i = changedClasses.length - 1; i >= 0; i--) {
5656             final String changedClass = changedClasses[i];
5657
5658             if (changedClass.equals(packageName)) {
5659                 try {
5660                     // Entire package setting changed
5661                     enabled = pm.getApplicationEnabledSetting(packageName,
5662                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5663                 } catch (Exception e) {
5664                     // No such package/component; probably racing with uninstall.  In any
5665                     // event it means we have nothing further to do here.
5666                     return;
5667                 }
5668                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5669                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5670                 if (packageDisabled) {
5671                     // Entire package is disabled.
5672                     // No need to continue to check component states.
5673                     disabledClasses = null;
5674                     break;
5675                 }
5676             } else {
5677                 try {
5678                     enabled = pm.getComponentEnabledSetting(
5679                             new ComponentName(packageName, changedClass),
5680                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5681                 } catch (Exception e) {
5682                     // As above, probably racing with uninstall.
5683                     return;
5684                 }
5685                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5686                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5687                     if (disabledClasses == null) {
5688                         disabledClasses = new ArraySet<>(changedClasses.length);
5689                     }
5690                     disabledClasses.add(changedClass);
5691                 }
5692             }
5693         }
5694
5695         if (!packageDisabled && disabledClasses == null) {
5696             // Nothing to do here...
5697             return;
5698         }
5699
5700         // Clean-up disabled activities.
5701         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5702                 packageName, disabledClasses, true, false, userId) && mBooted) {
5703             mStackSupervisor.resumeTopActivitiesLocked();
5704             mStackSupervisor.scheduleIdleLocked();
5705         }
5706
5707         // Clean-up disabled tasks
5708         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5709
5710         // Clean-up disabled services.
5711         mServices.bringDownDisabledPackageServicesLocked(
5712                 packageName, disabledClasses, userId, false, killProcess, true);
5713
5714         // Clean-up disabled providers.
5715         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5716         mProviderMap.collectPackageProvidersLocked(
5717                 packageName, disabledClasses, true, false, userId, providers);
5718         for (int i = providers.size() - 1; i >= 0; i--) {
5719             removeDyingProviderLocked(null, providers.get(i), true);
5720         }
5721
5722         // Clean-up disabled broadcast receivers.
5723         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5724             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5725                     packageName, disabledClasses, userId, true);
5726         }
5727
5728     }
5729
5730     private final boolean forceStopPackageLocked(String packageName, int appId,
5731             boolean callerWillRestart, boolean purgeCache, boolean doit,
5732             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5733         int i;
5734
5735         if (userId == UserHandle.USER_ALL && packageName == null) {
5736             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5737         }
5738
5739         if (appId < 0 && packageName != null) {
5740             try {
5741                 appId = UserHandle.getAppId(
5742                         AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5743             } catch (RemoteException e) {
5744             }
5745         }
5746
5747         if (doit) {
5748             if (packageName != null) {
5749                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5750                         + " user=" + userId + ": " + reason);
5751             } else {
5752                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5753             }
5754
5755             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5756             for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5757                 SparseArray<Long> ba = pmap.valueAt(ip);
5758                 for (i = ba.size() - 1; i >= 0; i--) {
5759                     boolean remove = false;
5760                     final int entUid = ba.keyAt(i);
5761                     if (packageName != null) {
5762                         if (userId == UserHandle.USER_ALL) {
5763                             if (UserHandle.getAppId(entUid) == appId) {
5764                                 remove = true;
5765                             }
5766                         } else {
5767                             if (entUid == UserHandle.getUid(userId, appId)) {
5768                                 remove = true;
5769                             }
5770                         }
5771                     } else if (UserHandle.getUserId(entUid) == userId) {
5772                         remove = true;
5773                     }
5774                     if (remove) {
5775                         ba.removeAt(i);
5776                     }
5777                 }
5778                 if (ba.size() == 0) {
5779                     pmap.removeAt(ip);
5780                 }
5781             }
5782         }
5783
5784         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5785                 -100, callerWillRestart, true, doit, evenPersistent,
5786                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5787
5788         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5789                 packageName, null, doit, evenPersistent, userId)) {
5790             if (!doit) {
5791                 return true;
5792             }
5793             didSomething = true;
5794         }
5795
5796         if (mServices.bringDownDisabledPackageServicesLocked(
5797                 packageName, null, userId, evenPersistent, true, doit)) {
5798             if (!doit) {
5799                 return true;
5800             }
5801             didSomething = true;
5802         }
5803
5804         if (packageName == null) {
5805             // Remove all sticky broadcasts from this user.
5806             mStickyBroadcasts.remove(userId);
5807         }
5808
5809         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5810         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5811                 userId, providers)) {
5812             if (!doit) {
5813                 return true;
5814             }
5815             didSomething = true;
5816         }
5817         for (i = providers.size() - 1; i >= 0; i--) {
5818             removeDyingProviderLocked(null, providers.get(i), true);
5819         }
5820
5821         // Remove transient permissions granted from/to this package/user
5822         removeUriPermissionsForPackageLocked(packageName, userId, false);
5823
5824         if (doit) {
5825             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5826                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5827                         packageName, null, userId, doit);
5828             }
5829         }
5830
5831         if (packageName == null || uninstalling) {
5832             // Remove pending intents.  For now we only do this when force
5833             // stopping users, because we have some problems when doing this
5834             // for packages -- app widgets are not currently cleaned up for
5835             // such packages, so they can be left with bad pending intents.
5836             if (mIntentSenderRecords.size() > 0) {
5837                 Iterator<WeakReference<PendingIntentRecord>> it
5838                         = mIntentSenderRecords.values().iterator();
5839                 while (it.hasNext()) {
5840                     WeakReference<PendingIntentRecord> wpir = it.next();
5841                     if (wpir == null) {
5842                         it.remove();
5843                         continue;
5844                     }
5845                     PendingIntentRecord pir = wpir.get();
5846                     if (pir == null) {
5847                         it.remove();
5848                         continue;
5849                     }
5850                     if (packageName == null) {
5851                         // Stopping user, remove all objects for the user.
5852                         if (pir.key.userId != userId) {
5853                             // Not the same user, skip it.
5854                             continue;
5855                         }
5856                     } else {
5857                         if (UserHandle.getAppId(pir.uid) != appId) {
5858                             // Different app id, skip it.
5859                             continue;
5860                         }
5861                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5862                             // Different user, skip it.
5863                             continue;
5864                         }
5865                         if (!pir.key.packageName.equals(packageName)) {
5866                             // Different package, skip it.
5867                             continue;
5868                         }
5869                     }
5870                     if (!doit) {
5871                         return true;
5872                     }
5873                     didSomething = true;
5874                     it.remove();
5875                     pir.canceled = true;
5876                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5877                         pir.key.activity.pendingResults.remove(pir.ref);
5878                     }
5879                 }
5880             }
5881         }
5882
5883         if (doit) {
5884             if (purgeCache && packageName != null) {
5885                 AttributeCache ac = AttributeCache.instance();
5886                 if (ac != null) {
5887                     ac.removePackage(packageName);
5888                 }
5889             }
5890             if (mBooted) {
5891                 mStackSupervisor.resumeTopActivitiesLocked();
5892                 mStackSupervisor.scheduleIdleLocked();
5893             }
5894         }
5895
5896         return didSomething;
5897     }
5898
5899     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5900         ProcessRecord old = mProcessNames.remove(name, uid);
5901         if (old != null) {
5902             old.uidRecord.numProcs--;
5903             if (old.uidRecord.numProcs == 0) {
5904                 // No more processes using this uid, tell clients it is gone.
5905                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5906                         "No more processes in " + old.uidRecord);
5907                 enqueueUidChangeLocked(old.uidRecord, true);
5908                 mActiveUids.remove(uid);
5909             }
5910             old.uidRecord = null;
5911         }
5912         mIsolatedProcesses.remove(uid);
5913         return old;
5914     }
5915
5916     private final void addProcessNameLocked(ProcessRecord proc) {
5917         // We shouldn't already have a process under this name, but just in case we
5918         // need to clean up whatever may be there now.
5919         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5920         if (old == proc && proc.persistent) {
5921             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
5922             Slog.w(TAG, "Re-adding persistent process " + proc);
5923         } else if (old != null) {
5924             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5925         }
5926         UidRecord uidRec = mActiveUids.get(proc.uid);
5927         if (uidRec == null) {
5928             uidRec = new UidRecord(proc.uid);
5929             // This is the first appearance of the uid, report it now!
5930             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5931                     "Creating new process uid: " + uidRec);
5932             mActiveUids.put(proc.uid, uidRec);
5933             enqueueUidChangeLocked(uidRec, false);
5934         }
5935         proc.uidRecord = uidRec;
5936         uidRec.numProcs++;
5937         mProcessNames.put(proc.processName, proc.uid, proc);
5938         if (proc.isolated) {
5939             mIsolatedProcesses.put(proc.uid, proc);
5940         }
5941     }
5942
5943     private final boolean removeProcessLocked(ProcessRecord app,
5944             boolean callerWillRestart, boolean allowRestart, String reason) {
5945         final String name = app.processName;
5946         final int uid = app.uid;
5947         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5948             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5949
5950         removeProcessNameLocked(name, uid);
5951         if (mHeavyWeightProcess == app) {
5952             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5953                     mHeavyWeightProcess.userId, 0));
5954             mHeavyWeightProcess = null;
5955         }
5956         boolean needRestart = false;
5957         if (app.pid > 0 && app.pid != MY_PID) {
5958             int pid = app.pid;
5959             synchronized (mPidsSelfLocked) {
5960                 mPidsSelfLocked.remove(pid);
5961                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5962             }
5963             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5964             if (app.isolated) {
5965                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5966             }
5967             boolean willRestart = false;
5968             if (app.persistent && !app.isolated) {
5969                 if (!callerWillRestart) {
5970                     willRestart = true;
5971                 } else {
5972                     needRestart = true;
5973                 }
5974             }
5975             app.kill(reason, true);
5976             handleAppDiedLocked(app, willRestart, allowRestart);
5977             if (willRestart) {
5978                 removeLruProcessLocked(app);
5979                 addAppLocked(app.info, false, null /* ABI override */);
5980             }
5981         } else {
5982             mRemovedProcesses.add(app);
5983         }
5984
5985         return needRestart;
5986     }
5987
5988     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
5989         cleanupAppInLaunchingProvidersLocked(app, true);
5990         removeProcessLocked(app, false, true, "timeout publishing content providers");
5991     }
5992
5993     private final void processStartTimedOutLocked(ProcessRecord app) {
5994         final int pid = app.pid;
5995         boolean gone = false;
5996         synchronized (mPidsSelfLocked) {
5997             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5998             if (knownApp != null && knownApp.thread == null) {
5999                 mPidsSelfLocked.remove(pid);
6000                 gone = true;
6001             }
6002         }
6003
6004         if (gone) {
6005             Slog.w(TAG, "Process " + app + " failed to attach");
6006             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6007                     pid, app.uid, app.processName);
6008             removeProcessNameLocked(app.processName, app.uid);
6009             if (mHeavyWeightProcess == app) {
6010                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6011                         mHeavyWeightProcess.userId, 0));
6012                 mHeavyWeightProcess = null;
6013             }
6014             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6015             if (app.isolated) {
6016                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6017             }
6018             // Take care of any launching providers waiting for this process.
6019             cleanupAppInLaunchingProvidersLocked(app, true);
6020             // Take care of any services that are waiting for the process.
6021             mServices.processStartTimedOutLocked(app);
6022             app.kill("start timeout", true);
6023             removeLruProcessLocked(app);
6024             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6025                 Slog.w(TAG, "Unattached app died before backup, skipping");
6026                 try {
6027                     IBackupManager bm = IBackupManager.Stub.asInterface(
6028                             ServiceManager.getService(Context.BACKUP_SERVICE));
6029                     bm.agentDisconnected(app.info.packageName);
6030                 } catch (RemoteException e) {
6031                     // Can't happen; the backup manager is local
6032                 }
6033             }
6034             if (isPendingBroadcastProcessLocked(pid)) {
6035                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6036                 skipPendingBroadcastLocked(pid);
6037             }
6038         } else {
6039             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6040         }
6041     }
6042
6043     private final boolean attachApplicationLocked(IApplicationThread thread,
6044             int pid) {
6045
6046         // Find the application record that is being attached...  either via
6047         // the pid if we are running in multiple processes, or just pull the
6048         // next app record if we are emulating process with anonymous threads.
6049         ProcessRecord app;
6050         if (pid != MY_PID && pid >= 0) {
6051             synchronized (mPidsSelfLocked) {
6052                 app = mPidsSelfLocked.get(pid);
6053             }
6054         } else {
6055             app = null;
6056         }
6057
6058         if (app == null) {
6059             Slog.w(TAG, "No pending application record for pid " + pid
6060                     + " (IApplicationThread " + thread + "); dropping process");
6061             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6062             if (pid > 0 && pid != MY_PID) {
6063                 Process.killProcessQuiet(pid);
6064                 //TODO: killProcessGroup(app.info.uid, pid);
6065             } else {
6066                 try {
6067                     thread.scheduleExit();
6068                 } catch (Exception e) {
6069                     // Ignore exceptions.
6070                 }
6071             }
6072             return false;
6073         }
6074
6075         // If this application record is still attached to a previous
6076         // process, clean it up now.
6077         if (app.thread != null) {
6078             handleAppDiedLocked(app, true, true);
6079         }
6080
6081         // Tell the process all about itself.
6082
6083         if (DEBUG_ALL) Slog.v(
6084                 TAG, "Binding process pid " + pid + " to record " + app);
6085
6086         final String processName = app.processName;
6087         try {
6088             AppDeathRecipient adr = new AppDeathRecipient(
6089                     app, pid, thread);
6090             thread.asBinder().linkToDeath(adr, 0);
6091             app.deathRecipient = adr;
6092         } catch (RemoteException e) {
6093             app.resetPackageList(mProcessStats);
6094             startProcessLocked(app, "link fail", processName);
6095             return false;
6096         }
6097
6098         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6099
6100         app.makeActive(thread, mProcessStats);
6101         app.curAdj = app.setAdj = -100;
6102         app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6103         app.forcingToForeground = null;
6104         updateProcessForegroundLocked(app, false, false);
6105         app.hasShownUi = false;
6106         app.debugging = false;
6107         app.cached = false;
6108         app.killedByAm = false;
6109
6110         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6111
6112         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6113         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6114
6115         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6116             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6117             msg.obj = app;
6118             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6119         }
6120
6121         if (!normalMode) {
6122             Slog.i(TAG, "Launching preboot mode app: " + app);
6123         }
6124
6125         if (DEBUG_ALL) Slog.v(
6126             TAG, "New app record " + app
6127             + " thread=" + thread.asBinder() + " pid=" + pid);
6128         try {
6129             int testMode = IApplicationThread.DEBUG_OFF;
6130             if (mDebugApp != null && mDebugApp.equals(processName)) {
6131                 testMode = mWaitForDebugger
6132                     ? IApplicationThread.DEBUG_WAIT
6133                     : IApplicationThread.DEBUG_ON;
6134                 app.debugging = true;
6135                 if (mDebugTransient) {
6136                     mDebugApp = mOrigDebugApp;
6137                     mWaitForDebugger = mOrigWaitForDebugger;
6138                 }
6139             }
6140             String profileFile = app.instrumentationProfileFile;
6141             ParcelFileDescriptor profileFd = null;
6142             int samplingInterval = 0;
6143             boolean profileAutoStop = false;
6144             if (mProfileApp != null && mProfileApp.equals(processName)) {
6145                 mProfileProc = app;
6146                 profileFile = mProfileFile;
6147                 profileFd = mProfileFd;
6148                 samplingInterval = mSamplingInterval;
6149                 profileAutoStop = mAutoStopProfiler;
6150             }
6151             boolean enableOpenGlTrace = false;
6152             if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6153                 enableOpenGlTrace = true;
6154                 mOpenGlTraceApp = null;
6155             }
6156
6157             // If the app is being launched for restore or full backup, set it up specially
6158             boolean isRestrictedBackupMode = false;
6159             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6160                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6161                         || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6162                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6163             }
6164
6165             ensurePackageDexOpt(app.instrumentationInfo != null
6166                     ? app.instrumentationInfo.packageName
6167                     : app.info.packageName);
6168             if (app.instrumentationClass != null) {
6169                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6170             }
6171             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6172                     + processName + " with config " + mConfiguration);
6173             ApplicationInfo appInfo = app.instrumentationInfo != null
6174                     ? app.instrumentationInfo : app.info;
6175             app.compat = compatibilityInfoForPackageLocked(appInfo);
6176             if (profileFd != null) {
6177                 profileFd = profileFd.dup();
6178             }
6179             ProfilerInfo profilerInfo = profileFile == null ? null
6180                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6181             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6182                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6183                     app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6184                     isRestrictedBackupMode || !normalMode, app.persistent,
6185                     new Configuration(mConfiguration), app.compat,
6186                     getCommonServicesLocked(app.isolated),
6187                     mCoreSettingsObserver.getCoreSettingsLocked());
6188             updateLruProcessLocked(app, false, null);
6189             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6190         } catch (Exception e) {
6191             // todo: Yikes!  What should we do?  For now we will try to
6192             // start another process, but that could easily get us in
6193             // an infinite loop of restarting processes...
6194             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6195
6196             app.resetPackageList(mProcessStats);
6197             app.unlinkDeathRecipient();
6198             startProcessLocked(app, "bind fail", processName);
6199             return false;
6200         }
6201
6202         // Remove this record from the list of starting applications.
6203         mPersistentStartingProcesses.remove(app);
6204         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6205                 "Attach application locked removing on hold: " + app);
6206         mProcessesOnHold.remove(app);
6207
6208         boolean badApp = false;
6209         boolean didSomething = false;
6210
6211         // See if the top visible activity is waiting to run in this process...
6212         if (normalMode) {
6213             try {
6214                 if (mStackSupervisor.attachApplicationLocked(app)) {
6215                     didSomething = true;
6216                 }
6217             } catch (Exception e) {
6218                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6219                 badApp = true;
6220             }
6221         }
6222
6223         // Find any services that should be running in this process...
6224         if (!badApp) {
6225             try {
6226                 didSomething |= mServices.attachApplicationLocked(app, processName);
6227             } catch (Exception e) {
6228                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6229                 badApp = true;
6230             }
6231         }
6232
6233         // Check if a next-broadcast receiver is in this process...
6234         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6235             try {
6236                 didSomething |= sendPendingBroadcastsLocked(app);
6237             } catch (Exception e) {
6238                 // If the app died trying to launch the receiver we declare it 'bad'
6239                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6240                 badApp = true;
6241             }
6242         }
6243
6244         // Check whether the next backup agent is in this process...
6245         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6246             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6247                     "New app is backup target, launching agent for " + app);
6248             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6249             try {
6250                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6251                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6252                         mBackupTarget.backupMode);
6253             } catch (Exception e) {
6254                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6255                 badApp = true;
6256             }
6257         }
6258
6259         if (badApp) {
6260             app.kill("error during init", true);
6261             handleAppDiedLocked(app, false, true);
6262             return false;
6263         }
6264
6265         if (!didSomething) {
6266             updateOomAdjLocked();
6267         }
6268
6269         return true;
6270     }
6271
6272     @Override
6273     public final void attachApplication(IApplicationThread thread) {
6274         synchronized (this) {
6275             int callingPid = Binder.getCallingPid();
6276             final long origId = Binder.clearCallingIdentity();
6277             attachApplicationLocked(thread, callingPid);
6278             Binder.restoreCallingIdentity(origId);
6279         }
6280     }
6281
6282     @Override
6283     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6284         final long origId = Binder.clearCallingIdentity();
6285         synchronized (this) {
6286             ActivityStack stack = ActivityRecord.getStackLocked(token);
6287             if (stack != null) {
6288                 ActivityRecord r =
6289                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
6290                 if (stopProfiling) {
6291                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
6292                         try {
6293                             mProfileFd.close();
6294                         } catch (IOException e) {
6295                         }
6296                         clearProfilerLocked();
6297                     }
6298                 }
6299             }
6300         }
6301         Binder.restoreCallingIdentity(origId);
6302     }
6303
6304     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6305         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6306                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6307     }
6308
6309     void enableScreenAfterBoot() {
6310         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6311                 SystemClock.uptimeMillis());
6312         mWindowManager.enableScreenAfterBoot();
6313
6314         synchronized (this) {
6315             updateEventDispatchingLocked();
6316         }
6317     }
6318
6319     @Override
6320     public void showBootMessage(final CharSequence msg, final boolean always) {
6321         if (Binder.getCallingUid() != Process.myUid()) {
6322             // These days only the core system can call this, so apps can't get in
6323             // the way of what we show about running them.
6324         }
6325         mWindowManager.showBootMessage(msg, always);
6326     }
6327
6328     @Override
6329     public void keyguardWaitingForActivityDrawn() {
6330         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6331         final long token = Binder.clearCallingIdentity();
6332         try {
6333             synchronized (this) {
6334                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6335                 mWindowManager.keyguardWaitingForActivityDrawn();
6336                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6337                     mLockScreenShown = LOCK_SCREEN_LEAVING;
6338                     updateSleepIfNeededLocked();
6339                 }
6340             }
6341         } finally {
6342             Binder.restoreCallingIdentity(token);
6343         }
6344     }
6345
6346     @Override
6347     public void keyguardGoingAway(boolean disableWindowAnimations,
6348             boolean keyguardGoingToNotificationShade) {
6349         enforceNotIsolatedCaller("keyguardGoingAway");
6350         final long token = Binder.clearCallingIdentity();
6351         try {
6352             synchronized (this) {
6353                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6354                 mWindowManager.keyguardGoingAway(disableWindowAnimations,
6355                         keyguardGoingToNotificationShade);
6356                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6357                     mLockScreenShown = LOCK_SCREEN_HIDDEN;
6358                     updateSleepIfNeededLocked();
6359                 }
6360             }
6361         } finally {
6362             Binder.restoreCallingIdentity(token);
6363         }
6364     }
6365
6366     final void finishBooting() {
6367         synchronized (this) {
6368             if (!mBootAnimationComplete) {
6369                 mCallFinishBooting = true;
6370                 return;
6371             }
6372             mCallFinishBooting = false;
6373         }
6374
6375         ArraySet<String> completedIsas = new ArraySet<String>();
6376         for (String abi : Build.SUPPORTED_ABIS) {
6377             Process.establishZygoteConnectionForAbi(abi);
6378             final String instructionSet = VMRuntime.getInstructionSet(abi);
6379             if (!completedIsas.contains(instructionSet)) {
6380                 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6381                     Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6382                 }
6383                 completedIsas.add(instructionSet);
6384             }
6385         }
6386
6387         IntentFilter pkgFilter = new IntentFilter();
6388         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6389         pkgFilter.addDataScheme("package");
6390         mContext.registerReceiver(new BroadcastReceiver() {
6391             @Override
6392             public void onReceive(Context context, Intent intent) {
6393                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6394                 if (pkgs != null) {
6395                     for (String pkg : pkgs) {
6396                         synchronized (ActivityManagerService.this) {
6397                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6398                                     0, "query restart")) {
6399                                 setResultCode(Activity.RESULT_OK);
6400                                 return;
6401                             }
6402                         }
6403                     }
6404                 }
6405             }
6406         }, pkgFilter);
6407
6408         IntentFilter dumpheapFilter = new IntentFilter();
6409         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6410         mContext.registerReceiver(new BroadcastReceiver() {
6411             @Override
6412             public void onReceive(Context context, Intent intent) {
6413                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6414                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6415                 } else {
6416                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6417                 }
6418             }
6419         }, dumpheapFilter);
6420
6421         // Let system services know.
6422         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6423
6424         synchronized (this) {
6425             // Ensure that any processes we had put on hold are now started
6426             // up.
6427             final int NP = mProcessesOnHold.size();
6428             if (NP > 0) {
6429                 ArrayList<ProcessRecord> procs =
6430                     new ArrayList<ProcessRecord>(mProcessesOnHold);
6431                 for (int ip=0; ip<NP; ip++) {
6432                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6433                             + procs.get(ip));
6434                     startProcessLocked(procs.get(ip), "on-hold", null);
6435                 }
6436             }
6437
6438             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6439                 // Start looking for apps that are abusing wake locks.
6440                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6441                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6442                 // Tell anyone interested that we are done booting!
6443                 SystemProperties.set("sys.boot_completed", "1");
6444
6445                 // And trigger dev.bootcomplete if we are not showing encryption progress
6446                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6447                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6448                     SystemProperties.set("dev.bootcomplete", "1");
6449                 }
6450                 for (int i=0; i<mStartedUsers.size(); i++) {
6451                     UserState uss = mStartedUsers.valueAt(i);
6452                     if (uss.mState == UserState.STATE_BOOTING) {
6453                         uss.mState = UserState.STATE_RUNNING;
6454                         final int userId = mStartedUsers.keyAt(i);
6455                         Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6456                         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6457                         intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6458                         broadcastIntentLocked(null, null, intent, null,
6459                                 new IIntentReceiver.Stub() {
6460                                     @Override
6461                                     public void performReceive(Intent intent, int resultCode,
6462                                             String data, Bundle extras, boolean ordered,
6463                                             boolean sticky, int sendingUser) {
6464                                         synchronized (ActivityManagerService.this) {
6465                                             requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6466                                                     true, false);
6467                                         }
6468                                     }
6469                                 },
6470                                 0, null, null,
6471                                 new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
6472                                 AppOpsManager.OP_NONE, null, true, false,
6473                                 MY_PID, Process.SYSTEM_UID, userId);
6474                     }
6475                 }
6476                 scheduleStartProfilesLocked();
6477             }
6478         }
6479     }
6480
6481     @Override
6482     public void bootAnimationComplete() {
6483         final boolean callFinishBooting;
6484         synchronized (this) {
6485             callFinishBooting = mCallFinishBooting;
6486             mBootAnimationComplete = true;
6487         }
6488         if (callFinishBooting) {
6489             finishBooting();
6490         }
6491     }
6492
6493     final void ensureBootCompleted() {
6494         boolean booting;
6495         boolean enableScreen;
6496         synchronized (this) {
6497             booting = mBooting;
6498             mBooting = false;
6499             enableScreen = !mBooted;
6500             mBooted = true;
6501         }
6502
6503         if (booting) {
6504             finishBooting();
6505         }
6506
6507         if (enableScreen) {
6508             enableScreenAfterBoot();
6509         }
6510     }
6511
6512     @Override
6513     public final void activityResumed(IBinder token) {
6514         final long origId = Binder.clearCallingIdentity();
6515         synchronized(this) {
6516             ActivityStack stack = ActivityRecord.getStackLocked(token);
6517             if (stack != null) {
6518                 ActivityRecord.activityResumedLocked(token);
6519             }
6520         }
6521         Binder.restoreCallingIdentity(origId);
6522     }
6523
6524     @Override
6525     public final void activityPaused(IBinder token) {
6526         final long origId = Binder.clearCallingIdentity();
6527         synchronized(this) {
6528             ActivityStack stack = ActivityRecord.getStackLocked(token);
6529             if (stack != null) {
6530                 stack.activityPausedLocked(token, false);
6531             }
6532         }
6533         Binder.restoreCallingIdentity(origId);
6534     }
6535
6536     @Override
6537     public final void activityStopped(IBinder token, Bundle icicle,
6538             PersistableBundle persistentState, CharSequence description) {
6539         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6540
6541         // Refuse possible leaked file descriptors
6542         if (icicle != null && icicle.hasFileDescriptors()) {
6543             throw new IllegalArgumentException("File descriptors passed in Bundle");
6544         }
6545
6546         final long origId = Binder.clearCallingIdentity();
6547
6548         synchronized (this) {
6549             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6550             if (r != null) {
6551                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6552             }
6553         }
6554
6555         trimApplications();
6556
6557         Binder.restoreCallingIdentity(origId);
6558     }
6559
6560     @Override
6561     public final void activityDestroyed(IBinder token) {
6562         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6563         synchronized (this) {
6564             ActivityStack stack = ActivityRecord.getStackLocked(token);
6565             if (stack != null) {
6566                 stack.activityDestroyedLocked(token, "activityDestroyed");
6567             }
6568         }
6569     }
6570
6571     @Override
6572     public final void backgroundResourcesReleased(IBinder token) {
6573         final long origId = Binder.clearCallingIdentity();
6574         try {
6575             synchronized (this) {
6576                 ActivityStack stack = ActivityRecord.getStackLocked(token);
6577                 if (stack != null) {
6578                     stack.backgroundResourcesReleased();
6579                 }
6580             }
6581         } finally {
6582             Binder.restoreCallingIdentity(origId);
6583         }
6584     }
6585
6586     @Override
6587     public final void notifyLaunchTaskBehindComplete(IBinder token) {
6588         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6589     }
6590
6591     @Override
6592     public final void notifyEnterAnimationComplete(IBinder token) {
6593         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6594     }
6595
6596     @Override
6597     public String getCallingPackage(IBinder token) {
6598         synchronized (this) {
6599             ActivityRecord r = getCallingRecordLocked(token);
6600             return r != null ? r.info.packageName : null;
6601         }
6602     }
6603
6604     @Override
6605     public ComponentName getCallingActivity(IBinder token) {
6606         synchronized (this) {
6607             ActivityRecord r = getCallingRecordLocked(token);
6608             return r != null ? r.intent.getComponent() : null;
6609         }
6610     }
6611
6612     private ActivityRecord getCallingRecordLocked(IBinder token) {
6613         ActivityRecord r = ActivityRecord.isInStackLocked(token);
6614         if (r == null) {
6615             return null;
6616         }
6617         return r.resultTo;
6618     }
6619
6620     @Override
6621     public ComponentName getActivityClassForToken(IBinder token) {
6622         synchronized(this) {
6623             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6624             if (r == null) {
6625                 return null;
6626             }
6627             return r.intent.getComponent();
6628         }
6629     }
6630
6631     @Override
6632     public String getPackageForToken(IBinder token) {
6633         synchronized(this) {
6634             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6635             if (r == null) {
6636                 return null;
6637             }
6638             return r.packageName;
6639         }
6640     }
6641
6642     @Override
6643     public boolean isRootVoiceInteraction(IBinder token) {
6644         synchronized(this) {
6645             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6646             if (r == null) {
6647                 return false;
6648             }
6649             return r.rootVoiceInteraction;
6650         }
6651     }
6652
6653     @Override
6654     public IIntentSender getIntentSender(int type,
6655             String packageName, IBinder token, String resultWho,
6656             int requestCode, Intent[] intents, String[] resolvedTypes,
6657             int flags, Bundle options, int userId) {
6658         enforceNotIsolatedCaller("getIntentSender");
6659         // Refuse possible leaked file descriptors
6660         if (intents != null) {
6661             if (intents.length < 1) {
6662                 throw new IllegalArgumentException("Intents array length must be >= 1");
6663             }
6664             for (int i=0; i<intents.length; i++) {
6665                 Intent intent = intents[i];
6666                 if (intent != null) {
6667                     if (intent.hasFileDescriptors()) {
6668                         throw new IllegalArgumentException("File descriptors passed in Intent");
6669                     }
6670                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6671                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6672                         throw new IllegalArgumentException(
6673                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6674                     }
6675                     intents[i] = new Intent(intent);
6676                 }
6677             }
6678             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6679                 throw new IllegalArgumentException(
6680                         "Intent array length does not match resolvedTypes length");
6681             }
6682         }
6683         if (options != null) {
6684             if (options.hasFileDescriptors()) {
6685                 throw new IllegalArgumentException("File descriptors passed in options");
6686             }
6687         }
6688
6689         synchronized(this) {
6690             int callingUid = Binder.getCallingUid();
6691             int origUserId = userId;
6692             userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6693                     type == ActivityManager.INTENT_SENDER_BROADCAST,
6694                     ALLOW_NON_FULL, "getIntentSender", null);
6695             if (origUserId == UserHandle.USER_CURRENT) {
6696                 // We don't want to evaluate this until the pending intent is
6697                 // actually executed.  However, we do want to always do the
6698                 // security checking for it above.
6699                 userId = UserHandle.USER_CURRENT;
6700             }
6701             try {
6702                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6703                     int uid = AppGlobals.getPackageManager()
6704                             .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6705                     if (!UserHandle.isSameApp(callingUid, uid)) {
6706                         String msg = "Permission Denial: getIntentSender() from pid="
6707                             + Binder.getCallingPid()
6708                             + ", uid=" + Binder.getCallingUid()
6709                             + ", (need uid=" + uid + ")"
6710                             + " is not allowed to send as package " + packageName;
6711                         Slog.w(TAG, msg);
6712                         throw new SecurityException(msg);
6713                     }
6714                 }
6715
6716                 return getIntentSenderLocked(type, packageName, callingUid, userId,
6717                         token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6718
6719             } catch (RemoteException e) {
6720                 throw new SecurityException(e);
6721             }
6722         }
6723     }
6724
6725     IIntentSender getIntentSenderLocked(int type, String packageName,
6726             int callingUid, int userId, IBinder token, String resultWho,
6727             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6728             Bundle options) {
6729         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6730         ActivityRecord activity = null;
6731         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6732             activity = ActivityRecord.isInStackLocked(token);
6733             if (activity == null) {
6734                 return null;
6735             }
6736             if (activity.finishing) {
6737                 return null;
6738             }
6739         }
6740
6741         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6742         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6743         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6744         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6745                 |PendingIntent.FLAG_UPDATE_CURRENT);
6746
6747         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6748                 type, packageName, activity, resultWho,
6749                 requestCode, intents, resolvedTypes, flags, options, userId);
6750         WeakReference<PendingIntentRecord> ref;
6751         ref = mIntentSenderRecords.get(key);
6752         PendingIntentRecord rec = ref != null ? ref.get() : null;
6753         if (rec != null) {
6754             if (!cancelCurrent) {
6755                 if (updateCurrent) {
6756                     if (rec.key.requestIntent != null) {
6757                         rec.key.requestIntent.replaceExtras(intents != null ?
6758                                 intents[intents.length - 1] : null);
6759                     }
6760                     if (intents != null) {
6761                         intents[intents.length-1] = rec.key.requestIntent;
6762                         rec.key.allIntents = intents;
6763                         rec.key.allResolvedTypes = resolvedTypes;
6764                     } else {
6765                         rec.key.allIntents = null;
6766                         rec.key.allResolvedTypes = null;
6767                     }
6768                 }
6769                 return rec;
6770             }
6771             rec.canceled = true;
6772             mIntentSenderRecords.remove(key);
6773         }
6774         if (noCreate) {
6775             return rec;
6776         }
6777         rec = new PendingIntentRecord(this, key, callingUid);
6778         mIntentSenderRecords.put(key, rec.ref);
6779         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6780             if (activity.pendingResults == null) {
6781                 activity.pendingResults
6782                         = new HashSet<WeakReference<PendingIntentRecord>>();
6783             }
6784             activity.pendingResults.add(rec.ref);
6785         }
6786         return rec;
6787     }
6788
6789     @Override
6790     public void cancelIntentSender(IIntentSender sender) {
6791         if (!(sender instanceof PendingIntentRecord)) {
6792             return;
6793         }
6794         synchronized(this) {
6795             PendingIntentRecord rec = (PendingIntentRecord)sender;
6796             try {
6797                 int uid = AppGlobals.getPackageManager()
6798                         .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6799                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6800                     String msg = "Permission Denial: cancelIntentSender() from pid="
6801                         + Binder.getCallingPid()
6802                         + ", uid=" + Binder.getCallingUid()
6803                         + " is not allowed to cancel packges "
6804                         + rec.key.packageName;
6805                     Slog.w(TAG, msg);
6806                     throw new SecurityException(msg);
6807                 }
6808             } catch (RemoteException e) {
6809                 throw new SecurityException(e);
6810             }
6811             cancelIntentSenderLocked(rec, true);
6812         }
6813     }
6814
6815     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6816         rec.canceled = true;
6817         mIntentSenderRecords.remove(rec.key);
6818         if (cleanActivity && rec.key.activity != null) {
6819             rec.key.activity.pendingResults.remove(rec.ref);
6820         }
6821     }
6822
6823     @Override
6824     public String getPackageForIntentSender(IIntentSender pendingResult) {
6825         if (!(pendingResult instanceof PendingIntentRecord)) {
6826             return null;
6827         }
6828         try {
6829             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6830             return res.key.packageName;
6831         } catch (ClassCastException e) {
6832         }
6833         return null;
6834     }
6835
6836     @Override
6837     public int getUidForIntentSender(IIntentSender sender) {
6838         if (sender instanceof PendingIntentRecord) {
6839             try {
6840                 PendingIntentRecord res = (PendingIntentRecord)sender;
6841                 return res.uid;
6842             } catch (ClassCastException e) {
6843             }
6844         }
6845         return -1;
6846     }
6847
6848     @Override
6849     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6850         if (!(pendingResult instanceof PendingIntentRecord)) {
6851             return false;
6852         }
6853         try {
6854             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6855             if (res.key.allIntents == null) {
6856                 return false;
6857             }
6858             for (int i=0; i<res.key.allIntents.length; i++) {
6859                 Intent intent = res.key.allIntents[i];
6860                 if (intent.getPackage() != null && intent.getComponent() != null) {
6861                     return false;
6862                 }
6863             }
6864             return true;
6865         } catch (ClassCastException e) {
6866         }
6867         return false;
6868     }
6869
6870     @Override
6871     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6872         if (!(pendingResult instanceof PendingIntentRecord)) {
6873             return false;
6874         }
6875         try {
6876             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6877             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6878                 return true;
6879             }
6880             return false;
6881         } catch (ClassCastException e) {
6882         }
6883         return false;
6884     }
6885
6886     @Override
6887     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6888         if (!(pendingResult instanceof PendingIntentRecord)) {
6889             return null;
6890         }
6891         try {
6892             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6893             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6894         } catch (ClassCastException e) {
6895         }
6896         return null;
6897     }
6898
6899     @Override
6900     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6901         if (!(pendingResult instanceof PendingIntentRecord)) {
6902             return null;
6903         }
6904         try {
6905             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6906             synchronized (this) {
6907                 return getTagForIntentSenderLocked(res, prefix);
6908             }
6909         } catch (ClassCastException e) {
6910         }
6911         return null;
6912     }
6913
6914     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6915         final Intent intent = res.key.requestIntent;
6916         if (intent != null) {
6917             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6918                     || res.lastTagPrefix.equals(prefix))) {
6919                 return res.lastTag;
6920             }
6921             res.lastTagPrefix = prefix;
6922             final StringBuilder sb = new StringBuilder(128);
6923             if (prefix != null) {
6924                 sb.append(prefix);
6925             }
6926             if (intent.getAction() != null) {
6927                 sb.append(intent.getAction());
6928             } else if (intent.getComponent() != null) {
6929                 intent.getComponent().appendShortString(sb);
6930             } else {
6931                 sb.append("?");
6932             }
6933             return res.lastTag = sb.toString();
6934         }
6935         return null;
6936     }
6937
6938     @Override
6939     public void setProcessLimit(int max) {
6940         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6941                 "setProcessLimit()");
6942         synchronized (this) {
6943             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6944             mProcessLimitOverride = max;
6945         }
6946         trimApplications();
6947     }
6948
6949     @Override
6950     public int getProcessLimit() {
6951         synchronized (this) {
6952             return mProcessLimitOverride;
6953         }
6954     }
6955
6956     void foregroundTokenDied(ForegroundToken token) {
6957         synchronized (ActivityManagerService.this) {
6958             synchronized (mPidsSelfLocked) {
6959                 ForegroundToken cur
6960                     = mForegroundProcesses.get(token.pid);
6961                 if (cur != token) {
6962                     return;
6963                 }
6964                 mForegroundProcesses.remove(token.pid);
6965                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6966                 if (pr == null) {
6967                     return;
6968                 }
6969                 pr.forcingToForeground = null;
6970                 updateProcessForegroundLocked(pr, false, false);
6971             }
6972             updateOomAdjLocked();
6973         }
6974     }
6975
6976     @Override
6977     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6978         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6979                 "setProcessForeground()");
6980         synchronized(this) {
6981             boolean changed = false;
6982
6983             synchronized (mPidsSelfLocked) {
6984                 ProcessRecord pr = mPidsSelfLocked.get(pid);
6985                 if (pr == null && isForeground) {
6986                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6987                     return;
6988                 }
6989                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
6990                 if (oldToken != null) {
6991                     oldToken.token.unlinkToDeath(oldToken, 0);
6992                     mForegroundProcesses.remove(pid);
6993                     if (pr != null) {
6994                         pr.forcingToForeground = null;
6995                     }
6996                     changed = true;
6997                 }
6998                 if (isForeground && token != null) {
6999                     ForegroundToken newToken = new ForegroundToken() {
7000                         @Override
7001                         public void binderDied() {
7002                             foregroundTokenDied(this);
7003                         }
7004                     };
7005                     newToken.pid = pid;
7006                     newToken.token = token;
7007                     try {
7008                         token.linkToDeath(newToken, 0);
7009                         mForegroundProcesses.put(pid, newToken);
7010                         pr.forcingToForeground = token;
7011                         changed = true;
7012                     } catch (RemoteException e) {
7013                         // If the process died while doing this, we will later
7014                         // do the cleanup with the process death link.
7015                     }
7016                 }
7017             }
7018
7019             if (changed) {
7020                 updateOomAdjLocked();
7021             }
7022         }
7023     }
7024
7025     // =========================================================
7026     // PROCESS INFO
7027     // =========================================================
7028
7029     static class ProcessInfoService extends IProcessInfoService.Stub {
7030         final ActivityManagerService mActivityManagerService;
7031         ProcessInfoService(ActivityManagerService activityManagerService) {
7032             mActivityManagerService = activityManagerService;
7033         }
7034
7035         @Override
7036         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7037             mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
7038         }
7039     }
7040
7041     /**
7042      * For each PID in the given input array, write the current process state
7043      * for that process into the output array, or -1 to indicate that no
7044      * process with the given PID exists.
7045      */
7046     public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
7047         if (pids == null) {
7048             throw new NullPointerException("pids");
7049         } else if (states == null) {
7050             throw new NullPointerException("states");
7051         } else if (pids.length != states.length) {
7052             throw new IllegalArgumentException("input and output arrays have different lengths!");
7053         }
7054
7055         synchronized (mPidsSelfLocked) {
7056             for (int i = 0; i < pids.length; i++) {
7057                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7058                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7059                         pr.curProcState;
7060             }
7061         }
7062     }
7063
7064     // =========================================================
7065     // PERMISSIONS
7066     // =========================================================
7067
7068     static class PermissionController extends IPermissionController.Stub {
7069         ActivityManagerService mActivityManagerService;
7070         PermissionController(ActivityManagerService activityManagerService) {
7071             mActivityManagerService = activityManagerService;
7072         }
7073
7074         @Override
7075         public boolean checkPermission(String permission, int pid, int uid) {
7076             return mActivityManagerService.checkPermission(permission, pid,
7077                     uid) == PackageManager.PERMISSION_GRANTED;
7078         }
7079
7080         @Override
7081         public String[] getPackagesForUid(int uid) {
7082             return mActivityManagerService.mContext.getPackageManager()
7083                     .getPackagesForUid(uid);
7084         }
7085
7086         @Override
7087         public boolean isRuntimePermission(String permission) {
7088             try {
7089                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7090                         .getPermissionInfo(permission, 0);
7091                 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7092             } catch (NameNotFoundException nnfe) {
7093                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7094             }
7095             return false;
7096         }
7097     }
7098
7099     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7100         @Override
7101         public int checkComponentPermission(String permission, int pid, int uid,
7102                 int owningUid, boolean exported) {
7103             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7104                     owningUid, exported);
7105         }
7106
7107         @Override
7108         public Object getAMSLock() {
7109             return ActivityManagerService.this;
7110         }
7111     }
7112
7113     /**
7114      * This can be called with or without the global lock held.
7115      */
7116     int checkComponentPermission(String permission, int pid, int uid,
7117             int owningUid, boolean exported) {
7118         if (pid == MY_PID) {
7119             return PackageManager.PERMISSION_GRANTED;
7120         }
7121         return ActivityManager.checkComponentPermission(permission, uid,
7122                 owningUid, exported);
7123     }
7124
7125     /**
7126      * As the only public entry point for permissions checking, this method
7127      * can enforce the semantic that requesting a check on a null global
7128      * permission is automatically denied.  (Internally a null permission
7129      * string is used when calling {@link #checkComponentPermission} in cases
7130      * when only uid-based security is needed.)
7131      *
7132      * This can be called with or without the global lock held.
7133      */
7134     @Override
7135     public int checkPermission(String permission, int pid, int uid) {
7136         if (permission == null) {
7137             return PackageManager.PERMISSION_DENIED;
7138         }
7139         return checkComponentPermission(permission, pid, uid, -1, true);
7140     }
7141
7142     @Override
7143     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7144         if (permission == null) {
7145             return PackageManager.PERMISSION_DENIED;
7146         }
7147
7148         // We might be performing an operation on behalf of an indirect binder
7149         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7150         // client identity accordingly before proceeding.
7151         Identity tlsIdentity = sCallerIdentity.get();
7152         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7153             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7154                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7155             uid = tlsIdentity.uid;
7156             pid = tlsIdentity.pid;
7157         }
7158
7159         return checkComponentPermission(permission, pid, uid, -1, true);
7160     }
7161
7162     /**
7163      * Binder IPC calls go through the public entry point.
7164      * This can be called with or without the global lock held.
7165      */
7166     int checkCallingPermission(String permission) {
7167         return checkPermission(permission,
7168                 Binder.getCallingPid(),
7169                 UserHandle.getAppId(Binder.getCallingUid()));
7170     }
7171
7172     /**
7173      * This can be called with or without the global lock held.
7174      */
7175     void enforceCallingPermission(String permission, String func) {
7176         if (checkCallingPermission(permission)
7177                 == PackageManager.PERMISSION_GRANTED) {
7178             return;
7179         }
7180
7181         String msg = "Permission Denial: " + func + " from pid="
7182                 + Binder.getCallingPid()
7183                 + ", uid=" + Binder.getCallingUid()
7184                 + " requires " + permission;
7185         Slog.w(TAG, msg);
7186         throw new SecurityException(msg);
7187     }
7188
7189     /**
7190      * Determine if UID is holding permissions required to access {@link Uri} in
7191      * the given {@link ProviderInfo}. Final permission checking is always done
7192      * in {@link ContentProvider}.
7193      */
7194     private final boolean checkHoldingPermissionsLocked(
7195             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7196         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7197                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7198         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7199             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7200                     != PERMISSION_GRANTED) {
7201                 return false;
7202             }
7203         }
7204         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7205     }
7206
7207     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7208             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7209         if (pi.applicationInfo.uid == uid) {
7210             return true;
7211         } else if (!pi.exported) {
7212             return false;
7213         }
7214
7215         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7216         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7217         try {
7218             // check if target holds top-level <provider> permissions
7219             if (!readMet && pi.readPermission != null && considerUidPermissions
7220                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7221                 readMet = true;
7222             }
7223             if (!writeMet && pi.writePermission != null && considerUidPermissions
7224                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7225                 writeMet = true;
7226             }
7227
7228             // track if unprotected read/write is allowed; any denied
7229             // <path-permission> below removes this ability
7230             boolean allowDefaultRead = pi.readPermission == null;
7231             boolean allowDefaultWrite = pi.writePermission == null;
7232
7233             // check if target holds any <path-permission> that match uri
7234             final PathPermission[] pps = pi.pathPermissions;
7235             if (pps != null) {
7236                 final String path = grantUri.uri.getPath();
7237                 int i = pps.length;
7238                 while (i > 0 && (!readMet || !writeMet)) {
7239                     i--;
7240                     PathPermission pp = pps[i];
7241                     if (pp.match(path)) {
7242                         if (!readMet) {
7243                             final String pprperm = pp.getReadPermission();
7244                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7245                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
7246                                     + ": match=" + pp.match(path)
7247                                     + " check=" + pm.checkUidPermission(pprperm, uid));
7248                             if (pprperm != null) {
7249                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7250                                         == PERMISSION_GRANTED) {
7251                                     readMet = true;
7252                                 } else {
7253                                     allowDefaultRead = false;
7254                                 }
7255                             }
7256                         }
7257                         if (!writeMet) {
7258                             final String ppwperm = pp.getWritePermission();
7259                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7260                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
7261                                     + ": match=" + pp.match(path)
7262                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
7263                             if (ppwperm != null) {
7264                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7265                                         == PERMISSION_GRANTED) {
7266                                     writeMet = true;
7267                                 } else {
7268                                     allowDefaultWrite = false;
7269                                 }
7270                             }
7271                         }
7272                     }
7273                 }
7274             }
7275
7276             // grant unprotected <provider> read/write, if not blocked by
7277             // <path-permission> above
7278             if (allowDefaultRead) readMet = true;
7279             if (allowDefaultWrite) writeMet = true;
7280
7281         } catch (RemoteException e) {
7282             return false;
7283         }
7284
7285         return readMet && writeMet;
7286     }
7287
7288     private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7289         ProviderInfo pi = null;
7290         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7291         if (cpr != null) {
7292             pi = cpr.info;
7293         } else {
7294             try {
7295                 pi = AppGlobals.getPackageManager().resolveContentProvider(
7296                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7297             } catch (RemoteException ex) {
7298             }
7299         }
7300         return pi;
7301     }
7302
7303     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7304         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7305         if (targetUris != null) {
7306             return targetUris.get(grantUri);
7307         }
7308         return null;
7309     }
7310
7311     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7312             String targetPkg, int targetUid, GrantUri grantUri) {
7313         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7314         if (targetUris == null) {
7315             targetUris = Maps.newArrayMap();
7316             mGrantedUriPermissions.put(targetUid, targetUris);
7317         }
7318
7319         UriPermission perm = targetUris.get(grantUri);
7320         if (perm == null) {
7321             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7322             targetUris.put(grantUri, perm);
7323         }
7324
7325         return perm;
7326     }
7327
7328     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7329             final int modeFlags) {
7330         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7331         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7332                 : UriPermission.STRENGTH_OWNED;
7333
7334         // Root gets to do everything.
7335         if (uid == 0) {
7336             return true;
7337         }
7338
7339         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7340         if (perms == null) return false;
7341
7342         // First look for exact match
7343         final UriPermission exactPerm = perms.get(grantUri);
7344         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7345             return true;
7346         }
7347
7348         // No exact match, look for prefixes
7349         final int N = perms.size();
7350         for (int i = 0; i < N; i++) {
7351             final UriPermission perm = perms.valueAt(i);
7352             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7353                     && perm.getStrength(modeFlags) >= minStrength) {
7354                 return true;
7355             }
7356         }
7357
7358         return false;
7359     }
7360
7361     /**
7362      * @param uri This uri must NOT contain an embedded userId.
7363      * @param userId The userId in which the uri is to be resolved.
7364      */
7365     @Override
7366     public int checkUriPermission(Uri uri, int pid, int uid,
7367             final int modeFlags, int userId, IBinder callerToken) {
7368         enforceNotIsolatedCaller("checkUriPermission");
7369
7370         // Another redirected-binder-call permissions check as in
7371         // {@link checkPermissionWithToken}.
7372         Identity tlsIdentity = sCallerIdentity.get();
7373         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7374             uid = tlsIdentity.uid;
7375             pid = tlsIdentity.pid;
7376         }
7377
7378         // Our own process gets to do everything.
7379         if (pid == MY_PID) {
7380             return PackageManager.PERMISSION_GRANTED;
7381         }
7382         synchronized (this) {
7383             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7384                     ? PackageManager.PERMISSION_GRANTED
7385                     : PackageManager.PERMISSION_DENIED;
7386         }
7387     }
7388
7389     /**
7390      * Check if the targetPkg can be granted permission to access uri by
7391      * the callingUid using the given modeFlags.  Throws a security exception
7392      * if callingUid is not allowed to do this.  Returns the uid of the target
7393      * if the URI permission grant should be performed; returns -1 if it is not
7394      * needed (for example targetPkg already has permission to access the URI).
7395      * If you already know the uid of the target, you can supply it in
7396      * lastTargetUid else set that to -1.
7397      */
7398     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7399             final int modeFlags, int lastTargetUid) {
7400         if (!Intent.isAccessUriMode(modeFlags)) {
7401             return -1;
7402         }
7403
7404         if (targetPkg != null) {
7405             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7406                     "Checking grant " + targetPkg + " permission to " + grantUri);
7407         }
7408
7409         final IPackageManager pm = AppGlobals.getPackageManager();
7410
7411         // If this is not a content: uri, we can't do anything with it.
7412         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7413             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7414                     "Can't grant URI permission for non-content URI: " + grantUri);
7415             return -1;
7416         }
7417
7418         final String authority = grantUri.uri.getAuthority();
7419         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7420         if (pi == null) {
7421             Slog.w(TAG, "No content provider found for permission check: " +
7422                     grantUri.uri.toSafeString());
7423             return -1;
7424         }
7425
7426         int targetUid = lastTargetUid;
7427         if (targetUid < 0 && targetPkg != null) {
7428             try {
7429                 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7430                 if (targetUid < 0) {
7431                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7432                             "Can't grant URI permission no uid for: " + targetPkg);
7433                     return -1;
7434                 }
7435             } catch (RemoteException ex) {
7436                 return -1;
7437             }
7438         }
7439
7440         if (targetUid >= 0) {
7441             // First...  does the target actually need this permission?
7442             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7443                 // No need to grant the target this permission.
7444                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7445                         "Target " + targetPkg + " already has full permission to " + grantUri);
7446                 return -1;
7447             }
7448         } else {
7449             // First...  there is no target package, so can anyone access it?
7450             boolean allowed = pi.exported;
7451             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7452                 if (pi.readPermission != null) {
7453                     allowed = false;
7454                 }
7455             }
7456             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7457                 if (pi.writePermission != null) {
7458                     allowed = false;
7459                 }
7460             }
7461             if (allowed) {
7462                 return -1;
7463             }
7464         }
7465
7466         /* There is a special cross user grant if:
7467          * - The target is on another user.
7468          * - Apps on the current user can access the uri without any uid permissions.
7469          * In this case, we grant a uri permission, even if the ContentProvider does not normally
7470          * grant uri permissions.
7471          */
7472         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7473                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7474                 modeFlags, false /*without considering the uid permissions*/);
7475
7476         // Second...  is the provider allowing granting of URI permissions?
7477         if (!specialCrossUserGrant) {
7478             if (!pi.grantUriPermissions) {
7479                 throw new SecurityException("Provider " + pi.packageName
7480                         + "/" + pi.name
7481                         + " does not allow granting of Uri permissions (uri "
7482                         + grantUri + ")");
7483             }
7484             if (pi.uriPermissionPatterns != null) {
7485                 final int N = pi.uriPermissionPatterns.length;
7486                 boolean allowed = false;
7487                 for (int i=0; i<N; i++) {
7488                     if (pi.uriPermissionPatterns[i] != null
7489                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7490                         allowed = true;
7491                         break;
7492                     }
7493                 }
7494                 if (!allowed) {
7495                     throw new SecurityException("Provider " + pi.packageName
7496                             + "/" + pi.name
7497                             + " does not allow granting of permission to path of Uri "
7498                             + grantUri);
7499                 }
7500             }
7501         }
7502
7503         // Third...  does the caller itself have permission to access
7504         // this uri?
7505         final int callingAppId = UserHandle.getAppId(callingUid);
7506         if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) {
7507             Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
7508                     + " grant to " + grantUri + "; use startActivityAsCaller() instead");
7509             return -1;
7510         } else {
7511             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7512                 // Require they hold a strong enough Uri permission
7513                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7514                     throw new SecurityException("Uid " + callingUid
7515                             + " does not have permission to uri " + grantUri);
7516                 }
7517             }
7518         }
7519         return targetUid;
7520     }
7521
7522     /**
7523      * @param uri This uri must NOT contain an embedded userId.
7524      * @param userId The userId in which the uri is to be resolved.
7525      */
7526     @Override
7527     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7528             final int modeFlags, int userId) {
7529         enforceNotIsolatedCaller("checkGrantUriPermission");
7530         synchronized(this) {
7531             return checkGrantUriPermissionLocked(callingUid, targetPkg,
7532                     new GrantUri(userId, uri, false), modeFlags, -1);
7533         }
7534     }
7535
7536     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7537             final int modeFlags, UriPermissionOwner owner) {
7538         if (!Intent.isAccessUriMode(modeFlags)) {
7539             return;
7540         }
7541
7542         // So here we are: the caller has the assumed permission
7543         // to the uri, and the target doesn't.  Let's now give this to
7544         // the target.
7545
7546         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7547                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7548
7549         final String authority = grantUri.uri.getAuthority();
7550         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7551         if (pi == null) {
7552             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7553             return;
7554         }
7555
7556         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7557             grantUri.prefix = true;
7558         }
7559         final UriPermission perm = findOrCreateUriPermissionLocked(
7560                 pi.packageName, targetPkg, targetUid, grantUri);
7561         perm.grantModes(modeFlags, owner);
7562     }
7563
7564     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7565             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7566         if (targetPkg == null) {
7567             throw new NullPointerException("targetPkg");
7568         }
7569         int targetUid;
7570         final IPackageManager pm = AppGlobals.getPackageManager();
7571         try {
7572             targetUid = pm.getPackageUid(targetPkg, targetUserId);
7573         } catch (RemoteException ex) {
7574             return;
7575         }
7576
7577         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7578                 targetUid);
7579         if (targetUid < 0) {
7580             return;
7581         }
7582
7583         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7584                 owner);
7585     }
7586
7587     static class NeededUriGrants extends ArrayList<GrantUri> {
7588         final String targetPkg;
7589         final int targetUid;
7590         final int flags;
7591
7592         NeededUriGrants(String targetPkg, int targetUid, int flags) {
7593             this.targetPkg = targetPkg;
7594             this.targetUid = targetUid;
7595             this.flags = flags;
7596         }
7597     }
7598
7599     /**
7600      * Like checkGrantUriPermissionLocked, but takes an Intent.
7601      */
7602     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7603             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7604         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7605                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7606                 + " clip=" + (intent != null ? intent.getClipData() : null)
7607                 + " from " + intent + "; flags=0x"
7608                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7609
7610         if (targetPkg == null) {
7611             throw new NullPointerException("targetPkg");
7612         }
7613
7614         if (intent == null) {
7615             return null;
7616         }
7617         Uri data = intent.getData();
7618         ClipData clip = intent.getClipData();
7619         if (data == null && clip == null) {
7620             return null;
7621         }
7622         // Default userId for uris in the intent (if they don't specify it themselves)
7623         int contentUserHint = intent.getContentUserHint();
7624         if (contentUserHint == UserHandle.USER_CURRENT) {
7625             contentUserHint = UserHandle.getUserId(callingUid);
7626         }
7627         final IPackageManager pm = AppGlobals.getPackageManager();
7628         int targetUid;
7629         if (needed != null) {
7630             targetUid = needed.targetUid;
7631         } else {
7632             try {
7633                 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7634             } catch (RemoteException ex) {
7635                 return null;
7636             }
7637             if (targetUid < 0) {
7638                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7639                         "Can't grant URI permission no uid for: " + targetPkg
7640                         + " on user " + targetUserId);
7641                 return null;
7642             }
7643         }
7644         if (data != null) {
7645             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7646             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7647                     targetUid);
7648             if (targetUid > 0) {
7649                 if (needed == null) {
7650                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
7651                 }
7652                 needed.add(grantUri);
7653             }
7654         }
7655         if (clip != null) {
7656             for (int i=0; i<clip.getItemCount(); i++) {
7657                 Uri uri = clip.getItemAt(i).getUri();
7658                 if (uri != null) {
7659                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7660                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7661                             targetUid);
7662                     if (targetUid > 0) {
7663                         if (needed == null) {
7664                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
7665                         }
7666                         needed.add(grantUri);
7667                     }
7668                 } else {
7669                     Intent clipIntent = clip.getItemAt(i).getIntent();
7670                     if (clipIntent != null) {
7671                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7672                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7673                         if (newNeeded != null) {
7674                             needed = newNeeded;
7675                         }
7676                     }
7677                 }
7678             }
7679         }
7680
7681         return needed;
7682     }
7683
7684     /**
7685      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7686      */
7687     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7688             UriPermissionOwner owner) {
7689         if (needed != null) {
7690             for (int i=0; i<needed.size(); i++) {
7691                 GrantUri grantUri = needed.get(i);
7692                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7693                         grantUri, needed.flags, owner);
7694             }
7695         }
7696     }
7697
7698     void grantUriPermissionFromIntentLocked(int callingUid,
7699             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7700         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7701                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7702         if (needed == null) {
7703             return;
7704         }
7705
7706         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7707     }
7708
7709     /**
7710      * @param uri This uri must NOT contain an embedded userId.
7711      * @param userId The userId in which the uri is to be resolved.
7712      */
7713     @Override
7714     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7715             final int modeFlags, int userId) {
7716         enforceNotIsolatedCaller("grantUriPermission");
7717         GrantUri grantUri = new GrantUri(userId, uri, false);
7718         synchronized(this) {
7719             final ProcessRecord r = getRecordForAppLocked(caller);
7720             if (r == null) {
7721                 throw new SecurityException("Unable to find app for caller "
7722                         + caller
7723                         + " when granting permission to uri " + grantUri);
7724             }
7725             if (targetPkg == null) {
7726                 throw new IllegalArgumentException("null target");
7727             }
7728             if (grantUri == null) {
7729                 throw new IllegalArgumentException("null uri");
7730             }
7731
7732             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7733                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7734                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7735                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7736
7737             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7738                     UserHandle.getUserId(r.uid));
7739         }
7740     }
7741
7742     void removeUriPermissionIfNeededLocked(UriPermission perm) {
7743         if (perm.modeFlags == 0) {
7744             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7745                     perm.targetUid);
7746             if (perms != null) {
7747                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7748                         "Removing " + perm.targetUid + " permission to " + perm.uri);
7749
7750                 perms.remove(perm.uri);
7751                 if (perms.isEmpty()) {
7752                     mGrantedUriPermissions.remove(perm.targetUid);
7753                 }
7754             }
7755         }
7756     }
7757
7758     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7759         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7760                 "Revoking all granted permissions to " + grantUri);
7761
7762         final IPackageManager pm = AppGlobals.getPackageManager();
7763         final String authority = grantUri.uri.getAuthority();
7764         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7765         if (pi == null) {
7766             Slog.w(TAG, "No content provider found for permission revoke: "
7767                     + grantUri.toSafeString());
7768             return;
7769         }
7770
7771         // Does the caller have this permission on the URI?
7772         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7773             // If they don't have direct access to the URI, then revoke any
7774             // ownerless URI permissions that have been granted to them.
7775             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7776             if (perms != null) {
7777                 boolean persistChanged = false;
7778                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7779                     final UriPermission perm = it.next();
7780                     if (perm.uri.sourceUserId == grantUri.sourceUserId
7781                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7782                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7783                                 "Revoking non-owned " + perm.targetUid
7784                                 + " permission to " + perm.uri);
7785                         persistChanged |= perm.revokeModes(
7786                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7787                         if (perm.modeFlags == 0) {
7788                             it.remove();
7789                         }
7790                     }
7791                 }
7792                 if (perms.isEmpty()) {
7793                     mGrantedUriPermissions.remove(callingUid);
7794                 }
7795                 if (persistChanged) {
7796                     schedulePersistUriGrants();
7797                 }
7798             }
7799             return;
7800         }
7801
7802         boolean persistChanged = false;
7803
7804         // Go through all of the permissions and remove any that match.
7805         int N = mGrantedUriPermissions.size();
7806         for (int i = 0; i < N; i++) {
7807             final int targetUid = mGrantedUriPermissions.keyAt(i);
7808             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7809
7810             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7811                 final UriPermission perm = it.next();
7812                 if (perm.uri.sourceUserId == grantUri.sourceUserId
7813                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7814                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7815                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
7816                     persistChanged |= perm.revokeModes(
7817                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7818                     if (perm.modeFlags == 0) {
7819                         it.remove();
7820                     }
7821                 }
7822             }
7823
7824             if (perms.isEmpty()) {
7825                 mGrantedUriPermissions.remove(targetUid);
7826                 N--;
7827                 i--;
7828             }
7829         }
7830
7831         if (persistChanged) {
7832             schedulePersistUriGrants();
7833         }
7834     }
7835
7836     /**
7837      * @param uri This uri must NOT contain an embedded userId.
7838      * @param userId The userId in which the uri is to be resolved.
7839      */
7840     @Override
7841     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7842             int userId) {
7843         enforceNotIsolatedCaller("revokeUriPermission");
7844         synchronized(this) {
7845             final ProcessRecord r = getRecordForAppLocked(caller);
7846             if (r == null) {
7847                 throw new SecurityException("Unable to find app for caller "
7848                         + caller
7849                         + " when revoking permission to uri " + uri);
7850             }
7851             if (uri == null) {
7852                 Slog.w(TAG, "revokeUriPermission: null uri");
7853                 return;
7854             }
7855
7856             if (!Intent.isAccessUriMode(modeFlags)) {
7857                 return;
7858             }
7859
7860             final String authority = uri.getAuthority();
7861             final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7862             if (pi == null) {
7863                 Slog.w(TAG, "No content provider found for permission revoke: "
7864                         + uri.toSafeString());
7865                 return;
7866             }
7867
7868             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7869         }
7870     }
7871
7872     /**
7873      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7874      * given package.
7875      *
7876      * @param packageName Package name to match, or {@code null} to apply to all
7877      *            packages.
7878      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7879      *            to all users.
7880      * @param persistable If persistable grants should be removed.
7881      */
7882     private void removeUriPermissionsForPackageLocked(
7883             String packageName, int userHandle, boolean persistable) {
7884         if (userHandle == UserHandle.USER_ALL && packageName == null) {
7885             throw new IllegalArgumentException("Must narrow by either package or user");
7886         }
7887
7888         boolean persistChanged = false;
7889
7890         int N = mGrantedUriPermissions.size();
7891         for (int i = 0; i < N; i++) {
7892             final int targetUid = mGrantedUriPermissions.keyAt(i);
7893             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7894
7895             // Only inspect grants matching user
7896             if (userHandle == UserHandle.USER_ALL
7897                     || userHandle == UserHandle.getUserId(targetUid)) {
7898                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7899                     final UriPermission perm = it.next();
7900
7901                     // Only inspect grants matching package
7902                     if (packageName == null || perm.sourcePkg.equals(packageName)
7903                             || perm.targetPkg.equals(packageName)) {
7904                         // Hacky solution as part of fixing a security bug; ignore
7905                         // grants associated with DownloadManager so we don't have
7906                         // to immediately launch it to regrant the permissions
7907                         if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
7908                                 && !persistable) continue;
7909
7910                         persistChanged |= perm.revokeModes(persistable
7911                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7912
7913                         // Only remove when no modes remain; any persisted grants
7914                         // will keep this alive.
7915                         if (perm.modeFlags == 0) {
7916                             it.remove();
7917                         }
7918                     }
7919                 }
7920
7921                 if (perms.isEmpty()) {
7922                     mGrantedUriPermissions.remove(targetUid);
7923                     N--;
7924                     i--;
7925                 }
7926             }
7927         }
7928
7929         if (persistChanged) {
7930             schedulePersistUriGrants();
7931         }
7932     }
7933
7934     @Override
7935     public IBinder newUriPermissionOwner(String name) {
7936         enforceNotIsolatedCaller("newUriPermissionOwner");
7937         synchronized(this) {
7938             UriPermissionOwner owner = new UriPermissionOwner(this, name);
7939             return owner.getExternalTokenLocked();
7940         }
7941     }
7942
7943     /**
7944      * @param uri This uri must NOT contain an embedded userId.
7945      * @param sourceUserId The userId in which the uri is to be resolved.
7946      * @param targetUserId The userId of the app that receives the grant.
7947      */
7948     @Override
7949     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7950             final int modeFlags, int sourceUserId, int targetUserId) {
7951         targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7952                 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7953         synchronized(this) {
7954             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7955             if (owner == null) {
7956                 throw new IllegalArgumentException("Unknown owner: " + token);
7957             }
7958             if (fromUid != Binder.getCallingUid()) {
7959                 if (Binder.getCallingUid() != Process.myUid()) {
7960                     // Only system code can grant URI permissions on behalf
7961                     // of other users.
7962                     throw new SecurityException("nice try");
7963                 }
7964             }
7965             if (targetPkg == null) {
7966                 throw new IllegalArgumentException("null target");
7967             }
7968             if (uri == null) {
7969                 throw new IllegalArgumentException("null uri");
7970             }
7971
7972             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7973                     modeFlags, owner, targetUserId);
7974         }
7975     }
7976
7977     /**
7978      * @param uri This uri must NOT contain an embedded userId.
7979      * @param userId The userId in which the uri is to be resolved.
7980      */
7981     @Override
7982     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7983         synchronized(this) {
7984             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7985             if (owner == null) {
7986                 throw new IllegalArgumentException("Unknown owner: " + token);
7987             }
7988
7989             if (uri == null) {
7990                 owner.removeUriPermissionsLocked(mode);
7991             } else {
7992                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7993             }
7994         }
7995     }
7996
7997     private void schedulePersistUriGrants() {
7998         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7999             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8000                     10 * DateUtils.SECOND_IN_MILLIS);
8001         }
8002     }
8003
8004     private void writeGrantedUriPermissions() {
8005         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8006
8007         // Snapshot permissions so we can persist without lock
8008         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8009         synchronized (this) {
8010             final int size = mGrantedUriPermissions.size();
8011             for (int i = 0; i < size; i++) {
8012                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8013                 for (UriPermission perm : perms.values()) {
8014                     if (perm.persistedModeFlags != 0) {
8015                         persist.add(perm.snapshot());
8016                     }
8017                 }
8018             }
8019         }
8020
8021         FileOutputStream fos = null;
8022         try {
8023             fos = mGrantFile.startWrite();
8024
8025             XmlSerializer out = new FastXmlSerializer();
8026             out.setOutput(fos, StandardCharsets.UTF_8.name());
8027             out.startDocument(null, true);
8028             out.startTag(null, TAG_URI_GRANTS);
8029             for (UriPermission.Snapshot perm : persist) {
8030                 out.startTag(null, TAG_URI_GRANT);
8031                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8032                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8033                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8034                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8035                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8036                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8037                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8038                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8039                 out.endTag(null, TAG_URI_GRANT);
8040             }
8041             out.endTag(null, TAG_URI_GRANTS);
8042             out.endDocument();
8043
8044             mGrantFile.finishWrite(fos);
8045         } catch (IOException e) {
8046             if (fos != null) {
8047                 mGrantFile.failWrite(fos);
8048             }
8049         }
8050     }
8051
8052     private void readGrantedUriPermissionsLocked() {
8053         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8054
8055         final long now = System.currentTimeMillis();
8056
8057         FileInputStream fis = null;
8058         try {
8059             fis = mGrantFile.openRead();
8060             final XmlPullParser in = Xml.newPullParser();
8061             in.setInput(fis, StandardCharsets.UTF_8.name());
8062
8063             int type;
8064             while ((type = in.next()) != END_DOCUMENT) {
8065                 final String tag = in.getName();
8066                 if (type == START_TAG) {
8067                     if (TAG_URI_GRANT.equals(tag)) {
8068                         final int sourceUserId;
8069                         final int targetUserId;
8070                         final int userHandle = readIntAttribute(in,
8071                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8072                         if (userHandle != UserHandle.USER_NULL) {
8073                             // For backwards compatibility.
8074                             sourceUserId = userHandle;
8075                             targetUserId = userHandle;
8076                         } else {
8077                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8078                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8079                         }
8080                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8081                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8082                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8083                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8084                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8085                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8086
8087                         // Sanity check that provider still belongs to source package
8088                         final ProviderInfo pi = getProviderInfoLocked(
8089                                 uri.getAuthority(), sourceUserId);
8090                         if (pi != null && sourcePkg.equals(pi.packageName)) {
8091                             int targetUid = -1;
8092                             try {
8093                                 targetUid = AppGlobals.getPackageManager()
8094                                         .getPackageUid(targetPkg, targetUserId);
8095                             } catch (RemoteException e) {
8096                             }
8097                             if (targetUid != -1) {
8098                                 final UriPermission perm = findOrCreateUriPermissionLocked(
8099                                         sourcePkg, targetPkg, targetUid,
8100                                         new GrantUri(sourceUserId, uri, prefix));
8101                                 perm.initPersistedModes(modeFlags, createdTime);
8102                             }
8103                         } else {
8104                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8105                                     + " but instead found " + pi);
8106                         }
8107                     }
8108                 }
8109             }
8110         } catch (FileNotFoundException e) {
8111             // Missing grants is okay
8112         } catch (IOException e) {
8113             Slog.wtf(TAG, "Failed reading Uri grants", e);
8114         } catch (XmlPullParserException e) {
8115             Slog.wtf(TAG, "Failed reading Uri grants", e);
8116         } finally {
8117             IoUtils.closeQuietly(fis);
8118         }
8119     }
8120
8121     /**
8122      * @param uri This uri must NOT contain an embedded userId.
8123      * @param userId The userId in which the uri is to be resolved.
8124      */
8125     @Override
8126     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8127         enforceNotIsolatedCaller("takePersistableUriPermission");
8128
8129         Preconditions.checkFlagsArgument(modeFlags,
8130                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8131
8132         synchronized (this) {
8133             final int callingUid = Binder.getCallingUid();
8134             boolean persistChanged = false;
8135             GrantUri grantUri = new GrantUri(userId, uri, false);
8136
8137             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8138                     new GrantUri(userId, uri, false));
8139             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8140                     new GrantUri(userId, uri, true));
8141
8142             final boolean exactValid = (exactPerm != null)
8143                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8144             final boolean prefixValid = (prefixPerm != null)
8145                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8146
8147             if (!(exactValid || prefixValid)) {
8148                 throw new SecurityException("No persistable permission grants found for UID "
8149                         + callingUid + " and Uri " + grantUri.toSafeString());
8150             }
8151
8152             if (exactValid) {
8153                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8154             }
8155             if (prefixValid) {
8156                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8157             }
8158
8159             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8160
8161             if (persistChanged) {
8162                 schedulePersistUriGrants();
8163             }
8164         }
8165     }
8166
8167     /**
8168      * @param uri This uri must NOT contain an embedded userId.
8169      * @param userId The userId in which the uri is to be resolved.
8170      */
8171     @Override
8172     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8173         enforceNotIsolatedCaller("releasePersistableUriPermission");
8174
8175         Preconditions.checkFlagsArgument(modeFlags,
8176                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8177
8178         synchronized (this) {
8179             final int callingUid = Binder.getCallingUid();
8180             boolean persistChanged = false;
8181
8182             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8183                     new GrantUri(userId, uri, false));
8184             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8185                     new GrantUri(userId, uri, true));
8186             if (exactPerm == null && prefixPerm == null) {
8187                 throw new SecurityException("No permission grants found for UID " + callingUid
8188                         + " and Uri " + uri.toSafeString());
8189             }
8190
8191             if (exactPerm != null) {
8192                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8193                 removeUriPermissionIfNeededLocked(exactPerm);
8194             }
8195             if (prefixPerm != null) {
8196                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8197                 removeUriPermissionIfNeededLocked(prefixPerm);
8198             }
8199
8200             if (persistChanged) {
8201                 schedulePersistUriGrants();
8202             }
8203         }
8204     }
8205
8206     /**
8207      * Prune any older {@link UriPermission} for the given UID until outstanding
8208      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8209      *
8210      * @return if any mutations occured that require persisting.
8211      */
8212     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8213         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8214         if (perms == null) return false;
8215         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8216
8217         final ArrayList<UriPermission> persisted = Lists.newArrayList();
8218         for (UriPermission perm : perms.values()) {
8219             if (perm.persistedModeFlags != 0) {
8220                 persisted.add(perm);
8221             }
8222         }
8223
8224         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8225         if (trimCount <= 0) return false;
8226
8227         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8228         for (int i = 0; i < trimCount; i++) {
8229             final UriPermission perm = persisted.get(i);
8230
8231             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8232                     "Trimming grant created at " + perm.persistedCreateTime);
8233
8234             perm.releasePersistableModes(~0);
8235             removeUriPermissionIfNeededLocked(perm);
8236         }
8237
8238         return true;
8239     }
8240
8241     @Override
8242     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8243             String packageName, boolean incoming) {
8244         enforceNotIsolatedCaller("getPersistedUriPermissions");
8245         Preconditions.checkNotNull(packageName, "packageName");
8246
8247         final int callingUid = Binder.getCallingUid();
8248         final IPackageManager pm = AppGlobals.getPackageManager();
8249         try {
8250             final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8251             if (packageUid != callingUid) {
8252                 throw new SecurityException(
8253                         "Package " + packageName + " does not belong to calling UID " + callingUid);
8254             }
8255         } catch (RemoteException e) {
8256             throw new SecurityException("Failed to verify package name ownership");
8257         }
8258
8259         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8260         synchronized (this) {
8261             if (incoming) {
8262                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8263                         callingUid);
8264                 if (perms == null) {
8265                     Slog.w(TAG, "No permission grants found for " + packageName);
8266                 } else {
8267                     for (UriPermission perm : perms.values()) {
8268                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8269                             result.add(perm.buildPersistedPublicApiObject());
8270                         }
8271                     }
8272                 }
8273             } else {
8274                 final int size = mGrantedUriPermissions.size();
8275                 for (int i = 0; i < size; i++) {
8276                     final ArrayMap<GrantUri, UriPermission> perms =
8277                             mGrantedUriPermissions.valueAt(i);
8278                     for (UriPermission perm : perms.values()) {
8279                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8280                             result.add(perm.buildPersistedPublicApiObject());
8281                         }
8282                     }
8283                 }
8284             }
8285         }
8286         return new ParceledListSlice<android.content.UriPermission>(result);
8287     }
8288
8289     @Override
8290     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8291         synchronized (this) {
8292             ProcessRecord app =
8293                 who != null ? getRecordForAppLocked(who) : null;
8294             if (app == null) return;
8295
8296             Message msg = Message.obtain();
8297             msg.what = WAIT_FOR_DEBUGGER_MSG;
8298             msg.obj = app;
8299             msg.arg1 = waiting ? 1 : 0;
8300             mUiHandler.sendMessage(msg);
8301         }
8302     }
8303
8304     @Override
8305     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8306         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8307         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8308         outInfo.availMem = Process.getFreeMemory();
8309         outInfo.totalMem = Process.getTotalMemory();
8310         outInfo.threshold = homeAppMem;
8311         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8312         outInfo.hiddenAppThreshold = cachedAppMem;
8313         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8314                 ProcessList.SERVICE_ADJ);
8315         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8316                 ProcessList.VISIBLE_APP_ADJ);
8317         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8318                 ProcessList.FOREGROUND_APP_ADJ);
8319     }
8320
8321     // =========================================================
8322     // TASK MANAGEMENT
8323     // =========================================================
8324
8325     @Override
8326     public List<IAppTask> getAppTasks(String callingPackage) {
8327         int callingUid = Binder.getCallingUid();
8328         long ident = Binder.clearCallingIdentity();
8329
8330         synchronized(this) {
8331             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8332             try {
8333                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8334
8335                 final int N = mRecentTasks.size();
8336                 for (int i = 0; i < N; i++) {
8337                     TaskRecord tr = mRecentTasks.get(i);
8338                     // Skip tasks that do not match the caller.  We don't need to verify
8339                     // callingPackage, because we are also limiting to callingUid and know
8340                     // that will limit to the correct security sandbox.
8341                     if (tr.effectiveUid != callingUid) {
8342                         continue;
8343                     }
8344                     Intent intent = tr.getBaseIntent();
8345                     if (intent == null ||
8346                             !callingPackage.equals(intent.getComponent().getPackageName())) {
8347                         continue;
8348                     }
8349                     ActivityManager.RecentTaskInfo taskInfo =
8350                             createRecentTaskInfoFromTaskRecord(tr);
8351                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8352                     list.add(taskImpl);
8353                 }
8354             } finally {
8355                 Binder.restoreCallingIdentity(ident);
8356             }
8357             return list;
8358         }
8359     }
8360
8361     @Override
8362     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8363         final int callingUid = Binder.getCallingUid();
8364         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8365
8366         synchronized(this) {
8367             if (DEBUG_ALL) Slog.v(
8368                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8369
8370             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8371                     callingUid);
8372
8373             // TODO: Improve with MRU list from all ActivityStacks.
8374             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8375         }
8376
8377         return list;
8378     }
8379
8380     /**
8381      * Creates a new RecentTaskInfo from a TaskRecord.
8382      */
8383     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8384         // Update the task description to reflect any changes in the task stack
8385         tr.updateTaskDescription();
8386
8387         // Compose the recent task info
8388         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8389         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8390         rti.persistentId = tr.taskId;
8391         rti.baseIntent = new Intent(tr.getBaseIntent());
8392         rti.origActivity = tr.origActivity;
8393         rti.description = tr.lastDescription;
8394         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8395         rti.userId = tr.userId;
8396         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8397         rti.firstActiveTime = tr.firstActiveTime;
8398         rti.lastActiveTime = tr.lastActiveTime;
8399         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8400         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8401         rti.numActivities = 0;
8402
8403         ActivityRecord base = null;
8404         ActivityRecord top = null;
8405         ActivityRecord tmp;
8406
8407         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8408             tmp = tr.mActivities.get(i);
8409             if (tmp.finishing) {
8410                 continue;
8411             }
8412             base = tmp;
8413             if (top == null || (top.state == ActivityState.INITIALIZING)) {
8414                 top = base;
8415             }
8416             rti.numActivities++;
8417         }
8418
8419         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8420         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8421
8422         return rti;
8423     }
8424
8425     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8426         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8427                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8428         if (!allowed) {
8429             if (checkPermission(android.Manifest.permission.GET_TASKS,
8430                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8431                 // Temporary compatibility: some existing apps on the system image may
8432                 // still be requesting the old permission and not switched to the new
8433                 // one; if so, we'll still allow them full access.  This means we need
8434                 // to see if they are holding the old permission and are a system app.
8435                 try {
8436                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8437                         allowed = true;
8438                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8439                                 + " is using old GET_TASKS but privileged; allowing");
8440                     }
8441                 } catch (RemoteException e) {
8442                 }
8443             }
8444         }
8445         if (!allowed) {
8446             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8447                     + " does not hold REAL_GET_TASKS; limiting output");
8448         }
8449         return allowed;
8450     }
8451
8452     @Override
8453     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8454         final int callingUid = Binder.getCallingUid();
8455         userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8456                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8457
8458         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8459         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8460         synchronized (this) {
8461             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8462                     callingUid);
8463             final boolean detailed = checkCallingPermission(
8464                     android.Manifest.permission.GET_DETAILED_TASKS)
8465                     == PackageManager.PERMISSION_GRANTED;
8466
8467             final int recentsCount = mRecentTasks.size();
8468             ArrayList<ActivityManager.RecentTaskInfo> res =
8469                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8470
8471             final Set<Integer> includedUsers;
8472             if (includeProfiles) {
8473                 includedUsers = getProfileIdsLocked(userId);
8474             } else {
8475                 includedUsers = new HashSet<>();
8476             }
8477             includedUsers.add(Integer.valueOf(userId));
8478
8479             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8480                 TaskRecord tr = mRecentTasks.get(i);
8481                 // Only add calling user or related users recent tasks
8482                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8483                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8484                     continue;
8485                 }
8486
8487                 // Return the entry if desired by the caller.  We always return
8488                 // the first entry, because callers always expect this to be the
8489                 // foreground app.  We may filter others if the caller has
8490                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
8491                 // we should exclude the entry.
8492
8493                 if (i == 0
8494                         || withExcluded
8495                         || (tr.intent == null)
8496                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8497                                 == 0)) {
8498                     if (!allowed) {
8499                         // If the caller doesn't have the GET_TASKS permission, then only
8500                         // allow them to see a small subset of tasks -- their own and home.
8501                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8502                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8503                             continue;
8504                         }
8505                     }
8506                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8507                         if (tr.stack != null && tr.stack.isHomeStack()) {
8508                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8509                                     "Skipping, home stack task: " + tr);
8510                             continue;
8511                         }
8512                     }
8513                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8514                         // Don't include auto remove tasks that are finished or finishing.
8515                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8516                                 "Skipping, auto-remove without activity: " + tr);
8517                         continue;
8518                     }
8519                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8520                             && !tr.isAvailable) {
8521                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8522                                 "Skipping, unavail real act: " + tr);
8523                         continue;
8524                     }
8525
8526                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8527                     if (!detailed) {
8528                         rti.baseIntent.replaceExtras((Bundle)null);
8529                     }
8530
8531                     res.add(rti);
8532                     maxNum--;
8533                 }
8534             }
8535             return res;
8536         }
8537     }
8538
8539     @Override
8540     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8541         synchronized (this) {
8542             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8543                     "getTaskThumbnail()");
8544             TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8545             if (tr != null) {
8546                 return tr.getTaskThumbnailLocked();
8547             }
8548         }
8549         return null;
8550     }
8551
8552     @Override
8553     public int addAppTask(IBinder activityToken, Intent intent,
8554             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8555         final int callingUid = Binder.getCallingUid();
8556         final long callingIdent = Binder.clearCallingIdentity();
8557
8558         try {
8559             synchronized (this) {
8560                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8561                 if (r == null) {
8562                     throw new IllegalArgumentException("Activity does not exist; token="
8563                             + activityToken);
8564                 }
8565                 ComponentName comp = intent.getComponent();
8566                 if (comp == null) {
8567                     throw new IllegalArgumentException("Intent " + intent
8568                             + " must specify explicit component");
8569                 }
8570                 if (thumbnail.getWidth() != mThumbnailWidth
8571                         || thumbnail.getHeight() != mThumbnailHeight) {
8572                     throw new IllegalArgumentException("Bad thumbnail size: got "
8573                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8574                             + mThumbnailWidth + "x" + mThumbnailHeight);
8575                 }
8576                 if (intent.getSelector() != null) {
8577                     intent.setSelector(null);
8578                 }
8579                 if (intent.getSourceBounds() != null) {
8580                     intent.setSourceBounds(null);
8581                 }
8582                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8583                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8584                         // The caller has added this as an auto-remove task...  that makes no
8585                         // sense, so turn off auto-remove.
8586                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8587                     }
8588                 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8589                     // Must be a new task.
8590                     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8591                 }
8592                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8593                     mLastAddedTaskActivity = null;
8594                 }
8595                 ActivityInfo ainfo = mLastAddedTaskActivity;
8596                 if (ainfo == null) {
8597                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8598                             comp, 0, UserHandle.getUserId(callingUid));
8599                     if (ainfo.applicationInfo.uid != callingUid) {
8600                         throw new SecurityException(
8601                                 "Can't add task for another application: target uid="
8602                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8603                     }
8604                 }
8605
8606                 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8607                         intent, description);
8608
8609                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8610                 if (trimIdx >= 0) {
8611                     // If this would have caused a trim, then we'll abort because that
8612                     // means it would be added at the end of the list but then just removed.
8613                     return INVALID_TASK_ID;
8614                 }
8615
8616                 final int N = mRecentTasks.size();
8617                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8618                     final TaskRecord tr = mRecentTasks.remove(N - 1);
8619                     tr.removedFromRecents();
8620                 }
8621
8622                 task.inRecents = true;
8623                 mRecentTasks.add(task);
8624                 r.task.stack.addTask(task, false, false);
8625
8626                 task.setLastThumbnail(thumbnail);
8627                 task.freeLastThumbnail();
8628
8629                 return task.taskId;
8630             }
8631         } finally {
8632             Binder.restoreCallingIdentity(callingIdent);
8633         }
8634     }
8635
8636     @Override
8637     public Point getAppTaskThumbnailSize() {
8638         synchronized (this) {
8639             return new Point(mThumbnailWidth,  mThumbnailHeight);
8640         }
8641     }
8642
8643     @Override
8644     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8645         synchronized (this) {
8646             ActivityRecord r = ActivityRecord.isInStackLocked(token);
8647             if (r != null) {
8648                 r.setTaskDescription(td);
8649                 r.task.updateTaskDescription();
8650             }
8651         }
8652     }
8653
8654     @Override
8655     public void setTaskResizeable(int taskId, boolean resizeable) {
8656         synchronized (this) {
8657             TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8658             if (task == null) {
8659                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8660                 return;
8661             }
8662             if (task.mResizeable != resizeable) {
8663                 task.mResizeable = resizeable;
8664                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8665                 mStackSupervisor.resumeTopActivitiesLocked();
8666             }
8667         }
8668     }
8669
8670     @Override
8671     public void resizeTask(int taskId, Rect bounds) {
8672         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8673                 "resizeTask()");
8674         long ident = Binder.clearCallingIdentity();
8675         try {
8676             synchronized (this) {
8677                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8678                 if (task == null) {
8679                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8680                     return;
8681                 }
8682                 mStackSupervisor.resizeTaskLocked(task, bounds);
8683             }
8684         } finally {
8685             Binder.restoreCallingIdentity(ident);
8686         }
8687     }
8688
8689     @Override
8690     public Bitmap getTaskDescriptionIcon(String filename) {
8691         if (!FileUtils.isValidExtFilename(filename)
8692                 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8693             throw new IllegalArgumentException("Bad filename: " + filename);
8694         }
8695         return mTaskPersister.getTaskDescriptionIcon(filename);
8696     }
8697
8698     @Override
8699     public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8700             throws RemoteException {
8701         if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8702                 opts.getCustomInPlaceResId() == 0) {
8703             throw new IllegalArgumentException("Expected in-place ActivityOption " +
8704                     "with valid animation");
8705         }
8706         mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8707         mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8708                 opts.getCustomInPlaceResId());
8709         mWindowManager.executeAppTransition();
8710     }
8711
8712     private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8713         mRecentTasks.remove(tr);
8714         tr.removedFromRecents();
8715         ComponentName component = tr.getBaseIntent().getComponent();
8716         if (component == null) {
8717             Slog.w(TAG, "No component for base intent of task: " + tr);
8718             return;
8719         }
8720
8721         // Find any running services associated with this app and stop if needed.
8722         mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8723
8724         if (!killProcess) {
8725             return;
8726         }
8727
8728         // Determine if the process(es) for this task should be killed.
8729         final String pkg = component.getPackageName();
8730         ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8731         ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8732         for (int i = 0; i < pmap.size(); i++) {
8733
8734             SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8735             for (int j = 0; j < uids.size(); j++) {
8736                 ProcessRecord proc = uids.valueAt(j);
8737                 if (proc.userId != tr.userId) {
8738                     // Don't kill process for a different user.
8739                     continue;
8740                 }
8741                 if (proc == mHomeProcess) {
8742                     // Don't kill the home process along with tasks from the same package.
8743                     continue;
8744                 }
8745                 if (!proc.pkgList.containsKey(pkg)) {
8746                     // Don't kill process that is not associated with this task.
8747                     continue;
8748                 }
8749
8750                 for (int k = 0; k < proc.activities.size(); k++) {
8751                     TaskRecord otherTask = proc.activities.get(k).task;
8752                     if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8753                         // Don't kill process(es) that has an activity in a different task that is
8754                         // also in recents.
8755                         return;
8756                     }
8757                 }
8758
8759                 if (proc.foregroundServices) {
8760                     // Don't kill process(es) with foreground service.
8761                     return;
8762                 }
8763
8764                 // Add process to kill list.
8765                 procsToKill.add(proc);
8766             }
8767         }
8768
8769         // Kill the running processes.
8770         for (int i = 0; i < procsToKill.size(); i++) {
8771             ProcessRecord pr = procsToKill.get(i);
8772             if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8773                     && pr.curReceiver == null) {
8774                 pr.kill("remove task", true);
8775             } else {
8776                 // We delay killing processes that are not in the background or running a receiver.
8777                 pr.waitingToKill = "remove task";
8778             }
8779         }
8780     }
8781
8782     private void removeTasksByPackageNameLocked(String packageName, int userId) {
8783         // Remove all tasks with activities in the specified package from the list of recent tasks
8784         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8785             TaskRecord tr = mRecentTasks.get(i);
8786             if (tr.userId != userId) continue;
8787
8788             ComponentName cn = tr.intent.getComponent();
8789             if (cn != null && cn.getPackageName().equals(packageName)) {
8790                 // If the package name matches, remove the task.
8791                 removeTaskByIdLocked(tr.taskId, true);
8792             }
8793         }
8794     }
8795
8796     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8797             int userId) {
8798
8799         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8800             TaskRecord tr = mRecentTasks.get(i);
8801             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8802                 continue;
8803             }
8804
8805             ComponentName cn = tr.intent.getComponent();
8806             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8807                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8808             if (sameComponent) {
8809                 removeTaskByIdLocked(tr.taskId, false);
8810             }
8811         }
8812     }
8813
8814     /**
8815      * Removes the task with the specified task id.
8816      *
8817      * @param taskId Identifier of the task to be removed.
8818      * @param killProcess Kill any process associated with the task if possible.
8819      * @return Returns true if the given task was found and removed.
8820      */
8821     private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8822         TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8823         if (tr != null) {
8824             tr.removeTaskActivitiesLocked();
8825             cleanUpRemovedTaskLocked(tr, killProcess);
8826             if (tr.isPersistable) {
8827                 notifyTaskPersisterLocked(null, true);
8828             }
8829             return true;
8830         }
8831         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8832         return false;
8833     }
8834
8835     @Override
8836     public boolean removeTask(int taskId) {
8837         synchronized (this) {
8838             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8839                     "removeTask()");
8840             long ident = Binder.clearCallingIdentity();
8841             try {
8842                 return removeTaskByIdLocked(taskId, true);
8843             } finally {
8844                 Binder.restoreCallingIdentity(ident);
8845             }
8846         }
8847     }
8848
8849     /**
8850      * TODO: Add mController hook
8851      */
8852     @Override
8853     public void moveTaskToFront(int taskId, int flags, Bundle options) {
8854         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8855
8856         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8857         synchronized(this) {
8858             moveTaskToFrontLocked(taskId, flags, options);
8859         }
8860     }
8861
8862     void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8863         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8864                 Binder.getCallingUid(), -1, -1, "Task to front")) {
8865             ActivityOptions.abort(options);
8866             return;
8867         }
8868         final long origId = Binder.clearCallingIdentity();
8869         try {
8870             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8871             if (task == null) {
8872                 Slog.d(TAG, "Could not find task for id: "+ taskId);
8873                 return;
8874             }
8875             if (mStackSupervisor.isLockTaskModeViolation(task)) {
8876                 mStackSupervisor.showLockTaskToast();
8877                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8878                 return;
8879             }
8880             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8881             if (prev != null && prev.isRecentsActivity()) {
8882                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8883             }
8884             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8885         } finally {
8886             Binder.restoreCallingIdentity(origId);
8887         }
8888         ActivityOptions.abort(options);
8889     }
8890
8891     /**
8892      * Moves an activity, and all of the other activities within the same task, to the bottom
8893      * of the history stack.  The activity's order within the task is unchanged.
8894      *
8895      * @param token A reference to the activity we wish to move
8896      * @param nonRoot If false then this only works if the activity is the root
8897      *                of a task; if true it will work for any activity in a task.
8898      * @return Returns true if the move completed, false if not.
8899      */
8900     @Override
8901     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8902         enforceNotIsolatedCaller("moveActivityTaskToBack");
8903         synchronized(this) {
8904             final long origId = Binder.clearCallingIdentity();
8905             try {
8906                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8907                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8908                 if (task != null) {
8909                     if (mStackSupervisor.isLockedTask(task)) {
8910                         mStackSupervisor.showLockTaskToast();
8911                         return false;
8912                     }
8913                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8914                 }
8915             } finally {
8916                 Binder.restoreCallingIdentity(origId);
8917             }
8918         }
8919         return false;
8920     }
8921
8922     @Override
8923     public void moveTaskBackwards(int task) {
8924         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8925                 "moveTaskBackwards()");
8926
8927         synchronized(this) {
8928             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8929                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
8930                 return;
8931             }
8932             final long origId = Binder.clearCallingIdentity();
8933             moveTaskBackwardsLocked(task);
8934             Binder.restoreCallingIdentity(origId);
8935         }
8936     }
8937
8938     private final void moveTaskBackwardsLocked(int task) {
8939         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8940     }
8941
8942     @Override
8943     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8944             IActivityContainerCallback callback) throws RemoteException {
8945         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8946                 "createActivityContainer()");
8947         synchronized (this) {
8948             if (parentActivityToken == null) {
8949                 throw new IllegalArgumentException("parent token must not be null");
8950             }
8951             ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8952             if (r == null) {
8953                 return null;
8954             }
8955             if (callback == null) {
8956                 throw new IllegalArgumentException("callback must not be null");
8957             }
8958             return mStackSupervisor.createVirtualActivityContainer(r, callback);
8959         }
8960     }
8961
8962     @Override
8963     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8964         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8965                 "deleteActivityContainer()");
8966         synchronized (this) {
8967             mStackSupervisor.deleteActivityContainer(container);
8968         }
8969     }
8970
8971     @Override
8972     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8973         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8974                 "createStackOnDisplay()");
8975         synchronized (this) {
8976             final int stackId = mStackSupervisor.getNextStackId();
8977             final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8978             if (stack == null) {
8979                 return null;
8980             }
8981             return stack.mActivityContainer;
8982         }
8983     }
8984
8985     @Override
8986     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8987         synchronized (this) {
8988             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8989             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8990                 return stack.mActivityContainer.getDisplayId();
8991             }
8992             return Display.DEFAULT_DISPLAY;
8993         }
8994     }
8995
8996     @Override
8997     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8998         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8999                 "moveTaskToStack()");
9000         if (stackId == HOME_STACK_ID) {
9001             Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
9002                     new RuntimeException("here").fillInStackTrace());
9003         }
9004         synchronized (this) {
9005             long ident = Binder.clearCallingIdentity();
9006             try {
9007                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9008                         + " to stackId=" + stackId + " toTop=" + toTop);
9009                 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
9010             } finally {
9011                 Binder.restoreCallingIdentity(ident);
9012             }
9013         }
9014     }
9015
9016     @Override
9017     public void resizeStack(int stackId, Rect bounds) {
9018         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9019                 "resizeStack()");
9020         long ident = Binder.clearCallingIdentity();
9021         try {
9022             synchronized (this) {
9023                 mStackSupervisor.resizeStackLocked(stackId, bounds);
9024             }
9025         } finally {
9026             Binder.restoreCallingIdentity(ident);
9027         }
9028     }
9029
9030     @Override
9031     public List<StackInfo> getAllStackInfos() {
9032         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9033                 "getAllStackInfos()");
9034         long ident = Binder.clearCallingIdentity();
9035         try {
9036             synchronized (this) {
9037                 return mStackSupervisor.getAllStackInfosLocked();
9038             }
9039         } finally {
9040             Binder.restoreCallingIdentity(ident);
9041         }
9042     }
9043
9044     @Override
9045     public StackInfo getStackInfo(int stackId) {
9046         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9047                 "getStackInfo()");
9048         long ident = Binder.clearCallingIdentity();
9049         try {
9050             synchronized (this) {
9051                 return mStackSupervisor.getStackInfoLocked(stackId);
9052             }
9053         } finally {
9054             Binder.restoreCallingIdentity(ident);
9055         }
9056     }
9057
9058     @Override
9059     public boolean isInHomeStack(int taskId) {
9060         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9061                 "getStackInfo()");
9062         long ident = Binder.clearCallingIdentity();
9063         try {
9064             synchronized (this) {
9065                 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
9066                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
9067             }
9068         } finally {
9069             Binder.restoreCallingIdentity(ident);
9070         }
9071     }
9072
9073     @Override
9074     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9075         synchronized(this) {
9076             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9077         }
9078     }
9079
9080     @Override
9081     public void updateDeviceOwner(String packageName) {
9082         final int callingUid = Binder.getCallingUid();
9083         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9084             throw new SecurityException("updateDeviceOwner called from non-system process");
9085         }
9086         synchronized (this) {
9087             mDeviceOwnerName = packageName;
9088         }
9089     }
9090
9091     @Override
9092     public void updateLockTaskPackages(int userId, String[] packages) {
9093         final int callingUid = Binder.getCallingUid();
9094         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9095             throw new SecurityException("updateLockTaskPackage called from non-system process");
9096         }
9097         synchronized (this) {
9098             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9099                     Arrays.toString(packages));
9100             mLockTaskPackages.put(userId, packages);
9101             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9102         }
9103     }
9104
9105
9106     void startLockTaskModeLocked(TaskRecord task) {
9107         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9108         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9109             return;
9110         }
9111
9112         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9113         // is initiated by system after the pinning request was shown and locked mode is initiated
9114         // by an authorized app directly
9115         final int callingUid = Binder.getCallingUid();
9116         boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9117         long ident = Binder.clearCallingIdentity();
9118         try {
9119             final ActivityStack stack = mStackSupervisor.getFocusedStack();
9120             if (!isSystemInitiated) {
9121                 task.mLockTaskUid = callingUid;
9122                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9123                     // startLockTask() called by app and task mode is lockTaskModeDefault.
9124                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9125                     StatusBarManagerInternal statusBarManager =
9126                             LocalServices.getService(StatusBarManagerInternal.class);
9127                     if (statusBarManager != null) {
9128                         statusBarManager.showScreenPinningRequest();
9129                     }
9130                     return;
9131                 }
9132
9133                 if (stack == null || task != stack.topTask()) {
9134                     throw new IllegalArgumentException("Invalid task, not in foreground");
9135                 }
9136             }
9137             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9138                     "Locking fully");
9139             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9140                     ActivityManager.LOCK_TASK_MODE_PINNED :
9141                     ActivityManager.LOCK_TASK_MODE_LOCKED,
9142                     "startLockTask", true);
9143         } finally {
9144             Binder.restoreCallingIdentity(ident);
9145         }
9146     }
9147
9148     @Override
9149     public void startLockTaskMode(int taskId) {
9150         synchronized (this) {
9151             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9152             if (task != null) {
9153                 startLockTaskModeLocked(task);
9154             }
9155         }
9156     }
9157
9158     @Override
9159     public void startLockTaskMode(IBinder token) {
9160         synchronized (this) {
9161             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9162             if (r == null) {
9163                 return;
9164             }
9165             final TaskRecord task = r.task;
9166             if (task != null) {
9167                 startLockTaskModeLocked(task);
9168             }
9169         }
9170     }
9171
9172     @Override
9173     public void startLockTaskModeOnCurrent() throws RemoteException {
9174         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9175                 "startLockTaskModeOnCurrent");
9176         long ident = Binder.clearCallingIdentity();
9177         try {
9178             synchronized (this) {
9179                 ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9180                 if (r != null) {
9181                     startLockTaskModeLocked(r.task);
9182                 }
9183             }
9184         } finally {
9185             Binder.restoreCallingIdentity(ident);
9186         }
9187     }
9188
9189     @Override
9190     public void stopLockTaskMode() {
9191         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9192         if (lockTask == null) {
9193             // Our work here is done.
9194             return;
9195         }
9196
9197         final int callingUid = Binder.getCallingUid();
9198         final int lockTaskUid = lockTask.mLockTaskUid;
9199         // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9200         // It is possible lockTaskMode was started by the system process because
9201         // android:lockTaskMode is set to a locking value in the application manifest instead of
9202         // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9203         // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9204         if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9205                 callingUid != lockTaskUid
9206                 && (lockTaskUid != 0
9207                     || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9208             throw new SecurityException("Invalid uid, expected " + lockTaskUid
9209                     + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9210         }
9211
9212         long ident = Binder.clearCallingIdentity();
9213         try {
9214             Log.d(TAG, "stopLockTaskMode");
9215             // Stop lock task
9216             synchronized (this) {
9217                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9218                         "stopLockTask", true);
9219             }
9220             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
9221             if (tm != null) {
9222                 tm.showInCallScreen(false);
9223             }
9224         } finally {
9225             Binder.restoreCallingIdentity(ident);
9226         }
9227     }
9228
9229     @Override
9230     public void stopLockTaskModeOnCurrent() throws RemoteException {
9231         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9232                 "stopLockTaskModeOnCurrent");
9233         long ident = Binder.clearCallingIdentity();
9234         try {
9235             stopLockTaskMode();
9236         } finally {
9237             Binder.restoreCallingIdentity(ident);
9238         }
9239     }
9240
9241     @Override
9242     public boolean isInLockTaskMode() {
9243         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9244     }
9245
9246     @Override
9247     public int getLockTaskModeState() {
9248         synchronized (this) {
9249             return mStackSupervisor.getLockTaskModeState();
9250         }
9251     }
9252
9253     @Override
9254     public void showLockTaskEscapeMessage(IBinder token) {
9255         synchronized (this) {
9256             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9257             if (r == null) {
9258                 return;
9259             }
9260             mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9261         }
9262     }
9263
9264     // =========================================================
9265     // CONTENT PROVIDERS
9266     // =========================================================
9267
9268     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9269         List<ProviderInfo> providers = null;
9270         try {
9271             ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
9272                 queryContentProviders(app.processName, app.uid,
9273                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9274             providers = slice != null ? slice.getList() : null;
9275         } catch (RemoteException ex) {
9276         }
9277         if (DEBUG_MU) Slog.v(TAG_MU,
9278                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9279         int userId = app.userId;
9280         if (providers != null) {
9281             int N = providers.size();
9282             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9283             for (int i=0; i<N; i++) {
9284                 ProviderInfo cpi =
9285                     (ProviderInfo)providers.get(i);
9286                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9287                         cpi.name, cpi.flags);
9288                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9289                     // This is a singleton provider, but a user besides the
9290                     // default user is asking to initialize a process it runs
9291                     // in...  well, no, it doesn't actually run in this process,
9292                     // it runs in the process of the default user.  Get rid of it.
9293                     providers.remove(i);
9294                     N--;
9295                     i--;
9296                     continue;
9297                 }
9298
9299                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9300                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9301                 if (cpr == null) {
9302                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9303                     mProviderMap.putProviderByClass(comp, cpr);
9304                 }
9305                 if (DEBUG_MU) Slog.v(TAG_MU,
9306                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9307                 app.pubProviders.put(cpi.name, cpr);
9308                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9309                     // Don't add this if it is a platform component that is marked
9310                     // to run in multiple processes, because this is actually
9311                     // part of the framework so doesn't make sense to track as a
9312                     // separate apk in the process.
9313                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9314                             mProcessStats);
9315                 }
9316                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
9317             }
9318         }
9319         return providers;
9320     }
9321
9322     /**
9323      * Check if the calling UID has a possible chance at accessing the provider
9324      * at the given authority and user.
9325      */
9326     public String checkContentProviderAccess(String authority, int userId) {
9327         if (userId == UserHandle.USER_ALL) {
9328             mContext.enforceCallingOrSelfPermission(
9329                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
9330             userId = UserHandle.getCallingUserId();
9331         }
9332
9333         ProviderInfo cpi = null;
9334         try {
9335             cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
9336                     STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9337         } catch (RemoteException ignored) {
9338         }
9339         if (cpi == null) {
9340             // TODO: make this an outright failure in a future platform release;
9341             // until then anonymous content notifications are unprotected
9342             //return "Failed to find provider " + authority + " for user " + userId;
9343             return null;
9344         }
9345
9346         ProcessRecord r = null;
9347         synchronized (mPidsSelfLocked) {
9348             r = mPidsSelfLocked.get(Binder.getCallingPid());
9349         }
9350         if (r == null) {
9351             return "Failed to find PID " + Binder.getCallingPid();
9352         }
9353
9354         synchronized (this) {
9355             return checkContentProviderPermissionLocked(cpi, r, userId, true);
9356         }
9357     }
9358
9359     /**
9360      * Check if {@link ProcessRecord} has a possible chance at accessing the
9361      * given {@link ProviderInfo}. Final permission checking is always done
9362      * in {@link ContentProvider}.
9363      */
9364     private final String checkContentProviderPermissionLocked(
9365             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9366         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9367         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9368         boolean checkedGrants = false;
9369         if (checkUser) {
9370             // Looking for cross-user grants before enforcing the typical cross-users permissions
9371             int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9372             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9373                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9374                     return null;
9375                 }
9376                 checkedGrants = true;
9377             }
9378             userId = handleIncomingUser(callingPid, callingUid, userId,
9379                     false, ALLOW_NON_FULL,
9380                     "checkContentProviderPermissionLocked " + cpi.authority, null);
9381             if (userId != tmpTargetUserId) {
9382                 // When we actually went to determine the final targer user ID, this ended
9383                 // up different than our initial check for the authority.  This is because
9384                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9385                 // SELF.  So we need to re-check the grants again.
9386                 checkedGrants = false;
9387             }
9388         }
9389         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9390                 cpi.applicationInfo.uid, cpi.exported)
9391                 == PackageManager.PERMISSION_GRANTED) {
9392             return null;
9393         }
9394         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9395                 cpi.applicationInfo.uid, cpi.exported)
9396                 == PackageManager.PERMISSION_GRANTED) {
9397             return null;
9398         }
9399
9400         PathPermission[] pps = cpi.pathPermissions;
9401         if (pps != null) {
9402             int i = pps.length;
9403             while (i > 0) {
9404                 i--;
9405                 PathPermission pp = pps[i];
9406                 String pprperm = pp.getReadPermission();
9407                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9408                         cpi.applicationInfo.uid, cpi.exported)
9409                         == PackageManager.PERMISSION_GRANTED) {
9410                     return null;
9411                 }
9412                 String ppwperm = pp.getWritePermission();
9413                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9414                         cpi.applicationInfo.uid, cpi.exported)
9415                         == PackageManager.PERMISSION_GRANTED) {
9416                     return null;
9417                 }
9418             }
9419         }
9420         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9421             return null;
9422         }
9423
9424         String msg;
9425         if (!cpi.exported) {
9426             msg = "Permission Denial: opening provider " + cpi.name
9427                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9428                     + ", uid=" + callingUid + ") that is not exported from uid "
9429                     + cpi.applicationInfo.uid;
9430         } else {
9431             msg = "Permission Denial: opening provider " + cpi.name
9432                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9433                     + ", uid=" + callingUid + ") requires "
9434                     + cpi.readPermission + " or " + cpi.writePermission;
9435         }
9436         Slog.w(TAG, msg);
9437         return msg;
9438     }
9439
9440     /**
9441      * Returns if the ContentProvider has granted a uri to callingUid
9442      */
9443     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9444         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9445         if (perms != null) {
9446             for (int i=perms.size()-1; i>=0; i--) {
9447                 GrantUri grantUri = perms.keyAt(i);
9448                 if (grantUri.sourceUserId == userId || !checkUser) {
9449                     if (matchesProvider(grantUri.uri, cpi)) {
9450                         return true;
9451                     }
9452                 }
9453             }
9454         }
9455         return false;
9456     }
9457
9458     /**
9459      * Returns true if the uri authority is one of the authorities specified in the provider.
9460      */
9461     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9462         String uriAuth = uri.getAuthority();
9463         String cpiAuth = cpi.authority;
9464         if (cpiAuth.indexOf(';') == -1) {
9465             return cpiAuth.equals(uriAuth);
9466         }
9467         String[] cpiAuths = cpiAuth.split(";");
9468         int length = cpiAuths.length;
9469         for (int i = 0; i < length; i++) {
9470             if (cpiAuths[i].equals(uriAuth)) return true;
9471         }
9472         return false;
9473     }
9474
9475     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9476             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9477         if (r != null) {
9478             for (int i=0; i<r.conProviders.size(); i++) {
9479                 ContentProviderConnection conn = r.conProviders.get(i);
9480                 if (conn.provider == cpr) {
9481                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9482                             "Adding provider requested by "
9483                             + r.processName + " from process "
9484                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9485                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9486                     if (stable) {
9487                         conn.stableCount++;
9488                         conn.numStableIncs++;
9489                     } else {
9490                         conn.unstableCount++;
9491                         conn.numUnstableIncs++;
9492                     }
9493                     return conn;
9494                 }
9495             }
9496             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9497             if (stable) {
9498                 conn.stableCount = 1;
9499                 conn.numStableIncs = 1;
9500             } else {
9501                 conn.unstableCount = 1;
9502                 conn.numUnstableIncs = 1;
9503             }
9504             cpr.connections.add(conn);
9505             r.conProviders.add(conn);
9506             startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9507             return conn;
9508         }
9509         cpr.addExternalProcessHandleLocked(externalProcessToken);
9510         return null;
9511     }
9512
9513     boolean decProviderCountLocked(ContentProviderConnection conn,
9514             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9515         if (conn != null) {
9516             cpr = conn.provider;
9517             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9518                     "Removing provider requested by "
9519                     + conn.client.processName + " from process "
9520                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9521                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9522             if (stable) {
9523                 conn.stableCount--;
9524             } else {
9525                 conn.unstableCount--;
9526             }
9527             if (conn.stableCount == 0 && conn.unstableCount == 0) {
9528                 cpr.connections.remove(conn);
9529                 conn.client.conProviders.remove(conn);
9530                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
9531                     // The client is more important than last activity -- note the time this
9532                     // is happening, so we keep the old provider process around a bit as last
9533                     // activity to avoid thrashing it.
9534                     if (cpr.proc != null) {
9535                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
9536                     }
9537                 }
9538                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9539                 return true;
9540             }
9541             return false;
9542         }
9543         cpr.removeExternalProcessHandleLocked(externalProcessToken);
9544         return false;
9545     }
9546
9547     private void checkTime(long startTime, String where) {
9548         long now = SystemClock.elapsedRealtime();
9549         if ((now-startTime) > 1000) {
9550             // If we are taking more than a second, log about it.
9551             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9552         }
9553     }
9554
9555     private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9556             String name, IBinder token, boolean stable, int userId) {
9557         ContentProviderRecord cpr;
9558         ContentProviderConnection conn = null;
9559         ProviderInfo cpi = null;
9560
9561         synchronized(this) {
9562             long startTime = SystemClock.elapsedRealtime();
9563
9564             ProcessRecord r = null;
9565             if (caller != null) {
9566                 r = getRecordForAppLocked(caller);
9567                 if (r == null) {
9568                     throw new SecurityException(
9569                             "Unable to find app for caller " + caller
9570                           + " (pid=" + Binder.getCallingPid()
9571                           + ") when getting content provider " + name);
9572                 }
9573             }
9574
9575             boolean checkCrossUser = true;
9576
9577             checkTime(startTime, "getContentProviderImpl: getProviderByName");
9578
9579             // First check if this content provider has been published...
9580             cpr = mProviderMap.getProviderByName(name, userId);
9581             // If that didn't work, check if it exists for user 0 and then
9582             // verify that it's a singleton provider before using it.
9583             if (cpr == null && userId != UserHandle.USER_OWNER) {
9584                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9585                 if (cpr != null) {
9586                     cpi = cpr.info;
9587                     if (isSingleton(cpi.processName, cpi.applicationInfo,
9588                             cpi.name, cpi.flags)
9589                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9590                         userId = UserHandle.USER_OWNER;
9591                         checkCrossUser = false;
9592                     } else {
9593                         cpr = null;
9594                         cpi = null;
9595                     }
9596                 }
9597             }
9598
9599             boolean providerRunning = cpr != null;
9600             if (providerRunning) {
9601                 cpi = cpr.info;
9602                 String msg;
9603                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9604                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9605                         != null) {
9606                     throw new SecurityException(msg);
9607                 }
9608                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9609
9610                 if (r != null && cpr.canRunHere(r)) {
9611                     // This provider has been published or is in the process
9612                     // of being published...  but it is also allowed to run
9613                     // in the caller's process, so don't make a connection
9614                     // and just let the caller instantiate its own instance.
9615                     ContentProviderHolder holder = cpr.newHolder(null);
9616                     // don't give caller the provider object, it needs
9617                     // to make its own.
9618                     holder.provider = null;
9619                     return holder;
9620                 }
9621
9622                 final long origId = Binder.clearCallingIdentity();
9623
9624                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9625
9626                 // In this case the provider instance already exists, so we can
9627                 // return it right away.
9628                 conn = incProviderCountLocked(r, cpr, token, stable);
9629                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9630                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9631                         // If this is a perceptible app accessing the provider,
9632                         // make sure to count it as being accessed and thus
9633                         // back up on the LRU list.  This is good because
9634                         // content providers are often expensive to start.
9635                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9636                         updateLruProcessLocked(cpr.proc, false, null);
9637                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9638                     }
9639                 }
9640
9641                 if (cpr.proc != null) {
9642                     if (false) {
9643                         if (cpr.name.flattenToShortString().equals(
9644                                 "com.android.providers.calendar/.CalendarProvider2")) {
9645                             Slog.v(TAG, "****************** KILLING "
9646                                 + cpr.name.flattenToShortString());
9647                             Process.killProcess(cpr.proc.pid);
9648                         }
9649                     }
9650                     checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9651                     boolean success = updateOomAdjLocked(cpr.proc);
9652                     maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9653                     checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9654                     if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9655                     // NOTE: there is still a race here where a signal could be
9656                     // pending on the process even though we managed to update its
9657                     // adj level.  Not sure what to do about this, but at least
9658                     // the race is now smaller.
9659                     if (!success) {
9660                         // Uh oh...  it looks like the provider's process
9661                         // has been killed on us.  We need to wait for a new
9662                         // process to be started, and make sure its death
9663                         // doesn't kill our process.
9664                         Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9665                                 + " is crashing; detaching " + r);
9666                         boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9667                         checkTime(startTime, "getContentProviderImpl: before appDied");
9668                         appDiedLocked(cpr.proc);
9669                         checkTime(startTime, "getContentProviderImpl: after appDied");
9670                         if (!lastRef) {
9671                             // This wasn't the last ref our process had on
9672                             // the provider...  we have now been killed, bail.
9673                             return null;
9674                         }
9675                         providerRunning = false;
9676                         conn = null;
9677                     }
9678                 }
9679
9680                 Binder.restoreCallingIdentity(origId);
9681             }
9682
9683             boolean singleton;
9684             if (!providerRunning) {
9685                 try {
9686                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9687                     cpi = AppGlobals.getPackageManager().
9688                         resolveContentProvider(name,
9689                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9690                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9691                 } catch (RemoteException ex) {
9692                 }
9693                 if (cpi == null) {
9694                     return null;
9695                 }
9696                 // If the provider is a singleton AND
9697                 // (it's a call within the same user || the provider is a
9698                 // privileged app)
9699                 // Then allow connecting to the singleton provider
9700                 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9701                         cpi.name, cpi.flags)
9702                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9703                 if (singleton) {
9704                     userId = UserHandle.USER_OWNER;
9705                 }
9706                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9707                 checkTime(startTime, "getContentProviderImpl: got app info for user");
9708
9709                 String msg;
9710                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9711                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9712                         != null) {
9713                     throw new SecurityException(msg);
9714                 }
9715                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9716
9717                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9718                         && !cpi.processName.equals("system")) {
9719                     // If this content provider does not run in the system
9720                     // process, and the system is not yet ready to run other
9721                     // processes, then fail fast instead of hanging.
9722                     throw new IllegalArgumentException(
9723                             "Attempt to launch content provider before system ready");
9724                 }
9725
9726                 // Make sure that the user who owns this provider is running.  If not,
9727                 // we don't want to allow it to run.
9728                 if (!isUserRunningLocked(userId, false)) {
9729                     Slog.w(TAG, "Unable to launch app "
9730                             + cpi.applicationInfo.packageName + "/"
9731                             + cpi.applicationInfo.uid + " for provider "
9732                             + name + ": user " + userId + " is stopped");
9733                     return null;
9734                 }
9735
9736                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9737                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9738                 cpr = mProviderMap.getProviderByClass(comp, userId);
9739                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9740                 final boolean firstClass = cpr == null;
9741                 if (firstClass) {
9742                     final long ident = Binder.clearCallingIdentity();
9743                     try {
9744                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9745                         ApplicationInfo ai =
9746                             AppGlobals.getPackageManager().
9747                                 getApplicationInfo(
9748                                         cpi.applicationInfo.packageName,
9749                                         STOCK_PM_FLAGS, userId);
9750                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9751                         if (ai == null) {
9752                             Slog.w(TAG, "No package info for content provider "
9753                                     + cpi.name);
9754                             return null;
9755                         }
9756                         ai = getAppInfoForUser(ai, userId);
9757                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9758                     } catch (RemoteException ex) {
9759                         // pm is in same process, this will never happen.
9760                     } finally {
9761                         Binder.restoreCallingIdentity(ident);
9762                     }
9763                 }
9764
9765                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9766
9767                 if (r != null && cpr.canRunHere(r)) {
9768                     // If this is a multiprocess provider, then just return its
9769                     // info and allow the caller to instantiate it.  Only do
9770                     // this if the provider is the same user as the caller's
9771                     // process, or can run as root (so can be in any process).
9772                     return cpr.newHolder(null);
9773                 }
9774
9775                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9776                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9777                             + cpr.info.name + " callers=" + Debug.getCallers(6));
9778
9779                 // This is single process, and our app is now connecting to it.
9780                 // See if we are already in the process of launching this
9781                 // provider.
9782                 final int N = mLaunchingProviders.size();
9783                 int i;
9784                 for (i = 0; i < N; i++) {
9785                     if (mLaunchingProviders.get(i) == cpr) {
9786                         break;
9787                     }
9788                 }
9789
9790                 // If the provider is not already being launched, then get it
9791                 // started.
9792                 if (i >= N) {
9793                     final long origId = Binder.clearCallingIdentity();
9794
9795                     try {
9796                         // Content provider is now in use, its package can't be stopped.
9797                         try {
9798                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
9799                             AppGlobals.getPackageManager().setPackageStoppedState(
9800                                     cpr.appInfo.packageName, false, userId);
9801                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
9802                         } catch (RemoteException e) {
9803                         } catch (IllegalArgumentException e) {
9804                             Slog.w(TAG, "Failed trying to unstop package "
9805                                     + cpr.appInfo.packageName + ": " + e);
9806                         }
9807
9808                         // Use existing process if already started
9809                         checkTime(startTime, "getContentProviderImpl: looking for process record");
9810                         ProcessRecord proc = getProcessRecordLocked(
9811                                 cpi.processName, cpr.appInfo.uid, false);
9812                         if (proc != null && proc.thread != null) {
9813                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9814                                     "Installing in existing process " + proc);
9815                             if (!proc.pubProviders.containsKey(cpi.name)) {
9816                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
9817                                 proc.pubProviders.put(cpi.name, cpr);
9818                                 try {
9819                                     proc.thread.scheduleInstallProvider(cpi);
9820                                 } catch (RemoteException e) {
9821                                 }
9822                             }
9823                         } else {
9824                             checkTime(startTime, "getContentProviderImpl: before start process");
9825                             proc = startProcessLocked(cpi.processName,
9826                                     cpr.appInfo, false, 0, "content provider",
9827                                     new ComponentName(cpi.applicationInfo.packageName,
9828                                             cpi.name), false, false, false);
9829                             checkTime(startTime, "getContentProviderImpl: after start process");
9830                             if (proc == null) {
9831                                 Slog.w(TAG, "Unable to launch app "
9832                                         + cpi.applicationInfo.packageName + "/"
9833                                         + cpi.applicationInfo.uid + " for provider "
9834                                         + name + ": process is bad");
9835                                 return null;
9836                             }
9837                         }
9838                         cpr.launchingApp = proc;
9839                         mLaunchingProviders.add(cpr);
9840                     } finally {
9841                         Binder.restoreCallingIdentity(origId);
9842                     }
9843                 }
9844
9845                 checkTime(startTime, "getContentProviderImpl: updating data structures");
9846
9847                 // Make sure the provider is published (the same provider class
9848                 // may be published under multiple names).
9849                 if (firstClass) {
9850                     mProviderMap.putProviderByClass(comp, cpr);
9851                 }
9852
9853                 mProviderMap.putProviderByName(name, cpr);
9854                 conn = incProviderCountLocked(r, cpr, token, stable);
9855                 if (conn != null) {
9856                     conn.waiting = true;
9857                 }
9858             }
9859             checkTime(startTime, "getContentProviderImpl: done!");
9860         }
9861
9862         // Wait for the provider to be published...
9863         synchronized (cpr) {
9864             while (cpr.provider == null) {
9865                 if (cpr.launchingApp == null) {
9866                     Slog.w(TAG, "Unable to launch app "
9867                             + cpi.applicationInfo.packageName + "/"
9868                             + cpi.applicationInfo.uid + " for provider "
9869                             + name + ": launching app became null");
9870                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9871                             UserHandle.getUserId(cpi.applicationInfo.uid),
9872                             cpi.applicationInfo.packageName,
9873                             cpi.applicationInfo.uid, name);
9874                     return null;
9875                 }
9876                 try {
9877                     if (DEBUG_MU) Slog.v(TAG_MU,
9878                             "Waiting to start provider " + cpr
9879                             + " launchingApp=" + cpr.launchingApp);
9880                     if (conn != null) {
9881                         conn.waiting = true;
9882                     }
9883                     cpr.wait();
9884                 } catch (InterruptedException ex) {
9885                 } finally {
9886                     if (conn != null) {
9887                         conn.waiting = false;
9888                     }
9889                 }
9890             }
9891         }
9892         return cpr != null ? cpr.newHolder(conn) : null;
9893     }
9894
9895     @Override
9896     public final ContentProviderHolder getContentProvider(
9897             IApplicationThread caller, String name, int userId, boolean stable) {
9898         enforceNotIsolatedCaller("getContentProvider");
9899         if (caller == null) {
9900             String msg = "null IApplicationThread when getting content provider "
9901                     + name;
9902             Slog.w(TAG, msg);
9903             throw new SecurityException(msg);
9904         }
9905         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9906         // with cross-user grant.
9907         return getContentProviderImpl(caller, name, null, stable, userId);
9908     }
9909
9910     public ContentProviderHolder getContentProviderExternal(
9911             String name, int userId, IBinder token) {
9912         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9913             "Do not have permission in call getContentProviderExternal()");
9914         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9915                 false, ALLOW_FULL_ONLY, "getContentProvider", null);
9916         return getContentProviderExternalUnchecked(name, token, userId);
9917     }
9918
9919     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9920             IBinder token, int userId) {
9921         return getContentProviderImpl(null, name, token, true, userId);
9922     }
9923
9924     /**
9925      * Drop a content provider from a ProcessRecord's bookkeeping
9926      */
9927     public void removeContentProvider(IBinder connection, boolean stable) {
9928         enforceNotIsolatedCaller("removeContentProvider");
9929         long ident = Binder.clearCallingIdentity();
9930         try {
9931             synchronized (this) {
9932                 ContentProviderConnection conn;
9933                 try {
9934                     conn = (ContentProviderConnection)connection;
9935                 } catch (ClassCastException e) {
9936                     String msg ="removeContentProvider: " + connection
9937                             + " not a ContentProviderConnection";
9938                     Slog.w(TAG, msg);
9939                     throw new IllegalArgumentException(msg);
9940                 }
9941                 if (conn == null) {
9942                     throw new NullPointerException("connection is null");
9943                 }
9944                 if (decProviderCountLocked(conn, null, null, stable)) {
9945                     updateOomAdjLocked();
9946                 }
9947             }
9948         } finally {
9949             Binder.restoreCallingIdentity(ident);
9950         }
9951     }
9952
9953     public void removeContentProviderExternal(String name, IBinder token) {
9954         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9955             "Do not have permission in call removeContentProviderExternal()");
9956         int userId = UserHandle.getCallingUserId();
9957         long ident = Binder.clearCallingIdentity();
9958         try {
9959             removeContentProviderExternalUnchecked(name, token, userId);
9960         } finally {
9961             Binder.restoreCallingIdentity(ident);
9962         }
9963     }
9964
9965     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9966         synchronized (this) {
9967             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9968             if(cpr == null) {
9969                 //remove from mProvidersByClass
9970                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9971                 return;
9972             }
9973
9974             //update content provider record entry info
9975             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9976             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9977             if (localCpr.hasExternalProcessHandles()) {
9978                 if (localCpr.removeExternalProcessHandleLocked(token)) {
9979                     updateOomAdjLocked();
9980                 } else {
9981                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9982                             + " with no external reference for token: "
9983                             + token + ".");
9984                 }
9985             } else {
9986                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9987                         + " with no external references.");
9988             }
9989         }
9990     }
9991
9992     public final void publishContentProviders(IApplicationThread caller,
9993             List<ContentProviderHolder> providers) {
9994         if (providers == null) {
9995             return;
9996         }
9997
9998         enforceNotIsolatedCaller("publishContentProviders");
9999         synchronized (this) {
10000             final ProcessRecord r = getRecordForAppLocked(caller);
10001             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10002             if (r == null) {
10003                 throw new SecurityException(
10004                         "Unable to find app for caller " + caller
10005                       + " (pid=" + Binder.getCallingPid()
10006                       + ") when publishing content providers");
10007             }
10008
10009             final long origId = Binder.clearCallingIdentity();
10010
10011             final int N = providers.size();
10012             for (int i = 0; i < N; i++) {
10013                 ContentProviderHolder src = providers.get(i);
10014                 if (src == null || src.info == null || src.provider == null) {
10015                     continue;
10016                 }
10017                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10018                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10019                 if (dst != null) {
10020                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10021                     mProviderMap.putProviderByClass(comp, dst);
10022                     String names[] = dst.info.authority.split(";");
10023                     for (int j = 0; j < names.length; j++) {
10024                         mProviderMap.putProviderByName(names[j], dst);
10025                     }
10026
10027                     int launchingCount = mLaunchingProviders.size();
10028                     int j;
10029                     boolean wasInLaunchingProviders = false;
10030                     for (j = 0; j < launchingCount; j++) {
10031                         if (mLaunchingProviders.get(j) == dst) {
10032                             mLaunchingProviders.remove(j);
10033                             wasInLaunchingProviders = true;
10034                             j--;
10035                             launchingCount--;
10036                         }
10037                     }
10038                     if (wasInLaunchingProviders) {
10039                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10040                     }
10041                     synchronized (dst) {
10042                         dst.provider = src.provider;
10043                         dst.proc = r;
10044                         dst.notifyAll();
10045                     }
10046                     updateOomAdjLocked(r);
10047                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10048                             src.info.authority);
10049                 }
10050             }
10051
10052             Binder.restoreCallingIdentity(origId);
10053         }
10054     }
10055
10056     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10057         ContentProviderConnection conn;
10058         try {
10059             conn = (ContentProviderConnection)connection;
10060         } catch (ClassCastException e) {
10061             String msg ="refContentProvider: " + connection
10062                     + " not a ContentProviderConnection";
10063             Slog.w(TAG, msg);
10064             throw new IllegalArgumentException(msg);
10065         }
10066         if (conn == null) {
10067             throw new NullPointerException("connection is null");
10068         }
10069
10070         synchronized (this) {
10071             if (stable > 0) {
10072                 conn.numStableIncs += stable;
10073             }
10074             stable = conn.stableCount + stable;
10075             if (stable < 0) {
10076                 throw new IllegalStateException("stableCount < 0: " + stable);
10077             }
10078
10079             if (unstable > 0) {
10080                 conn.numUnstableIncs += unstable;
10081             }
10082             unstable = conn.unstableCount + unstable;
10083             if (unstable < 0) {
10084                 throw new IllegalStateException("unstableCount < 0: " + unstable);
10085             }
10086
10087             if ((stable+unstable) <= 0) {
10088                 throw new IllegalStateException("ref counts can't go to zero here: stable="
10089                         + stable + " unstable=" + unstable);
10090             }
10091             conn.stableCount = stable;
10092             conn.unstableCount = unstable;
10093             return !conn.dead;
10094         }
10095     }
10096
10097     public void unstableProviderDied(IBinder connection) {
10098         ContentProviderConnection conn;
10099         try {
10100             conn = (ContentProviderConnection)connection;
10101         } catch (ClassCastException e) {
10102             String msg ="refContentProvider: " + connection
10103                     + " not a ContentProviderConnection";
10104             Slog.w(TAG, msg);
10105             throw new IllegalArgumentException(msg);
10106         }
10107         if (conn == null) {
10108             throw new NullPointerException("connection is null");
10109         }
10110
10111         // Safely retrieve the content provider associated with the connection.
10112         IContentProvider provider;
10113         synchronized (this) {
10114             provider = conn.provider.provider;
10115         }
10116
10117         if (provider == null) {
10118             // Um, yeah, we're way ahead of you.
10119             return;
10120         }
10121
10122         // Make sure the caller is being honest with us.
10123         if (provider.asBinder().pingBinder()) {
10124             // Er, no, still looks good to us.
10125             synchronized (this) {
10126                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10127                         + " says " + conn + " died, but we don't agree");
10128                 return;
10129             }
10130         }
10131
10132         // Well look at that!  It's dead!
10133         synchronized (this) {
10134             if (conn.provider.provider != provider) {
10135                 // But something changed...  good enough.
10136                 return;
10137             }
10138
10139             ProcessRecord proc = conn.provider.proc;
10140             if (proc == null || proc.thread == null) {
10141                 // Seems like the process is already cleaned up.
10142                 return;
10143             }
10144
10145             // As far as we're concerned, this is just like receiving a
10146             // death notification...  just a bit prematurely.
10147             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10148                     + ") early provider death");
10149             final long ident = Binder.clearCallingIdentity();
10150             try {
10151                 appDiedLocked(proc);
10152             } finally {
10153                 Binder.restoreCallingIdentity(ident);
10154             }
10155         }
10156     }
10157
10158     @Override
10159     public void appNotRespondingViaProvider(IBinder connection) {
10160         enforceCallingPermission(
10161                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10162
10163         final ContentProviderConnection conn = (ContentProviderConnection) connection;
10164         if (conn == null) {
10165             Slog.w(TAG, "ContentProviderConnection is null");
10166             return;
10167         }
10168
10169         final ProcessRecord host = conn.provider.proc;
10170         if (host == null) {
10171             Slog.w(TAG, "Failed to find hosting ProcessRecord");
10172             return;
10173         }
10174
10175         final long token = Binder.clearCallingIdentity();
10176         try {
10177             appNotResponding(host, null, null, false, "ContentProvider not responding");
10178         } finally {
10179             Binder.restoreCallingIdentity(token);
10180         }
10181     }
10182
10183     public final void installSystemProviders() {
10184         List<ProviderInfo> providers;
10185         synchronized (this) {
10186             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10187             providers = generateApplicationProvidersLocked(app);
10188             if (providers != null) {
10189                 for (int i=providers.size()-1; i>=0; i--) {
10190                     ProviderInfo pi = (ProviderInfo)providers.get(i);
10191                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10192                         Slog.w(TAG, "Not installing system proc provider " + pi.name
10193                                 + ": not system .apk");
10194                         providers.remove(i);
10195                     }
10196                 }
10197             }
10198         }
10199         if (providers != null) {
10200             mSystemThread.installSystemProviders(providers);
10201         }
10202
10203         mCoreSettingsObserver = new CoreSettingsObserver(this);
10204
10205         //mUsageStatsService.monitorPackages();
10206     }
10207
10208     /**
10209      * Allows apps to retrieve the MIME type of a URI.
10210      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10211      * users, then it does not need permission to access the ContentProvider.
10212      * Either, it needs cross-user uri grants.
10213      *
10214      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10215      *
10216      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10217      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10218      */
10219     public String getProviderMimeType(Uri uri, int userId) {
10220         enforceNotIsolatedCaller("getProviderMimeType");
10221         final String name = uri.getAuthority();
10222         int callingUid = Binder.getCallingUid();
10223         int callingPid = Binder.getCallingPid();
10224         long ident = 0;
10225         boolean clearedIdentity = false;
10226         userId = unsafeConvertIncomingUser(userId);
10227         if (canClearIdentity(callingPid, callingUid, userId)) {
10228             clearedIdentity = true;
10229             ident = Binder.clearCallingIdentity();
10230         }
10231         ContentProviderHolder holder = null;
10232         try {
10233             holder = getContentProviderExternalUnchecked(name, null, userId);
10234             if (holder != null) {
10235                 return holder.provider.getType(uri);
10236             }
10237         } catch (RemoteException e) {
10238             Log.w(TAG, "Content provider dead retrieving " + uri, e);
10239             return null;
10240         } finally {
10241             // We need to clear the identity to call removeContentProviderExternalUnchecked
10242             if (!clearedIdentity) {
10243                 ident = Binder.clearCallingIdentity();
10244             }
10245             try {
10246                 if (holder != null) {
10247                     removeContentProviderExternalUnchecked(name, null, userId);
10248                 }
10249             } finally {
10250                 Binder.restoreCallingIdentity(ident);
10251             }
10252         }
10253
10254         return null;
10255     }
10256
10257     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10258         if (UserHandle.getUserId(callingUid) == userId) {
10259             return true;
10260         }
10261         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10262                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10263                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10264                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10265                 return true;
10266         }
10267         return false;
10268     }
10269
10270     // =========================================================
10271     // GLOBAL MANAGEMENT
10272     // =========================================================
10273
10274     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10275             boolean isolated, int isolatedUid) {
10276         String proc = customProcess != null ? customProcess : info.processName;
10277         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10278         final int userId = UserHandle.getUserId(info.uid);
10279         int uid = info.uid;
10280         if (isolated) {
10281             if (isolatedUid == 0) {
10282                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10283                 while (true) {
10284                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10285                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10286                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10287                     }
10288                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10289                     mNextIsolatedProcessUid++;
10290                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10291                         // No process for this uid, use it.
10292                         break;
10293                     }
10294                     stepsLeft--;
10295                     if (stepsLeft <= 0) {
10296                         return null;
10297                     }
10298                 }
10299             } else {
10300                 // Special case for startIsolatedProcess (internal only), where
10301                 // the uid of the isolated process is specified by the caller.
10302                 uid = isolatedUid;
10303             }
10304         }
10305         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10306         if (!mBooted && !mBooting
10307                 && userId == UserHandle.USER_OWNER
10308                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10309             r.persistent = true;
10310         }
10311         addProcessNameLocked(r);
10312         return r;
10313     }
10314
10315     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10316             String abiOverride) {
10317         ProcessRecord app;
10318         if (!isolated) {
10319             app = getProcessRecordLocked(info.processName, info.uid, true);
10320         } else {
10321             app = null;
10322         }
10323
10324         if (app == null) {
10325             app = newProcessRecordLocked(info, null, isolated, 0);
10326             updateLruProcessLocked(app, false, null);
10327             updateOomAdjLocked();
10328         }
10329
10330         // This package really, really can not be stopped.
10331         try {
10332             AppGlobals.getPackageManager().setPackageStoppedState(
10333                     info.packageName, false, UserHandle.getUserId(app.uid));
10334         } catch (RemoteException e) {
10335         } catch (IllegalArgumentException e) {
10336             Slog.w(TAG, "Failed trying to unstop package "
10337                     + info.packageName + ": " + e);
10338         }
10339
10340         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10341             app.persistent = true;
10342             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10343         }
10344         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10345             mPersistentStartingProcesses.add(app);
10346             startProcessLocked(app, "added application", app.processName, abiOverride,
10347                     null /* entryPoint */, null /* entryPointArgs */);
10348         }
10349
10350         return app;
10351     }
10352
10353     public void unhandledBack() {
10354         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10355                 "unhandledBack()");
10356
10357         synchronized(this) {
10358             final long origId = Binder.clearCallingIdentity();
10359             try {
10360                 getFocusedStack().unhandledBackLocked();
10361             } finally {
10362                 Binder.restoreCallingIdentity(origId);
10363             }
10364         }
10365     }
10366
10367     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10368         enforceNotIsolatedCaller("openContentUri");
10369         final int userId = UserHandle.getCallingUserId();
10370         String name = uri.getAuthority();
10371         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10372         ParcelFileDescriptor pfd = null;
10373         if (cph != null) {
10374             // We record the binder invoker's uid in thread-local storage before
10375             // going to the content provider to open the file.  Later, in the code
10376             // that handles all permissions checks, we look for this uid and use
10377             // that rather than the Activity Manager's own uid.  The effect is that
10378             // we do the check against the caller's permissions even though it looks
10379             // to the content provider like the Activity Manager itself is making
10380             // the request.
10381             Binder token = new Binder();
10382             sCallerIdentity.set(new Identity(
10383                     token, Binder.getCallingPid(), Binder.getCallingUid()));
10384             try {
10385                 pfd = cph.provider.openFile(null, uri, "r", null, token);
10386             } catch (FileNotFoundException e) {
10387                 // do nothing; pfd will be returned null
10388             } finally {
10389                 // Ensure that whatever happens, we clean up the identity state
10390                 sCallerIdentity.remove();
10391                 // Ensure we're done with the provider.
10392                 removeContentProviderExternalUnchecked(name, null, userId);
10393             }
10394         } else {
10395             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10396         }
10397         return pfd;
10398     }
10399
10400     // Actually is sleeping or shutting down or whatever else in the future
10401     // is an inactive state.
10402     public boolean isSleepingOrShuttingDown() {
10403         return isSleeping() || mShuttingDown;
10404     }
10405
10406     public boolean isSleeping() {
10407         return mSleeping;
10408     }
10409
10410     void onWakefulnessChanged(int wakefulness) {
10411         synchronized(this) {
10412             mWakefulness = wakefulness;
10413             updateSleepIfNeededLocked();
10414         }
10415     }
10416
10417     void finishRunningVoiceLocked() {
10418         if (mRunningVoice != null) {
10419             mRunningVoice = null;
10420             mVoiceWakeLock.release();
10421             updateSleepIfNeededLocked();
10422         }
10423     }
10424
10425     void startTimeTrackingFocusedActivityLocked() {
10426         if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10427             mCurAppTimeTracker.start(mFocusedActivity.packageName);
10428         }
10429     }
10430
10431     void updateSleepIfNeededLocked() {
10432         if (mSleeping && !shouldSleepLocked()) {
10433             mSleeping = false;
10434             startTimeTrackingFocusedActivityLocked();
10435             mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10436             mStackSupervisor.comeOutOfSleepIfNeededLocked();
10437             updateOomAdjLocked();
10438         } else if (!mSleeping && shouldSleepLocked()) {
10439             mSleeping = true;
10440             if (mCurAppTimeTracker != null) {
10441                 mCurAppTimeTracker.stop();
10442             }
10443             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10444             mStackSupervisor.goingToSleepLocked();
10445             updateOomAdjLocked();
10446
10447             // Initialize the wake times of all processes.
10448             checkExcessivePowerUsageLocked(false);
10449             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10450             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10451             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10452         }
10453     }
10454
10455     private boolean shouldSleepLocked() {
10456         // Resume applications while running a voice interactor.
10457         if (mRunningVoice != null) {
10458             return false;
10459         }
10460
10461         // TODO: Transform the lock screen state into a sleep token instead.
10462         switch (mWakefulness) {
10463             case PowerManagerInternal.WAKEFULNESS_AWAKE:
10464             case PowerManagerInternal.WAKEFULNESS_DREAMING:
10465             case PowerManagerInternal.WAKEFULNESS_DOZING:
10466                 // Pause applications whenever the lock screen is shown or any sleep
10467                 // tokens have been acquired.
10468                 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10469             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10470             default:
10471                 // If we're asleep then pause applications unconditionally.
10472                 return true;
10473         }
10474     }
10475
10476     /** Pokes the task persister. */
10477     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10478         if (task != null && task.stack != null && task.stack.isHomeStack()) {
10479             // Never persist the home stack.
10480             return;
10481         }
10482         mTaskPersister.wakeup(task, flush);
10483     }
10484
10485     /** Notifies all listeners when the task stack has changed. */
10486     void notifyTaskStackChangedLocked() {
10487         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10488         Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10489         mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10490     }
10491
10492     @Override
10493     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10494         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10495     }
10496
10497     @Override
10498     public boolean shutdown(int timeout) {
10499         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10500                 != PackageManager.PERMISSION_GRANTED) {
10501             throw new SecurityException("Requires permission "
10502                     + android.Manifest.permission.SHUTDOWN);
10503         }
10504
10505         boolean timedout = false;
10506
10507         synchronized(this) {
10508             mShuttingDown = true;
10509             updateEventDispatchingLocked();
10510             timedout = mStackSupervisor.shutdownLocked(timeout);
10511         }
10512
10513         mAppOpsService.shutdown();
10514         if (mUsageStatsService != null) {
10515             mUsageStatsService.prepareShutdown();
10516         }
10517         mBatteryStatsService.shutdown();
10518         synchronized (this) {
10519             mProcessStats.shutdownLocked();
10520             notifyTaskPersisterLocked(null, true);
10521         }
10522
10523         return timedout;
10524     }
10525
10526     public final void activitySlept(IBinder token) {
10527         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10528
10529         final long origId = Binder.clearCallingIdentity();
10530
10531         synchronized (this) {
10532             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10533             if (r != null) {
10534                 mStackSupervisor.activitySleptLocked(r);
10535             }
10536         }
10537
10538         Binder.restoreCallingIdentity(origId);
10539     }
10540
10541     private String lockScreenShownToString() {
10542         switch (mLockScreenShown) {
10543             case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10544             case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10545             case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10546             default: return "Unknown=" + mLockScreenShown;
10547         }
10548     }
10549
10550     void logLockScreen(String msg) {
10551         if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10552                 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10553                 + PowerManagerInternal.wakefulnessToString(mWakefulness)
10554                 + " mSleeping=" + mSleeping);
10555     }
10556
10557     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10558         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10559         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10560             boolean wasRunningVoice = mRunningVoice != null;
10561             mRunningVoice = session;
10562             if (!wasRunningVoice) {
10563                 mVoiceWakeLock.acquire();
10564                 updateSleepIfNeededLocked();
10565             }
10566         }
10567     }
10568
10569     private void updateEventDispatchingLocked() {
10570         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10571     }
10572
10573     public void setLockScreenShown(boolean shown) {
10574         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10575                 != PackageManager.PERMISSION_GRANTED) {
10576             throw new SecurityException("Requires permission "
10577                     + android.Manifest.permission.DEVICE_POWER);
10578         }
10579
10580         synchronized(this) {
10581             long ident = Binder.clearCallingIdentity();
10582             try {
10583                 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10584                 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10585                 updateSleepIfNeededLocked();
10586             } finally {
10587                 Binder.restoreCallingIdentity(ident);
10588             }
10589         }
10590     }
10591
10592     @Override
10593     public void stopAppSwitches() {
10594         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10595                 != PackageManager.PERMISSION_GRANTED) {
10596             throw new SecurityException("Requires permission "
10597                     + android.Manifest.permission.STOP_APP_SWITCHES);
10598         }
10599
10600         synchronized(this) {
10601             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10602                     + APP_SWITCH_DELAY_TIME;
10603             mDidAppSwitch = false;
10604             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10605             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10606             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10607         }
10608     }
10609
10610     public void resumeAppSwitches() {
10611         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10612                 != PackageManager.PERMISSION_GRANTED) {
10613             throw new SecurityException("Requires permission "
10614                     + android.Manifest.permission.STOP_APP_SWITCHES);
10615         }
10616
10617         synchronized(this) {
10618             // Note that we don't execute any pending app switches... we will
10619             // let those wait until either the timeout, or the next start
10620             // activity request.
10621             mAppSwitchesAllowedTime = 0;
10622         }
10623     }
10624
10625     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10626             int callingPid, int callingUid, String name) {
10627         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10628             return true;
10629         }
10630
10631         int perm = checkComponentPermission(
10632                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10633                 sourceUid, -1, true);
10634         if (perm == PackageManager.PERMISSION_GRANTED) {
10635             return true;
10636         }
10637
10638         // If the actual IPC caller is different from the logical source, then
10639         // also see if they are allowed to control app switches.
10640         if (callingUid != -1 && callingUid != sourceUid) {
10641             perm = checkComponentPermission(
10642                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10643                     callingUid, -1, true);
10644             if (perm == PackageManager.PERMISSION_GRANTED) {
10645                 return true;
10646             }
10647         }
10648
10649         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10650         return false;
10651     }
10652
10653     public void setDebugApp(String packageName, boolean waitForDebugger,
10654             boolean persistent) {
10655         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10656                 "setDebugApp()");
10657
10658         long ident = Binder.clearCallingIdentity();
10659         try {
10660             // Note that this is not really thread safe if there are multiple
10661             // callers into it at the same time, but that's not a situation we
10662             // care about.
10663             if (persistent) {
10664                 final ContentResolver resolver = mContext.getContentResolver();
10665                 Settings.Global.putString(
10666                     resolver, Settings.Global.DEBUG_APP,
10667                     packageName);
10668                 Settings.Global.putInt(
10669                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10670                     waitForDebugger ? 1 : 0);
10671             }
10672
10673             synchronized (this) {
10674                 if (!persistent) {
10675                     mOrigDebugApp = mDebugApp;
10676                     mOrigWaitForDebugger = mWaitForDebugger;
10677                 }
10678                 mDebugApp = packageName;
10679                 mWaitForDebugger = waitForDebugger;
10680                 mDebugTransient = !persistent;
10681                 if (packageName != null) {
10682                     forceStopPackageLocked(packageName, -1, false, false, true, true,
10683                             false, UserHandle.USER_ALL, "set debug app");
10684                 }
10685             }
10686         } finally {
10687             Binder.restoreCallingIdentity(ident);
10688         }
10689     }
10690
10691     void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10692         synchronized (this) {
10693             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10694             if (!isDebuggable) {
10695                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10696                     throw new SecurityException("Process not debuggable: " + app.packageName);
10697                 }
10698             }
10699
10700             mOpenGlTraceApp = processName;
10701         }
10702     }
10703
10704     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10705         synchronized (this) {
10706             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10707             if (!isDebuggable) {
10708                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10709                     throw new SecurityException("Process not debuggable: " + app.packageName);
10710                 }
10711             }
10712             mProfileApp = processName;
10713             mProfileFile = profilerInfo.profileFile;
10714             if (mProfileFd != null) {
10715                 try {
10716                     mProfileFd.close();
10717                 } catch (IOException e) {
10718                 }
10719                 mProfileFd = null;
10720             }
10721             mProfileFd = profilerInfo.profileFd;
10722             mSamplingInterval = profilerInfo.samplingInterval;
10723             mAutoStopProfiler = profilerInfo.autoStopProfiler;
10724             mProfileType = 0;
10725         }
10726     }
10727
10728     @Override
10729     public void setAlwaysFinish(boolean enabled) {
10730         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10731                 "setAlwaysFinish()");
10732
10733         Settings.Global.putInt(
10734                 mContext.getContentResolver(),
10735                 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10736
10737         synchronized (this) {
10738             mAlwaysFinishActivities = enabled;
10739         }
10740     }
10741
10742     @Override
10743     public void setActivityController(IActivityController controller) {
10744         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10745                 "setActivityController()");
10746         synchronized (this) {
10747             mController = controller;
10748             Watchdog.getInstance().setActivityController(controller);
10749         }
10750     }
10751
10752     @Override
10753     public void setUserIsMonkey(boolean userIsMonkey) {
10754         synchronized (this) {
10755             synchronized (mPidsSelfLocked) {
10756                 final int callingPid = Binder.getCallingPid();
10757                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10758                 if (precessRecord == null) {
10759                     throw new SecurityException("Unknown process: " + callingPid);
10760                 }
10761                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
10762                     throw new SecurityException("Only an instrumentation process "
10763                             + "with a UiAutomation can call setUserIsMonkey");
10764                 }
10765             }
10766             mUserIsMonkey = userIsMonkey;
10767         }
10768     }
10769
10770     @Override
10771     public boolean isUserAMonkey() {
10772         synchronized (this) {
10773             // If there is a controller also implies the user is a monkey.
10774             return (mUserIsMonkey || mController != null);
10775         }
10776     }
10777
10778     public void requestBugReport() {
10779         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10780         SystemProperties.set("ctl.start", "bugreport");
10781     }
10782
10783     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10784         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10785     }
10786
10787     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10788         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10789             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10790         }
10791         return KEY_DISPATCHING_TIMEOUT;
10792     }
10793
10794     @Override
10795     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10796         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10797                 != PackageManager.PERMISSION_GRANTED) {
10798             throw new SecurityException("Requires permission "
10799                     + android.Manifest.permission.FILTER_EVENTS);
10800         }
10801         ProcessRecord proc;
10802         long timeout;
10803         synchronized (this) {
10804             synchronized (mPidsSelfLocked) {
10805                 proc = mPidsSelfLocked.get(pid);
10806             }
10807             timeout = getInputDispatchingTimeoutLocked(proc);
10808         }
10809
10810         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10811             return -1;
10812         }
10813
10814         return timeout;
10815     }
10816
10817     /**
10818      * Handle input dispatching timeouts.
10819      * Returns whether input dispatching should be aborted or not.
10820      */
10821     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10822             final ActivityRecord activity, final ActivityRecord parent,
10823             final boolean aboveSystem, String reason) {
10824         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10825                 != PackageManager.PERMISSION_GRANTED) {
10826             throw new SecurityException("Requires permission "
10827                     + android.Manifest.permission.FILTER_EVENTS);
10828         }
10829
10830         final String annotation;
10831         if (reason == null) {
10832             annotation = "Input dispatching timed out";
10833         } else {
10834             annotation = "Input dispatching timed out (" + reason + ")";
10835         }
10836
10837         if (proc != null) {
10838             synchronized (this) {
10839                 if (proc.debugging) {
10840                     return false;
10841                 }
10842
10843                 if (mDidDexOpt) {
10844                     // Give more time since we were dexopting.
10845                     mDidDexOpt = false;
10846                     return false;
10847                 }
10848
10849                 if (proc.instrumentationClass != null) {
10850                     Bundle info = new Bundle();
10851                     info.putString("shortMsg", "keyDispatchingTimedOut");
10852                     info.putString("longMsg", annotation);
10853                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10854                     return true;
10855                 }
10856             }
10857             mHandler.post(new Runnable() {
10858                 @Override
10859                 public void run() {
10860                     appNotResponding(proc, activity, parent, aboveSystem, annotation);
10861                 }
10862             });
10863         }
10864
10865         return true;
10866     }
10867
10868     @Override
10869     public Bundle getAssistContextExtras(int requestType) {
10870         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10871                 null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10872         if (pae == null) {
10873             return null;
10874         }
10875         synchronized (pae) {
10876             while (!pae.haveResult) {
10877                 try {
10878                     pae.wait();
10879                 } catch (InterruptedException e) {
10880                 }
10881             }
10882         }
10883         synchronized (this) {
10884             buildAssistBundleLocked(pae, pae.result);
10885             mPendingAssistExtras.remove(pae);
10886             mUiHandler.removeCallbacks(pae);
10887         }
10888         return pae.extras;
10889     }
10890
10891     @Override
10892     public boolean isAssistDataAllowedOnCurrentActivity() {
10893         int userId = mCurrentUserId;
10894         synchronized (this) {
10895             ActivityRecord activity = getFocusedStack().topActivity();
10896             if (activity == null) {
10897                 return false;
10898             }
10899             userId = activity.userId;
10900         }
10901         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
10902                 Context.DEVICE_POLICY_SERVICE);
10903         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
10904     }
10905
10906     @Override
10907     public boolean showAssistFromActivity(IBinder token, Bundle args) {
10908         long ident = Binder.clearCallingIdentity();
10909         try {
10910             synchronized (this) {
10911                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
10912                 ActivityRecord top = getFocusedStack().topActivity();
10913                 if (top != caller) {
10914                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10915                             + " is not current top " + top);
10916                     return false;
10917                 }
10918                 if (!top.nowVisible) {
10919                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10920                             + " is not visible");
10921                     return false;
10922                 }
10923             }
10924             AssistUtils utils = new AssistUtils(mContext);
10925             return utils.showSessionForActiveService(args,
10926                     VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
10927         } finally {
10928             Binder.restoreCallingIdentity(ident);
10929         }
10930     }
10931
10932     @Override
10933     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
10934             IBinder activityToken) {
10935         return enqueueAssistContext(requestType, null, null, receiver, activityToken,
10936                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
10937     }
10938
10939     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10940             IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
10941             long timeout) {
10942         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10943                 "enqueueAssistContext()");
10944         synchronized (this) {
10945             ActivityRecord activity = getFocusedStack().topActivity();
10946             if (activity == null) {
10947                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10948                 return null;
10949             }
10950             if (activity.app == null || activity.app.thread == null) {
10951                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10952                 return null;
10953             }
10954             if (activityToken != null) {
10955                 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
10956                 if (activity != caller) {
10957                     Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
10958                             + " is not current top " + activity);
10959                     return null;
10960                 }
10961             }
10962             PendingAssistExtras pae;
10963             Bundle extras = new Bundle();
10964             if (args != null) {
10965                 extras.putAll(args);
10966             }
10967             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10968             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10969             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10970             try {
10971                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10972                         requestType);
10973                 mPendingAssistExtras.add(pae);
10974                 mUiHandler.postDelayed(pae, timeout);
10975             } catch (RemoteException e) {
10976                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10977                 return null;
10978             }
10979             return pae;
10980         }
10981     }
10982
10983     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
10984         IResultReceiver receiver;
10985         synchronized (this) {
10986             mPendingAssistExtras.remove(pae);
10987             receiver = pae.receiver;
10988         }
10989         if (receiver != null) {
10990             // Caller wants result sent back to them.
10991             try {
10992                 pae.receiver.send(0, null);
10993             } catch (RemoteException e) {
10994             }
10995         }
10996     }
10997
10998     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10999         if (result != null) {
11000             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11001         }
11002         if (pae.hint != null) {
11003             pae.extras.putBoolean(pae.hint, true);
11004         }
11005     }
11006
11007     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11008             AssistContent content, Uri referrer) {
11009         PendingAssistExtras pae = (PendingAssistExtras)token;
11010         synchronized (pae) {
11011             pae.result = extras;
11012             pae.structure = structure;
11013             pae.content = content;
11014             if (referrer != null) {
11015                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11016             }
11017             pae.haveResult = true;
11018             pae.notifyAll();
11019             if (pae.intent == null && pae.receiver == null) {
11020                 // Caller is just waiting for the result.
11021                 return;
11022             }
11023         }
11024
11025         // We are now ready to launch the assist activity.
11026         IResultReceiver sendReceiver = null;
11027         Bundle sendBundle = null;
11028         synchronized (this) {
11029             buildAssistBundleLocked(pae, extras);
11030             boolean exists = mPendingAssistExtras.remove(pae);
11031             mUiHandler.removeCallbacks(pae);
11032             if (!exists) {
11033                 // Timed out.
11034                 return;
11035             }
11036             if ((sendReceiver=pae.receiver) != null) {
11037                 // Caller wants result sent back to them.
11038                 sendBundle = new Bundle();
11039                 sendBundle.putBundle("data", pae.extras);
11040                 sendBundle.putParcelable("structure", pae.structure);
11041                 sendBundle.putParcelable("content", pae.content);
11042             }
11043         }
11044         if (sendReceiver != null) {
11045             try {
11046                 sendReceiver.send(0, sendBundle);
11047             } catch (RemoteException e) {
11048             }
11049             return;
11050         }
11051
11052         long ident = Binder.clearCallingIdentity();
11053         try {
11054             pae.intent.replaceExtras(pae.extras);
11055             pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11056                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
11057                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11058             closeSystemDialogs("assist");
11059             try {
11060                 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11061             } catch (ActivityNotFoundException e) {
11062                 Slog.w(TAG, "No activity to handle assist action.", e);
11063             }
11064         } finally {
11065             Binder.restoreCallingIdentity(ident);
11066         }
11067     }
11068
11069     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
11070             Bundle args) {
11071         return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
11072                 PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
11073     }
11074
11075     public void registerProcessObserver(IProcessObserver observer) {
11076         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11077                 "registerProcessObserver()");
11078         synchronized (this) {
11079             mProcessObservers.register(observer);
11080         }
11081     }
11082
11083     @Override
11084     public void unregisterProcessObserver(IProcessObserver observer) {
11085         synchronized (this) {
11086             mProcessObservers.unregister(observer);
11087         }
11088     }
11089
11090     public void registerUidObserver(IUidObserver observer) {
11091         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11092                 "registerUidObserver()");
11093         synchronized (this) {
11094             mUidObservers.register(observer);
11095         }
11096     }
11097
11098     @Override
11099     public void unregisterUidObserver(IUidObserver observer) {
11100         synchronized (this) {
11101             mUidObservers.unregister(observer);
11102         }
11103     }
11104
11105     @Override
11106     public boolean convertFromTranslucent(IBinder token) {
11107         final long origId = Binder.clearCallingIdentity();
11108         try {
11109             synchronized (this) {
11110                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11111                 if (r == null) {
11112                     return false;
11113                 }
11114                 final boolean translucentChanged = r.changeWindowTranslucency(true);
11115                 if (translucentChanged) {
11116                     r.task.stack.releaseBackgroundResources(r);
11117                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
11118                 }
11119                 mWindowManager.setAppFullscreen(token, true);
11120                 return translucentChanged;
11121             }
11122         } finally {
11123             Binder.restoreCallingIdentity(origId);
11124         }
11125     }
11126
11127     @Override
11128     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11129         final long origId = Binder.clearCallingIdentity();
11130         try {
11131             synchronized (this) {
11132                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11133                 if (r == null) {
11134                     return false;
11135                 }
11136                 int index = r.task.mActivities.lastIndexOf(r);
11137                 if (index > 0) {
11138                     ActivityRecord under = r.task.mActivities.get(index - 1);
11139                     under.returningOptions = options;
11140                 }
11141                 final boolean translucentChanged = r.changeWindowTranslucency(false);
11142                 if (translucentChanged) {
11143                     r.task.stack.convertActivityToTranslucent(r);
11144                 }
11145                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
11146                 mWindowManager.setAppFullscreen(token, false);
11147                 return translucentChanged;
11148             }
11149         } finally {
11150             Binder.restoreCallingIdentity(origId);
11151         }
11152     }
11153
11154     @Override
11155     public boolean requestVisibleBehind(IBinder token, boolean visible) {
11156         final long origId = Binder.clearCallingIdentity();
11157         try {
11158             synchronized (this) {
11159                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11160                 if (r != null) {
11161                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11162                 }
11163             }
11164             return false;
11165         } finally {
11166             Binder.restoreCallingIdentity(origId);
11167         }
11168     }
11169
11170     @Override
11171     public boolean isBackgroundVisibleBehind(IBinder token) {
11172         final long origId = Binder.clearCallingIdentity();
11173         try {
11174             synchronized (this) {
11175                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
11176                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11177                 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11178                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11179                 return visible;
11180             }
11181         } finally {
11182             Binder.restoreCallingIdentity(origId);
11183         }
11184     }
11185
11186     @Override
11187     public ActivityOptions getActivityOptions(IBinder token) {
11188         final long origId = Binder.clearCallingIdentity();
11189         try {
11190             synchronized (this) {
11191                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11192                 if (r != null) {
11193                     final ActivityOptions activityOptions = r.pendingOptions;
11194                     r.pendingOptions = null;
11195                     return activityOptions;
11196                 }
11197                 return null;
11198             }
11199         } finally {
11200             Binder.restoreCallingIdentity(origId);
11201         }
11202     }
11203
11204     @Override
11205     public void setImmersive(IBinder token, boolean immersive) {
11206         synchronized(this) {
11207             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11208             if (r == null) {
11209                 throw new IllegalArgumentException();
11210             }
11211             r.immersive = immersive;
11212
11213             // update associated state if we're frontmost
11214             if (r == mFocusedActivity) {
11215                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11216                 applyUpdateLockStateLocked(r);
11217             }
11218         }
11219     }
11220
11221     @Override
11222     public boolean isImmersive(IBinder token) {
11223         synchronized (this) {
11224             ActivityRecord r = ActivityRecord.isInStackLocked(token);
11225             if (r == null) {
11226                 throw new IllegalArgumentException();
11227             }
11228             return r.immersive;
11229         }
11230     }
11231
11232     public boolean isTopActivityImmersive() {
11233         enforceNotIsolatedCaller("startActivity");
11234         synchronized (this) {
11235             ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
11236             return (r != null) ? r.immersive : false;
11237         }
11238     }
11239
11240     @Override
11241     public boolean isTopOfTask(IBinder token) {
11242         synchronized (this) {
11243             ActivityRecord r = ActivityRecord.isInStackLocked(token);
11244             if (r == null) {
11245                 throw new IllegalArgumentException();
11246             }
11247             return r.task.getTopActivity() == r;
11248         }
11249     }
11250
11251     public final void enterSafeMode() {
11252         synchronized(this) {
11253             // It only makes sense to do this before the system is ready
11254             // and started launching other packages.
11255             if (!mSystemReady) {
11256                 try {
11257                     AppGlobals.getPackageManager().enterSafeMode();
11258                 } catch (RemoteException e) {
11259                 }
11260             }
11261
11262             mSafeMode = true;
11263         }
11264     }
11265
11266     public final void showSafeModeOverlay() {
11267         View v = LayoutInflater.from(mContext).inflate(
11268                 com.android.internal.R.layout.safe_mode, null);
11269         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11270         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11271         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11272         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11273         lp.gravity = Gravity.BOTTOM | Gravity.START;
11274         lp.format = v.getBackground().getOpacity();
11275         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11276                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11277         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11278         ((WindowManager)mContext.getSystemService(
11279                 Context.WINDOW_SERVICE)).addView(v, lp);
11280     }
11281
11282     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11283         if (!(sender instanceof PendingIntentRecord)) {
11284             return;
11285         }
11286         final PendingIntentRecord rec = (PendingIntentRecord)sender;
11287         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11288         synchronized (stats) {
11289             if (mBatteryStatsService.isOnBattery()) {
11290                 mBatteryStatsService.enforceCallingPermission();
11291                 int MY_UID = Binder.getCallingUid();
11292                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11293                 BatteryStatsImpl.Uid.Pkg pkg =
11294                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11295                             sourcePkg != null ? sourcePkg : rec.key.packageName);
11296                 pkg.noteWakeupAlarmLocked(tag);
11297             }
11298         }
11299     }
11300
11301     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11302         if (!(sender instanceof PendingIntentRecord)) {
11303             return;
11304         }
11305         final PendingIntentRecord rec = (PendingIntentRecord)sender;
11306         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11307         synchronized (stats) {
11308             mBatteryStatsService.enforceCallingPermission();
11309             int MY_UID = Binder.getCallingUid();
11310             int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11311             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11312         }
11313     }
11314
11315     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11316         if (!(sender instanceof PendingIntentRecord)) {
11317             return;
11318         }
11319         final PendingIntentRecord rec = (PendingIntentRecord)sender;
11320         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11321         synchronized (stats) {
11322             mBatteryStatsService.enforceCallingPermission();
11323             int MY_UID = Binder.getCallingUid();
11324             int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11325             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11326         }
11327     }
11328
11329     public boolean killPids(int[] pids, String pReason, boolean secure) {
11330         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11331             throw new SecurityException("killPids only available to the system");
11332         }
11333         String reason = (pReason == null) ? "Unknown" : pReason;
11334         // XXX Note: don't acquire main activity lock here, because the window
11335         // manager calls in with its locks held.
11336
11337         boolean killed = false;
11338         synchronized (mPidsSelfLocked) {
11339             int[] types = new int[pids.length];
11340             int worstType = 0;
11341             for (int i=0; i<pids.length; i++) {
11342                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11343                 if (proc != null) {
11344                     int type = proc.setAdj;
11345                     types[i] = type;
11346                     if (type > worstType) {
11347                         worstType = type;
11348                     }
11349                 }
11350             }
11351
11352             // If the worst oom_adj is somewhere in the cached proc LRU range,
11353             // then constrain it so we will kill all cached procs.
11354             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11355                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11356                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
11357             }
11358
11359             // If this is not a secure call, don't let it kill processes that
11360             // are important.
11361             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11362                 worstType = ProcessList.SERVICE_ADJ;
11363             }
11364
11365             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11366             for (int i=0; i<pids.length; i++) {
11367                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11368                 if (proc == null) {
11369                     continue;
11370                 }
11371                 int adj = proc.setAdj;
11372                 if (adj >= worstType && !proc.killedByAm) {
11373                     proc.kill(reason, true);
11374                     killed = true;
11375                 }
11376             }
11377         }
11378         return killed;
11379     }
11380
11381     @Override
11382     public void killUid(int appId, int userId, String reason) {
11383         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11384         synchronized (this) {
11385             final long identity = Binder.clearCallingIdentity();
11386             try {
11387                 killPackageProcessesLocked(null, appId, userId,
11388                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11389                         reason != null ? reason : "kill uid");
11390             } finally {
11391                 Binder.restoreCallingIdentity(identity);
11392             }
11393         }
11394     }
11395
11396     @Override
11397     public boolean killProcessesBelowForeground(String reason) {
11398         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11399             throw new SecurityException("killProcessesBelowForeground() only available to system");
11400         }
11401
11402         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11403     }
11404
11405     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11406         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11407             throw new SecurityException("killProcessesBelowAdj() only available to system");
11408         }
11409
11410         boolean killed = false;
11411         synchronized (mPidsSelfLocked) {
11412             final int size = mPidsSelfLocked.size();
11413             for (int i = 0; i < size; i++) {
11414                 final int pid = mPidsSelfLocked.keyAt(i);
11415                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11416                 if (proc == null) continue;
11417
11418                 final int adj = proc.setAdj;
11419                 if (adj > belowAdj && !proc.killedByAm) {
11420                     proc.kill(reason, true);
11421                     killed = true;
11422                 }
11423             }
11424         }
11425         return killed;
11426     }
11427
11428     @Override
11429     public void hang(final IBinder who, boolean allowRestart) {
11430         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11431                 != PackageManager.PERMISSION_GRANTED) {
11432             throw new SecurityException("Requires permission "
11433                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11434         }
11435
11436         final IBinder.DeathRecipient death = new DeathRecipient() {
11437             @Override
11438             public void binderDied() {
11439                 synchronized (this) {
11440                     notifyAll();
11441                 }
11442             }
11443         };
11444
11445         try {
11446             who.linkToDeath(death, 0);
11447         } catch (RemoteException e) {
11448             Slog.w(TAG, "hang: given caller IBinder is already dead.");
11449             return;
11450         }
11451
11452         synchronized (this) {
11453             Watchdog.getInstance().setAllowRestart(allowRestart);
11454             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11455             synchronized (death) {
11456                 while (who.isBinderAlive()) {
11457                     try {
11458                         death.wait();
11459                     } catch (InterruptedException e) {
11460                     }
11461                 }
11462             }
11463             Watchdog.getInstance().setAllowRestart(true);
11464         }
11465     }
11466
11467     @Override
11468     public void restart() {
11469         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11470                 != PackageManager.PERMISSION_GRANTED) {
11471             throw new SecurityException("Requires permission "
11472                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11473         }
11474
11475         Log.i(TAG, "Sending shutdown broadcast...");
11476
11477         BroadcastReceiver br = new BroadcastReceiver() {
11478             @Override public void onReceive(Context context, Intent intent) {
11479                 // Now the broadcast is done, finish up the low-level shutdown.
11480                 Log.i(TAG, "Shutting down activity manager...");
11481                 shutdown(10000);
11482                 Log.i(TAG, "Shutdown complete, restarting!");
11483                 Process.killProcess(Process.myPid());
11484                 System.exit(10);
11485             }
11486         };
11487
11488         // First send the high-level shut down broadcast.
11489         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11490         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11491         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11492         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11493         mContext.sendOrderedBroadcastAsUser(intent,
11494                 UserHandle.ALL, null, br, mHandler, 0, null, null);
11495         */
11496         br.onReceive(mContext, intent);
11497     }
11498
11499     private long getLowRamTimeSinceIdle(long now) {
11500         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11501     }
11502
11503     @Override
11504     public void performIdleMaintenance() {
11505         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11506                 != PackageManager.PERMISSION_GRANTED) {
11507             throw new SecurityException("Requires permission "
11508                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11509         }
11510
11511         synchronized (this) {
11512             final long now = SystemClock.uptimeMillis();
11513             final long timeSinceLastIdle = now - mLastIdleTime;
11514             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11515             mLastIdleTime = now;
11516             mLowRamTimeSinceLastIdle = 0;
11517             if (mLowRamStartTime != 0) {
11518                 mLowRamStartTime = now;
11519             }
11520
11521             StringBuilder sb = new StringBuilder(128);
11522             sb.append("Idle maintenance over ");
11523             TimeUtils.formatDuration(timeSinceLastIdle, sb);
11524             sb.append(" low RAM for ");
11525             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11526             Slog.i(TAG, sb.toString());
11527
11528             // If at least 1/3 of our time since the last idle period has been spent
11529             // with RAM low, then we want to kill processes.
11530             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11531
11532             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11533                 ProcessRecord proc = mLruProcesses.get(i);
11534                 if (proc.notCachedSinceIdle) {
11535                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11536                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11537                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11538                         if (doKilling && proc.initialIdlePss != 0
11539                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11540                             sb = new StringBuilder(128);
11541                             sb.append("Kill");
11542                             sb.append(proc.processName);
11543                             sb.append(" in idle maint: pss=");
11544                             sb.append(proc.lastPss);
11545                             sb.append(", initialPss=");
11546                             sb.append(proc.initialIdlePss);
11547                             sb.append(", period=");
11548                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
11549                             sb.append(", lowRamPeriod=");
11550                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11551                             Slog.wtfQuiet(TAG, sb.toString());
11552                             proc.kill("idle maint (pss " + proc.lastPss
11553                                     + " from " + proc.initialIdlePss + ")", true);
11554                         }
11555                     }
11556                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11557                     proc.notCachedSinceIdle = true;
11558                     proc.initialIdlePss = 0;
11559                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11560                             mTestPssMode, isSleeping(), now);
11561                 }
11562             }
11563
11564             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11565             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11566         }
11567     }
11568
11569     private void retrieveSettings() {
11570         final ContentResolver resolver = mContext.getContentResolver();
11571         String debugApp = Settings.Global.getString(
11572             resolver, Settings.Global.DEBUG_APP);
11573         boolean waitForDebugger = Settings.Global.getInt(
11574             resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11575         boolean alwaysFinishActivities = Settings.Global.getInt(
11576             resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11577         boolean forceRtl = Settings.Global.getInt(
11578                 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11579         // Transfer any global setting for forcing RTL layout, into a System Property
11580         SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11581
11582         Configuration configuration = new Configuration();
11583         Settings.System.getConfiguration(resolver, configuration);
11584         if (forceRtl) {
11585             // This will take care of setting the correct layout direction flags
11586             configuration.setLayoutDirection(configuration.locale);
11587         }
11588
11589         synchronized (this) {
11590             mDebugApp = mOrigDebugApp = debugApp;
11591             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11592             mAlwaysFinishActivities = alwaysFinishActivities;
11593             // This happens before any activities are started, so we can
11594             // change mConfiguration in-place.
11595             updateConfigurationLocked(configuration, null, false, true);
11596             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11597                     "Initial config: " + mConfiguration);
11598         }
11599     }
11600
11601     /** Loads resources after the current configuration has been set. */
11602     private void loadResourcesOnSystemReady() {
11603         final Resources res = mContext.getResources();
11604         mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11605         mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11606         mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11607     }
11608
11609     public boolean testIsSystemReady() {
11610         // no need to synchronize(this) just to read & return the value
11611         return mSystemReady;
11612     }
11613
11614     private static File getCalledPreBootReceiversFile() {
11615         File dataDir = Environment.getDataDirectory();
11616         File systemDir = new File(dataDir, "system");
11617         File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11618         return fname;
11619     }
11620
11621     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11622         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11623         File file = getCalledPreBootReceiversFile();
11624         FileInputStream fis = null;
11625         try {
11626             fis = new FileInputStream(file);
11627             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11628             int fvers = dis.readInt();
11629             if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11630                 String vers = dis.readUTF();
11631                 String codename = dis.readUTF();
11632                 String build = dis.readUTF();
11633                 if (android.os.Build.VERSION.RELEASE.equals(vers)
11634                         && android.os.Build.VERSION.CODENAME.equals(codename)
11635                         && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11636                     int num = dis.readInt();
11637                     while (num > 0) {
11638                         num--;
11639                         String pkg = dis.readUTF();
11640                         String cls = dis.readUTF();
11641                         lastDoneReceivers.add(new ComponentName(pkg, cls));
11642                     }
11643                 }
11644             }
11645         } catch (FileNotFoundException e) {
11646         } catch (IOException e) {
11647             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11648         } finally {
11649             if (fis != null) {
11650                 try {
11651                     fis.close();
11652                 } catch (IOException e) {
11653                 }
11654             }
11655         }
11656         return lastDoneReceivers;
11657     }
11658
11659     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11660         File file = getCalledPreBootReceiversFile();
11661         FileOutputStream fos = null;
11662         DataOutputStream dos = null;
11663         try {
11664             fos = new FileOutputStream(file);
11665             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11666             dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11667             dos.writeUTF(android.os.Build.VERSION.RELEASE);
11668             dos.writeUTF(android.os.Build.VERSION.CODENAME);
11669             dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11670             dos.writeInt(list.size());
11671             for (int i=0; i<list.size(); i++) {
11672                 dos.writeUTF(list.get(i).getPackageName());
11673                 dos.writeUTF(list.get(i).getClassName());
11674             }
11675         } catch (IOException e) {
11676             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11677             file.delete();
11678         } finally {
11679             FileUtils.sync(fos);
11680             if (dos != null) {
11681                 try {
11682                     dos.close();
11683                 } catch (IOException e) {
11684                     // TODO Auto-generated catch block
11685                     e.printStackTrace();
11686                 }
11687             }
11688         }
11689     }
11690
11691     final class PreBootContinuation extends IIntentReceiver.Stub {
11692         final Intent intent;
11693         final Runnable onFinishCallback;
11694         final ArrayList<ComponentName> doneReceivers;
11695         final List<ResolveInfo> ris;
11696         final int[] users;
11697         int lastRi = -1;
11698         int curRi = 0;
11699         int curUser = 0;
11700
11701         PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11702                 ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11703             intent = _intent;
11704             onFinishCallback = _onFinishCallback;
11705             doneReceivers = _doneReceivers;
11706             ris = _ris;
11707             users = _users;
11708         }
11709
11710         void go() {
11711             if (lastRi != curRi) {
11712                 ActivityInfo ai = ris.get(curRi).activityInfo;
11713                 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11714                 intent.setComponent(comp);
11715                 doneReceivers.add(comp);
11716                 lastRi = curRi;
11717                 CharSequence label = ai.loadLabel(mContext.getPackageManager());
11718                 showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11719             }
11720             Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11721                     + " for user " + users[curUser]);
11722             EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11723             broadcastIntentLocked(null, null, intent, null, this,
11724                     0, null, null, null, AppOpsManager.OP_NONE,
11725                     null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11726         }
11727
11728         public void performReceive(Intent intent, int resultCode,
11729                 String data, Bundle extras, boolean ordered,
11730                 boolean sticky, int sendingUser) {
11731             curUser++;
11732             if (curUser >= users.length) {
11733                 curUser = 0;
11734                 curRi++;
11735                 if (curRi >= ris.size()) {
11736                     // All done sending broadcasts!
11737                     if (onFinishCallback != null) {
11738                         // The raw IIntentReceiver interface is called
11739                         // with the AM lock held, so redispatch to
11740                         // execute our code without the lock.
11741                         mHandler.post(onFinishCallback);
11742                     }
11743                     return;
11744                 }
11745             }
11746             go();
11747         }
11748     }
11749
11750     private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11751             ArrayList<ComponentName> doneReceivers, int userId) {
11752         Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11753         List<ResolveInfo> ris = null;
11754         try {
11755             ris = AppGlobals.getPackageManager().queryIntentReceivers(
11756                     intent, null, 0, userId);
11757         } catch (RemoteException e) {
11758         }
11759         if (ris == null) {
11760             return false;
11761         }
11762         for (int i=ris.size()-1; i>=0; i--) {
11763             if ((ris.get(i).activityInfo.applicationInfo.flags
11764                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
11765                 ris.remove(i);
11766             }
11767         }
11768         intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11769
11770         // For User 0, load the version number. When delivering to a new user, deliver
11771         // to all receivers.
11772         if (userId == UserHandle.USER_OWNER) {
11773             ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11774             for (int i=0; i<ris.size(); i++) {
11775                 ActivityInfo ai = ris.get(i).activityInfo;
11776                 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11777                 if (lastDoneReceivers.contains(comp)) {
11778                     // We already did the pre boot receiver for this app with the current
11779                     // platform version, so don't do it again...
11780                     ris.remove(i);
11781                     i--;
11782                     // ...however, do keep it as one that has been done, so we don't
11783                     // forget about it when rewriting the file of last done receivers.
11784                     doneReceivers.add(comp);
11785                 }
11786             }
11787         }
11788
11789         if (ris.size() <= 0) {
11790             return false;
11791         }
11792
11793         // If primary user, send broadcast to all available users, else just to userId
11794         final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11795                 : new int[] { userId };
11796         if (users.length <= 0) {
11797             return false;
11798         }
11799
11800         PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11801                 ris, users);
11802         cont.go();
11803         return true;
11804     }
11805
11806     public void systemReady(final Runnable goingCallback) {
11807         synchronized(this) {
11808             if (mSystemReady) {
11809                 // If we're done calling all the receivers, run the next "boot phase" passed in
11810                 // by the SystemServer
11811                 if (goingCallback != null) {
11812                     goingCallback.run();
11813                 }
11814                 return;
11815             }
11816
11817             mLocalDeviceIdleController
11818                     = LocalServices.getService(DeviceIdleController.LocalService.class);
11819
11820             // Make sure we have the current profile info, since it is needed for
11821             // security checks.
11822             updateCurrentProfileIdsLocked();
11823
11824             mRecentTasks.clear();
11825             mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11826             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11827             mTaskPersister.startPersisting();
11828
11829             // Check to see if there are any update receivers to run.
11830             if (!mDidUpdate) {
11831                 if (mWaitingUpdate) {
11832                     return;
11833                 }
11834                 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11835                 mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11836                     public void run() {
11837                         synchronized (ActivityManagerService.this) {
11838                             mDidUpdate = true;
11839                         }
11840                         showBootMessage(mContext.getText(
11841                                 R.string.android_upgrading_complete),
11842                                 false);
11843                         writeLastDonePreBootReceivers(doneReceivers);
11844                         systemReady(goingCallback);
11845                     }
11846                 }, doneReceivers, UserHandle.USER_OWNER);
11847
11848                 if (mWaitingUpdate) {
11849                     return;
11850                 }
11851                 mDidUpdate = true;
11852             }
11853
11854             mAppOpsService.systemReady();
11855             mSystemReady = true;
11856         }
11857
11858         ArrayList<ProcessRecord> procsToKill = null;
11859         synchronized(mPidsSelfLocked) {
11860             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11861                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11862                 if (!isAllowedWhileBooting(proc.info)){
11863                     if (procsToKill == null) {
11864                         procsToKill = new ArrayList<ProcessRecord>();
11865                     }
11866                     procsToKill.add(proc);
11867                 }
11868             }
11869         }
11870
11871         synchronized(this) {
11872             if (procsToKill != null) {
11873                 for (int i=procsToKill.size()-1; i>=0; i--) {
11874                     ProcessRecord proc = procsToKill.get(i);
11875                     Slog.i(TAG, "Removing system update proc: " + proc);
11876                     removeProcessLocked(proc, true, false, "system update done");
11877                 }
11878             }
11879
11880             // Now that we have cleaned up any update processes, we
11881             // are ready to start launching real processes and know that
11882             // we won't trample on them any more.
11883             mProcessesReady = true;
11884         }
11885
11886         Slog.i(TAG, "System now ready");
11887         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11888             SystemClock.uptimeMillis());
11889
11890         synchronized(this) {
11891             // Make sure we have no pre-ready processes sitting around.
11892
11893             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11894                 ResolveInfo ri = mContext.getPackageManager()
11895                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11896                                 STOCK_PM_FLAGS);
11897                 CharSequence errorMsg = null;
11898                 if (ri != null) {
11899                     ActivityInfo ai = ri.activityInfo;
11900                     ApplicationInfo app = ai.applicationInfo;
11901                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11902                         mTopAction = Intent.ACTION_FACTORY_TEST;
11903                         mTopData = null;
11904                         mTopComponent = new ComponentName(app.packageName,
11905                                 ai.name);
11906                     } else {
11907                         errorMsg = mContext.getResources().getText(
11908                                 com.android.internal.R.string.factorytest_not_system);
11909                     }
11910                 } else {
11911                     errorMsg = mContext.getResources().getText(
11912                             com.android.internal.R.string.factorytest_no_action);
11913                 }
11914                 if (errorMsg != null) {
11915                     mTopAction = null;
11916                     mTopData = null;
11917                     mTopComponent = null;
11918                     Message msg = Message.obtain();
11919                     msg.what = SHOW_FACTORY_ERROR_MSG;
11920                     msg.getData().putCharSequence("msg", errorMsg);
11921                     mUiHandler.sendMessage(msg);
11922                 }
11923             }
11924         }
11925
11926         retrieveSettings();
11927         loadResourcesOnSystemReady();
11928
11929         synchronized (this) {
11930             readGrantedUriPermissionsLocked();
11931         }
11932
11933         if (goingCallback != null) goingCallback.run();
11934
11935         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11936                 Integer.toString(mCurrentUserId), mCurrentUserId);
11937         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11938                 Integer.toString(mCurrentUserId), mCurrentUserId);
11939         mSystemServiceManager.startUser(mCurrentUserId);
11940
11941         synchronized (this) {
11942             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11943                 try {
11944                     List apps = AppGlobals.getPackageManager().
11945                         getPersistentApplications(STOCK_PM_FLAGS);
11946                     if (apps != null) {
11947                         int N = apps.size();
11948                         int i;
11949                         for (i=0; i<N; i++) {
11950                             ApplicationInfo info
11951                                 = (ApplicationInfo)apps.get(i);
11952                             if (info != null &&
11953                                     !info.packageName.equals("android")) {
11954                                 addAppLocked(info, false, null /* ABI override */);
11955                             }
11956                         }
11957                     }
11958                 } catch (RemoteException ex) {
11959                     // pm is in same process, this will never happen.
11960                 }
11961             }
11962
11963             // Start up initial activity.
11964             mBooting = true;
11965             startHomeActivityLocked(mCurrentUserId, "systemReady");
11966
11967             try {
11968                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11969                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11970                             + " data partition or your device will be unstable.");
11971                     mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11972                 }
11973             } catch (RemoteException e) {
11974             }
11975
11976             if (!Build.isBuildConsistent()) {
11977                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11978                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11979             }
11980
11981             long ident = Binder.clearCallingIdentity();
11982             try {
11983                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11984                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11985                         | Intent.FLAG_RECEIVER_FOREGROUND);
11986                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11987                 broadcastIntentLocked(null, null, intent,
11988                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11989                         null, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11990                 intent = new Intent(Intent.ACTION_USER_STARTING);
11991                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11992                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11993                 broadcastIntentLocked(null, null, intent,
11994                         null, new IIntentReceiver.Stub() {
11995                             @Override
11996                             public void performReceive(Intent intent, int resultCode, String data,
11997                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11998                                     throws RemoteException {
11999                             }
12000                         }, 0, null, null,
12001                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12002                         null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12003             } catch (Throwable t) {
12004                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12005             } finally {
12006                 Binder.restoreCallingIdentity(ident);
12007             }
12008             mStackSupervisor.resumeTopActivitiesLocked();
12009             sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
12010         }
12011     }
12012
12013     private boolean makeAppCrashingLocked(ProcessRecord app,
12014             String shortMsg, String longMsg, String stackTrace) {
12015         app.crashing = true;
12016         app.crashingReport = generateProcessError(app,
12017                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
12018         startAppProblemLocked(app);
12019         app.stopFreezingAllLocked();
12020         return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
12021     }
12022
12023     private void makeAppNotRespondingLocked(ProcessRecord app,
12024             String activity, String shortMsg, String longMsg) {
12025         app.notResponding = true;
12026         app.notRespondingReport = generateProcessError(app,
12027                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
12028                 activity, shortMsg, longMsg, null);
12029         startAppProblemLocked(app);
12030         app.stopFreezingAllLocked();
12031     }
12032
12033     /**
12034      * Generate a process error record, suitable for attachment to a ProcessRecord.
12035      *
12036      * @param app The ProcessRecord in which the error occurred.
12037      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
12038      *                      ActivityManager.AppErrorStateInfo
12039      * @param activity The activity associated with the crash, if known.
12040      * @param shortMsg Short message describing the crash.
12041      * @param longMsg Long message describing the crash.
12042      * @param stackTrace Full crash stack trace, may be null.
12043      *
12044      * @return Returns a fully-formed AppErrorStateInfo record.
12045      */
12046     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
12047             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
12048         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
12049
12050         report.condition = condition;
12051         report.processName = app.processName;
12052         report.pid = app.pid;
12053         report.uid = app.info.uid;
12054         report.tag = activity;
12055         report.shortMsg = shortMsg;
12056         report.longMsg = longMsg;
12057         report.stackTrace = stackTrace;
12058
12059         return report;
12060     }
12061
12062     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12063         synchronized (this) {
12064             app.crashing = false;
12065             app.crashingReport = null;
12066             app.notResponding = false;
12067             app.notRespondingReport = null;
12068             if (app.anrDialog == fromDialog) {
12069                 app.anrDialog = null;
12070             }
12071             if (app.waitDialog == fromDialog) {
12072                 app.waitDialog = null;
12073             }
12074             if (app.pid > 0 && app.pid != MY_PID) {
12075                 handleAppCrashLocked(app, "user-terminated" /*reason*/,
12076                         null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
12077                 app.kill("user request after error", true);
12078             }
12079         }
12080     }
12081
12082     private boolean handleAppCrashLocked(ProcessRecord app, String reason,
12083             String shortMsg, String longMsg, String stackTrace) {
12084         long now = SystemClock.uptimeMillis();
12085
12086         Long crashTime;
12087         if (!app.isolated) {
12088             crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
12089         } else {
12090             crashTime = null;
12091         }
12092         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
12093             // This process loses!
12094             Slog.w(TAG, "Process " + app.info.processName
12095                     + " has crashed too many times: killing!");
12096             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
12097                     app.userId, app.info.processName, app.uid);
12098             mStackSupervisor.handleAppCrashLocked(app);
12099             if (!app.persistent) {
12100                 // We don't want to start this process again until the user
12101                 // explicitly does so...  but for persistent process, we really
12102                 // need to keep it running.  If a persistent process is actually
12103                 // repeatedly crashing, then badness for everyone.
12104                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
12105                         app.info.processName);
12106                 if (!app.isolated) {
12107                     // XXX We don't have a way to mark isolated processes
12108                     // as bad, since they don't have a peristent identity.
12109                     mBadProcesses.put(app.info.processName, app.uid,
12110                             new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
12111                     mProcessCrashTimes.remove(app.info.processName, app.uid);
12112                 }
12113                 app.bad = true;
12114                 app.removed = true;
12115                 // Don't let services in this process be restarted and potentially
12116                 // annoy the user repeatedly.  Unless it is persistent, since those
12117                 // processes run critical code.
12118                 removeProcessLocked(app, false, false, "crash");
12119                 mStackSupervisor.resumeTopActivitiesLocked();
12120                 return false;
12121             }
12122             mStackSupervisor.resumeTopActivitiesLocked();
12123         } else {
12124             mStackSupervisor.finishTopRunningActivityLocked(app, reason);
12125         }
12126
12127         // Bump up the crash count of any services currently running in the proc.
12128         for (int i=app.services.size()-1; i>=0; i--) {
12129             // Any services running in the application need to be placed
12130             // back in the pending list.
12131             ServiceRecord sr = app.services.valueAt(i);
12132             sr.crashCount++;
12133         }
12134
12135         // If the crashing process is what we consider to be the "home process" and it has been
12136         // replaced by a third-party app, clear the package preferred activities from packages
12137         // with a home activity running in the process to prevent a repeatedly crashing app
12138         // from blocking the user to manually clear the list.
12139         final ArrayList<ActivityRecord> activities = app.activities;
12140         if (app == mHomeProcess && activities.size() > 0
12141                     && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
12142             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
12143                 final ActivityRecord r = activities.get(activityNdx);
12144                 if (r.isHomeActivity()) {
12145                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
12146                     try {
12147                         ActivityThread.getPackageManager()
12148                                 .clearPackagePreferredActivities(r.packageName);
12149                     } catch (RemoteException c) {
12150                         // pm is in same process, this will never happen.
12151                     }
12152                 }
12153             }
12154         }
12155
12156         if (!app.isolated) {
12157             // XXX Can't keep track of crash times for isolated processes,
12158             // because they don't have a perisistent identity.
12159             mProcessCrashTimes.put(app.info.processName, app.uid, now);
12160         }
12161
12162         if (app.crashHandler != null) mHandler.post(app.crashHandler);
12163         return true;
12164     }
12165
12166     void startAppProblemLocked(ProcessRecord app) {
12167         // If this app is not running under the current user, then we
12168         // can't give it a report button because that would require
12169         // launching the report UI under a different user.
12170         app.errorReportReceiver = null;
12171
12172         for (int userId : mCurrentProfileIds) {
12173             if (app.userId == userId) {
12174                 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12175                         mContext, app.info.packageName, app.info.flags);
12176             }
12177         }
12178         skipCurrentReceiverLocked(app);
12179     }
12180
12181     void skipCurrentReceiverLocked(ProcessRecord app) {
12182         for (BroadcastQueue queue : mBroadcastQueues) {
12183             queue.skipCurrentReceiverLocked(app);
12184         }
12185     }
12186
12187     /**
12188      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12189      * The application process will exit immediately after this call returns.
12190      * @param app object of the crashing app, null for the system server
12191      * @param crashInfo describing the exception
12192      */
12193     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12194         ProcessRecord r = findAppProcess(app, "Crash");
12195         final String processName = app == null ? "system_server"
12196                 : (r == null ? "unknown" : r.processName);
12197
12198         handleApplicationCrashInner("crash", r, processName, crashInfo);
12199     }
12200
12201     /* Native crash reporting uses this inner version because it needs to be somewhat
12202      * decoupled from the AM-managed cleanup lifecycle
12203      */
12204     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12205             ApplicationErrorReport.CrashInfo crashInfo) {
12206         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12207                 UserHandle.getUserId(Binder.getCallingUid()), processName,
12208                 r == null ? -1 : r.info.flags,
12209                 crashInfo.exceptionClassName,
12210                 crashInfo.exceptionMessage,
12211                 crashInfo.throwFileName,
12212                 crashInfo.throwLineNumber);
12213
12214         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12215
12216         crashApplication(r, crashInfo);
12217     }
12218
12219     public void handleApplicationStrictModeViolation(
12220             IBinder app,
12221             int violationMask,
12222             StrictMode.ViolationInfo info) {
12223         ProcessRecord r = findAppProcess(app, "StrictMode");
12224         if (r == null) {
12225             return;
12226         }
12227
12228         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12229             Integer stackFingerprint = info.hashCode();
12230             boolean logIt = true;
12231             synchronized (mAlreadyLoggedViolatedStacks) {
12232                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12233                     logIt = false;
12234                     // TODO: sub-sample into EventLog for these, with
12235                     // the info.durationMillis?  Then we'd get
12236                     // the relative pain numbers, without logging all
12237                     // the stack traces repeatedly.  We'd want to do
12238                     // likewise in the client code, which also does
12239                     // dup suppression, before the Binder call.
12240                 } else {
12241                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12242                         mAlreadyLoggedViolatedStacks.clear();
12243                     }
12244                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12245                 }
12246             }
12247             if (logIt) {
12248                 logStrictModeViolationToDropBox(r, info);
12249             }
12250         }
12251
12252         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12253             AppErrorResult result = new AppErrorResult();
12254             synchronized (this) {
12255                 final long origId = Binder.clearCallingIdentity();
12256
12257                 Message msg = Message.obtain();
12258                 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
12259                 HashMap<String, Object> data = new HashMap<String, Object>();
12260                 data.put("result", result);
12261                 data.put("app", r);
12262                 data.put("violationMask", violationMask);
12263                 data.put("info", info);
12264                 msg.obj = data;
12265                 mUiHandler.sendMessage(msg);
12266
12267                 Binder.restoreCallingIdentity(origId);
12268             }
12269             int res = result.get();
12270             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12271         }
12272     }
12273
12274     // Depending on the policy in effect, there could be a bunch of
12275     // these in quick succession so we try to batch these together to
12276     // minimize disk writes, number of dropbox entries, and maximize
12277     // compression, by having more fewer, larger records.
12278     private void logStrictModeViolationToDropBox(
12279             ProcessRecord process,
12280             StrictMode.ViolationInfo info) {
12281         if (info == null) {
12282             return;
12283         }
12284         final boolean isSystemApp = process == null ||
12285                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12286                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12287         final String processName = process == null ? "unknown" : process.processName;
12288         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12289         final DropBoxManager dbox = (DropBoxManager)
12290                 mContext.getSystemService(Context.DROPBOX_SERVICE);
12291
12292         // Exit early if the dropbox isn't configured to accept this report type.
12293         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12294
12295         boolean bufferWasEmpty;
12296         boolean needsFlush;
12297         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12298         synchronized (sb) {
12299             bufferWasEmpty = sb.length() == 0;
12300             appendDropBoxProcessHeaders(process, processName, sb);
12301             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12302             sb.append("System-App: ").append(isSystemApp).append("\n");
12303             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12304             if (info.violationNumThisLoop != 0) {
12305                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12306             }
12307             if (info.numAnimationsRunning != 0) {
12308                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12309             }
12310             if (info.broadcastIntentAction != null) {
12311                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12312             }
12313             if (info.durationMillis != -1) {
12314                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12315             }
12316             if (info.numInstances != -1) {
12317                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12318             }
12319             if (info.tags != null) {
12320                 for (String tag : info.tags) {
12321                     sb.append("Span-Tag: ").append(tag).append("\n");
12322                 }
12323             }
12324             sb.append("\n");
12325             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12326                 sb.append(info.crashInfo.stackTrace);
12327                 sb.append("\n");
12328             }
12329             if (info.message != null) {
12330                 sb.append(info.message);
12331                 sb.append("\n");
12332             }
12333
12334             // Only buffer up to ~64k.  Various logging bits truncate
12335             // things at 128k.
12336             needsFlush = (sb.length() > 64 * 1024);
12337         }
12338
12339         // Flush immediately if the buffer's grown too large, or this
12340         // is a non-system app.  Non-system apps are isolated with a
12341         // different tag & policy and not batched.
12342         //
12343         // Batching is useful during internal testing with
12344         // StrictMode settings turned up high.  Without batching,
12345         // thousands of separate files could be created on boot.
12346         if (!isSystemApp || needsFlush) {
12347             new Thread("Error dump: " + dropboxTag) {
12348                 @Override
12349                 public void run() {
12350                     String report;
12351                     synchronized (sb) {
12352                         report = sb.toString();
12353                         sb.delete(0, sb.length());
12354                         sb.trimToSize();
12355                     }
12356                     if (report.length() != 0) {
12357                         dbox.addText(dropboxTag, report);
12358                     }
12359                 }
12360             }.start();
12361             return;
12362         }
12363
12364         // System app batching:
12365         if (!bufferWasEmpty) {
12366             // An existing dropbox-writing thread is outstanding, so
12367             // we don't need to start it up.  The existing thread will
12368             // catch the buffer appends we just did.
12369             return;
12370         }
12371
12372         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12373         // (After this point, we shouldn't access AMS internal data structures.)
12374         new Thread("Error dump: " + dropboxTag) {
12375             @Override
12376             public void run() {
12377                 // 5 second sleep to let stacks arrive and be batched together
12378                 try {
12379                     Thread.sleep(5000);  // 5 seconds
12380                 } catch (InterruptedException e) {}
12381
12382                 String errorReport;
12383                 synchronized (mStrictModeBuffer) {
12384                     errorReport = mStrictModeBuffer.toString();
12385                     if (errorReport.length() == 0) {
12386                         return;
12387                     }
12388                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12389                     mStrictModeBuffer.trimToSize();
12390                 }
12391                 dbox.addText(dropboxTag, errorReport);
12392             }
12393         }.start();
12394     }
12395
12396     /**
12397      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12398      * @param app object of the crashing app, null for the system server
12399      * @param tag reported by the caller
12400      * @param system whether this wtf is coming from the system
12401      * @param crashInfo describing the context of the error
12402      * @return true if the process should exit immediately (WTF is fatal)
12403      */
12404     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12405             final ApplicationErrorReport.CrashInfo crashInfo) {
12406         final int callingUid = Binder.getCallingUid();
12407         final int callingPid = Binder.getCallingPid();
12408
12409         if (system) {
12410             // If this is coming from the system, we could very well have low-level
12411             // system locks held, so we want to do this all asynchronously.  And we
12412             // never want this to become fatal, so there is that too.
12413             mHandler.post(new Runnable() {
12414                 @Override public void run() {
12415                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12416                 }
12417             });
12418             return false;
12419         }
12420
12421         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12422                 crashInfo);
12423
12424         if (r != null && r.pid != Process.myPid() &&
12425                 Settings.Global.getInt(mContext.getContentResolver(),
12426                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
12427             crashApplication(r, crashInfo);
12428             return true;
12429         } else {
12430             return false;
12431         }
12432     }
12433
12434     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12435             final ApplicationErrorReport.CrashInfo crashInfo) {
12436         final ProcessRecord r = findAppProcess(app, "WTF");
12437         final String processName = app == null ? "system_server"
12438                 : (r == null ? "unknown" : r.processName);
12439
12440         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12441                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12442
12443         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12444
12445         return r;
12446     }
12447
12448     /**
12449      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12450      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12451      */
12452     private ProcessRecord findAppProcess(IBinder app, String reason) {
12453         if (app == null) {
12454             return null;
12455         }
12456
12457         synchronized (this) {
12458             final int NP = mProcessNames.getMap().size();
12459             for (int ip=0; ip<NP; ip++) {
12460                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12461                 final int NA = apps.size();
12462                 for (int ia=0; ia<NA; ia++) {
12463                     ProcessRecord p = apps.valueAt(ia);
12464                     if (p.thread != null && p.thread.asBinder() == app) {
12465                         return p;
12466                     }
12467                 }
12468             }
12469
12470             Slog.w(TAG, "Can't find mystery application for " + reason
12471                     + " from pid=" + Binder.getCallingPid()
12472                     + " uid=" + Binder.getCallingUid() + ": " + app);
12473             return null;
12474         }
12475     }
12476
12477     /**
12478      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12479      * to append various headers to the dropbox log text.
12480      */
12481     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12482             StringBuilder sb) {
12483         // Watchdog thread ends up invoking this function (with
12484         // a null ProcessRecord) to add the stack file to dropbox.
12485         // Do not acquire a lock on this (am) in such cases, as it
12486         // could cause a potential deadlock, if and when watchdog
12487         // is invoked due to unavailability of lock on am and it
12488         // would prevent watchdog from killing system_server.
12489         if (process == null) {
12490             sb.append("Process: ").append(processName).append("\n");
12491             return;
12492         }
12493         // Note: ProcessRecord 'process' is guarded by the service
12494         // instance.  (notably process.pkgList, which could otherwise change
12495         // concurrently during execution of this method)
12496         synchronized (this) {
12497             sb.append("Process: ").append(processName).append("\n");
12498             int flags = process.info.flags;
12499             IPackageManager pm = AppGlobals.getPackageManager();
12500             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12501             for (int ip=0; ip<process.pkgList.size(); ip++) {
12502                 String pkg = process.pkgList.keyAt(ip);
12503                 sb.append("Package: ").append(pkg);
12504                 try {
12505                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12506                     if (pi != null) {
12507                         sb.append(" v").append(pi.versionCode);
12508                         if (pi.versionName != null) {
12509                             sb.append(" (").append(pi.versionName).append(")");
12510                         }
12511                     }
12512                 } catch (RemoteException e) {
12513                     Slog.e(TAG, "Error getting package info: " + pkg, e);
12514                 }
12515                 sb.append("\n");
12516             }
12517         }
12518     }
12519
12520     private static String processClass(ProcessRecord process) {
12521         if (process == null || process.pid == MY_PID) {
12522             return "system_server";
12523         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12524             return "system_app";
12525         } else {
12526             return "data_app";
12527         }
12528     }
12529
12530     /**
12531      * Write a description of an error (crash, WTF, ANR) to the drop box.
12532      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12533      * @param process which caused the error, null means the system server
12534      * @param activity which triggered the error, null if unknown
12535      * @param parent activity related to the error, null if unknown
12536      * @param subject line related to the error, null if absent
12537      * @param report in long form describing the error, null if absent
12538      * @param logFile to include in the report, null if none
12539      * @param crashInfo giving an application stack trace, null if absent
12540      */
12541     public void addErrorToDropBox(String eventType,
12542             ProcessRecord process, String processName, ActivityRecord activity,
12543             ActivityRecord parent, String subject,
12544             final String report, final File logFile,
12545             final ApplicationErrorReport.CrashInfo crashInfo) {
12546         // NOTE -- this must never acquire the ActivityManagerService lock,
12547         // otherwise the watchdog may be prevented from resetting the system.
12548
12549         final String dropboxTag = processClass(process) + "_" + eventType;
12550         final DropBoxManager dbox = (DropBoxManager)
12551                 mContext.getSystemService(Context.DROPBOX_SERVICE);
12552
12553         // Exit early if the dropbox isn't configured to accept this report type.
12554         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12555
12556         final StringBuilder sb = new StringBuilder(1024);
12557         appendDropBoxProcessHeaders(process, processName, sb);
12558         if (activity != null) {
12559             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12560         }
12561         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12562             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12563         }
12564         if (parent != null && parent != activity) {
12565             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12566         }
12567         if (subject != null) {
12568             sb.append("Subject: ").append(subject).append("\n");
12569         }
12570         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12571         if (Debug.isDebuggerConnected()) {
12572             sb.append("Debugger: Connected\n");
12573         }
12574         sb.append("\n");
12575
12576         // Do the rest in a worker thread to avoid blocking the caller on I/O
12577         // (After this point, we shouldn't access AMS internal data structures.)
12578         Thread worker = new Thread("Error dump: " + dropboxTag) {
12579             @Override
12580             public void run() {
12581                 if (report != null) {
12582                     sb.append(report);
12583                 }
12584                 if (logFile != null) {
12585                     try {
12586                         sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12587                                     "\n\n[[TRUNCATED]]"));
12588                     } catch (IOException e) {
12589                         Slog.e(TAG, "Error reading " + logFile, e);
12590                     }
12591                 }
12592                 if (crashInfo != null && crashInfo.stackTrace != null) {
12593                     sb.append(crashInfo.stackTrace);
12594                 }
12595
12596                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12597                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12598                 if (lines > 0) {
12599                     sb.append("\n");
12600
12601                     // Merge several logcat streams, and take the last N lines
12602                     InputStreamReader input = null;
12603                     try {
12604                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12605                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12606                                 "-b", "crash",
12607                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12608
12609                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
12610                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
12611                         input = new InputStreamReader(logcat.getInputStream());
12612
12613                         int num;
12614                         char[] buf = new char[8192];
12615                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12616                     } catch (IOException e) {
12617                         Slog.e(TAG, "Error running logcat", e);
12618                     } finally {
12619                         if (input != null) try { input.close(); } catch (IOException e) {}
12620                     }
12621                 }
12622
12623                 dbox.addText(dropboxTag, sb.toString());
12624             }
12625         };
12626
12627         if (process == null) {
12628             // If process is null, we are being called from some internal code
12629             // and may be about to die -- run this synchronously.
12630             worker.run();
12631         } else {
12632             worker.start();
12633         }
12634     }
12635
12636     /**
12637      * Bring up the "unexpected error" dialog box for a crashing app.
12638      * Deal with edge cases (intercepts from instrumented applications,
12639      * ActivityController, error intent receivers, that sort of thing).
12640      * @param r the application crashing
12641      * @param crashInfo describing the failure
12642      */
12643     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12644         long timeMillis = System.currentTimeMillis();
12645         String shortMsg = crashInfo.exceptionClassName;
12646         String longMsg = crashInfo.exceptionMessage;
12647         String stackTrace = crashInfo.stackTrace;
12648         if (shortMsg != null && longMsg != null) {
12649             longMsg = shortMsg + ": " + longMsg;
12650         } else if (shortMsg != null) {
12651             longMsg = shortMsg;
12652         }
12653
12654         AppErrorResult result = new AppErrorResult();
12655         synchronized (this) {
12656             if (mController != null) {
12657                 try {
12658                     String name = r != null ? r.processName : null;
12659                     int pid = r != null ? r.pid : Binder.getCallingPid();
12660                     int uid = r != null ? r.info.uid : Binder.getCallingUid();
12661                     if (!mController.appCrashed(name, pid,
12662                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12663                         if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12664                                 && "Native crash".equals(crashInfo.exceptionClassName)) {
12665                             Slog.w(TAG, "Skip killing native crashed app " + name
12666                                     + "(" + pid + ") during testing");
12667                         } else {
12668                             Slog.w(TAG, "Force-killing crashed app " + name
12669                                     + " at watcher's request");
12670                             if (r != null) {
12671                                 r.kill("crash", true);
12672                             } else {
12673                                 // Huh.
12674                                 Process.killProcess(pid);
12675                                 killProcessGroup(uid, pid);
12676                             }
12677                         }
12678                         return;
12679                     }
12680                 } catch (RemoteException e) {
12681                     mController = null;
12682                     Watchdog.getInstance().setActivityController(null);
12683                 }
12684             }
12685
12686             final long origId = Binder.clearCallingIdentity();
12687
12688             // If this process is running instrumentation, finish it.
12689             if (r != null && r.instrumentationClass != null) {
12690                 Slog.w(TAG, "Error in app " + r.processName
12691                       + " running instrumentation " + r.instrumentationClass + ":");
12692                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12693                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12694                 Bundle info = new Bundle();
12695                 info.putString("shortMsg", shortMsg);
12696                 info.putString("longMsg", longMsg);
12697                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12698                 Binder.restoreCallingIdentity(origId);
12699                 return;
12700             }
12701
12702             // Log crash in battery stats.
12703             if (r != null) {
12704                 mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12705             }
12706
12707             // If we can't identify the process or it's already exceeded its crash quota,
12708             // quit right away without showing a crash dialog.
12709             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12710                 Binder.restoreCallingIdentity(origId);
12711                 return;
12712             }
12713
12714             Message msg = Message.obtain();
12715             msg.what = SHOW_ERROR_MSG;
12716             HashMap data = new HashMap();
12717             data.put("result", result);
12718             data.put("app", r);
12719             msg.obj = data;
12720             mUiHandler.sendMessage(msg);
12721
12722             Binder.restoreCallingIdentity(origId);
12723         }
12724
12725         int res = result.get();
12726
12727         Intent appErrorIntent = null;
12728         synchronized (this) {
12729             if (r != null && !r.isolated) {
12730                 // XXX Can't keep track of crash time for isolated processes,
12731                 // since they don't have a persistent identity.
12732                 mProcessCrashTimes.put(r.info.processName, r.uid,
12733                         SystemClock.uptimeMillis());
12734             }
12735             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12736                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12737             }
12738         }
12739
12740         if (appErrorIntent != null) {
12741             try {
12742                 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12743             } catch (ActivityNotFoundException e) {
12744                 Slog.w(TAG, "bug report receiver dissappeared", e);
12745             }
12746         }
12747     }
12748
12749     Intent createAppErrorIntentLocked(ProcessRecord r,
12750             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12751         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12752         if (report == null) {
12753             return null;
12754         }
12755         Intent result = new Intent(Intent.ACTION_APP_ERROR);
12756         result.setComponent(r.errorReportReceiver);
12757         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12758         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12759         return result;
12760     }
12761
12762     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12763             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12764         if (r.errorReportReceiver == null) {
12765             return null;
12766         }
12767
12768         if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12769             return null;
12770         }
12771
12772         ApplicationErrorReport report = new ApplicationErrorReport();
12773         report.packageName = r.info.packageName;
12774         report.installerPackageName = r.errorReportReceiver.getPackageName();
12775         report.processName = r.processName;
12776         report.time = timeMillis;
12777         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12778
12779         if (r.crashing || r.forceCrashReport) {
12780             report.type = ApplicationErrorReport.TYPE_CRASH;
12781             report.crashInfo = crashInfo;
12782         } else if (r.notResponding) {
12783             report.type = ApplicationErrorReport.TYPE_ANR;
12784             report.anrInfo = new ApplicationErrorReport.AnrInfo();
12785
12786             report.anrInfo.activity = r.notRespondingReport.tag;
12787             report.anrInfo.cause = r.notRespondingReport.shortMsg;
12788             report.anrInfo.info = r.notRespondingReport.longMsg;
12789         }
12790
12791         return report;
12792     }
12793
12794     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12795         enforceNotIsolatedCaller("getProcessesInErrorState");
12796         // assume our apps are happy - lazy create the list
12797         List<ActivityManager.ProcessErrorStateInfo> errList = null;
12798
12799         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12800                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12801         int userId = UserHandle.getUserId(Binder.getCallingUid());
12802
12803         synchronized (this) {
12804
12805             // iterate across all processes
12806             for (int i=mLruProcesses.size()-1; i>=0; i--) {
12807                 ProcessRecord app = mLruProcesses.get(i);
12808                 if (!allUsers && app.userId != userId) {
12809                     continue;
12810                 }
12811                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
12812                     // This one's in trouble, so we'll generate a report for it
12813                     // crashes are higher priority (in case there's a crash *and* an anr)
12814                     ActivityManager.ProcessErrorStateInfo report = null;
12815                     if (app.crashing) {
12816                         report = app.crashingReport;
12817                     } else if (app.notResponding) {
12818                         report = app.notRespondingReport;
12819                     }
12820
12821                     if (report != null) {
12822                         if (errList == null) {
12823                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12824                         }
12825                         errList.add(report);
12826                     } else {
12827                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
12828                                 " crashing = " + app.crashing +
12829                                 " notResponding = " + app.notResponding);
12830                     }
12831                 }
12832             }
12833         }
12834
12835         return errList;
12836     }
12837
12838     static int procStateToImportance(int procState, int memAdj,
12839             ActivityManager.RunningAppProcessInfo currApp) {
12840         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12841         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12842             currApp.lru = memAdj;
12843         } else {
12844             currApp.lru = 0;
12845         }
12846         return imp;
12847     }
12848
12849     private void fillInProcMemInfo(ProcessRecord app,
12850             ActivityManager.RunningAppProcessInfo outInfo) {
12851         outInfo.pid = app.pid;
12852         outInfo.uid = app.info.uid;
12853         if (mHeavyWeightProcess == app) {
12854             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12855         }
12856         if (app.persistent) {
12857             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12858         }
12859         if (app.activities.size() > 0) {
12860             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12861         }
12862         outInfo.lastTrimLevel = app.trimMemoryLevel;
12863         int adj = app.curAdj;
12864         int procState = app.curProcState;
12865         outInfo.importance = procStateToImportance(procState, adj, outInfo);
12866         outInfo.importanceReasonCode = app.adjTypeCode;
12867         outInfo.processState = app.curProcState;
12868     }
12869
12870     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12871         enforceNotIsolatedCaller("getRunningAppProcesses");
12872
12873         final int callingUid = Binder.getCallingUid();
12874
12875         // Lazy instantiation of list
12876         List<ActivityManager.RunningAppProcessInfo> runList = null;
12877         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12878                 callingUid) == PackageManager.PERMISSION_GRANTED;
12879         final int userId = UserHandle.getUserId(callingUid);
12880         final boolean allUids = isGetTasksAllowed(
12881                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12882
12883         synchronized (this) {
12884             // Iterate across all processes
12885             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12886                 ProcessRecord app = mLruProcesses.get(i);
12887                 if ((!allUsers && app.userId != userId)
12888                         || (!allUids && app.uid != callingUid)) {
12889                     continue;
12890                 }
12891                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12892                     // Generate process state info for running application
12893                     ActivityManager.RunningAppProcessInfo currApp =
12894                         new ActivityManager.RunningAppProcessInfo(app.processName,
12895                                 app.pid, app.getPackageList());
12896                     fillInProcMemInfo(app, currApp);
12897                     if (app.adjSource instanceof ProcessRecord) {
12898                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12899                         currApp.importanceReasonImportance =
12900                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
12901                                         app.adjSourceProcState);
12902                     } else if (app.adjSource instanceof ActivityRecord) {
12903                         ActivityRecord r = (ActivityRecord)app.adjSource;
12904                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12905                     }
12906                     if (app.adjTarget instanceof ComponentName) {
12907                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12908                     }
12909                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12910                     //        + " lru=" + currApp.lru);
12911                     if (runList == null) {
12912                         runList = new ArrayList<>();
12913                     }
12914                     runList.add(currApp);
12915                 }
12916             }
12917         }
12918         return runList;
12919     }
12920
12921     public List<ApplicationInfo> getRunningExternalApplications() {
12922         enforceNotIsolatedCaller("getRunningExternalApplications");
12923         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12924         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12925         if (runningApps != null && runningApps.size() > 0) {
12926             Set<String> extList = new HashSet<String>();
12927             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12928                 if (app.pkgList != null) {
12929                     for (String pkg : app.pkgList) {
12930                         extList.add(pkg);
12931                     }
12932                 }
12933             }
12934             IPackageManager pm = AppGlobals.getPackageManager();
12935             for (String pkg : extList) {
12936                 try {
12937                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12938                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12939                         retList.add(info);
12940                     }
12941                 } catch (RemoteException e) {
12942                 }
12943             }
12944         }
12945         return retList;
12946     }
12947
12948     @Override
12949     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12950         enforceNotIsolatedCaller("getMyMemoryState");
12951         synchronized (this) {
12952             ProcessRecord proc;
12953             synchronized (mPidsSelfLocked) {
12954                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
12955             }
12956             fillInProcMemInfo(proc, outInfo);
12957         }
12958     }
12959
12960     @Override
12961     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12962         if (checkCallingPermission(android.Manifest.permission.DUMP)
12963                 != PackageManager.PERMISSION_GRANTED) {
12964             pw.println("Permission Denial: can't dump ActivityManager from from pid="
12965                     + Binder.getCallingPid()
12966                     + ", uid=" + Binder.getCallingUid()
12967                     + " without permission "
12968                     + android.Manifest.permission.DUMP);
12969             return;
12970         }
12971
12972         boolean dumpAll = false;
12973         boolean dumpClient = false;
12974         String dumpPackage = null;
12975
12976         int opti = 0;
12977         while (opti < args.length) {
12978             String opt = args[opti];
12979             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12980                 break;
12981             }
12982             opti++;
12983             if ("-a".equals(opt)) {
12984                 dumpAll = true;
12985             } else if ("-c".equals(opt)) {
12986                 dumpClient = true;
12987             } else if ("-p".equals(opt)) {
12988                 if (opti < args.length) {
12989                     dumpPackage = args[opti];
12990                     opti++;
12991                 } else {
12992                     pw.println("Error: -p option requires package argument");
12993                     return;
12994                 }
12995                 dumpClient = true;
12996             } else if ("-h".equals(opt)) {
12997                 pw.println("Activity manager dump options:");
12998                 pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12999                 pw.println("  cmd may be one of:");
13000                 pw.println("    a[ctivities]: activity stack state");
13001                 pw.println("    r[recents]: recent activities state");
13002                 pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
13003                 pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
13004                 pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
13005                 pw.println("    o[om]: out of memory management");
13006                 pw.println("    perm[issions]: URI permission grant state");
13007                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
13008                 pw.println("    provider [COMP_SPEC]: provider client-side state");
13009                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
13010                 pw.println("    as[sociations]: tracked app associations");
13011                 pw.println("    service [COMP_SPEC]: service client-side state");
13012                 pw.println("    package [PACKAGE_NAME]: all state related to given package");
13013                 pw.println("    all: dump all activities");
13014                 pw.println("    top: dump the top activity");
13015                 pw.println("    write: write all pending state to storage");
13016                 pw.println("    track-associations: enable association tracking");
13017                 pw.println("    untrack-associations: disable and clear association tracking");
13018                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
13019                 pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
13020                 pw.println("    a partial substring in a component name, a");
13021                 pw.println("    hex object identifier.");
13022                 pw.println("  -a: include all available server state.");
13023                 pw.println("  -c: include client state.");
13024                 pw.println("  -p: limit output to given package.");
13025                 return;
13026             } else {
13027                 pw.println("Unknown argument: " + opt + "; use -h for help");
13028             }
13029         }
13030
13031         long origId = Binder.clearCallingIdentity();
13032         boolean more = false;
13033         // Is the caller requesting to dump a particular piece of data?
13034         if (opti < args.length) {
13035             String cmd = args[opti];
13036             opti++;
13037             if ("activities".equals(cmd) || "a".equals(cmd)) {
13038                 synchronized (this) {
13039                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13040                 }
13041             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13042                 synchronized (this) {
13043                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13044                 }
13045             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13046                 String[] newArgs;
13047                 String name;
13048                 if (opti >= args.length) {
13049                     name = null;
13050                     newArgs = EMPTY_STRING_ARRAY;
13051                 } else {
13052                     dumpPackage = args[opti];
13053                     opti++;
13054                     newArgs = new String[args.length - opti];
13055                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13056                             args.length - opti);
13057                 }
13058                 synchronized (this) {
13059                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13060                 }
13061             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13062                 String[] newArgs;
13063                 String name;
13064                 if (opti >= args.length) {
13065                     name = null;
13066                     newArgs = EMPTY_STRING_ARRAY;
13067                 } else {
13068                     dumpPackage = args[opti];
13069                     opti++;
13070                     newArgs = new String[args.length - opti];
13071                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13072                             args.length - opti);
13073                 }
13074                 synchronized (this) {
13075                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13076                 }
13077             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13078                 String[] newArgs;
13079                 String name;
13080                 if (opti >= args.length) {
13081                     name = null;
13082                     newArgs = EMPTY_STRING_ARRAY;
13083                 } else {
13084                     dumpPackage = args[opti];
13085                     opti++;
13086                     newArgs = new String[args.length - opti];
13087                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13088                             args.length - opti);
13089                 }
13090                 synchronized (this) {
13091                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13092                 }
13093             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13094                 synchronized (this) {
13095                     dumpOomLocked(fd, pw, args, opti, true);
13096                 }
13097             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13098                 synchronized (this) {
13099                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
13100                 }
13101             } else if ("provider".equals(cmd)) {
13102                 String[] newArgs;
13103                 String name;
13104                 if (opti >= args.length) {
13105                     name = null;
13106                     newArgs = EMPTY_STRING_ARRAY;
13107                 } else {
13108                     name = args[opti];
13109                     opti++;
13110                     newArgs = new String[args.length - opti];
13111                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13112                 }
13113                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13114                     pw.println("No providers match: " + name);
13115                     pw.println("Use -h for help.");
13116                 }
13117             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13118                 synchronized (this) {
13119                     dumpProvidersLocked(fd, pw, args, opti, true, null);
13120                 }
13121             } else if ("service".equals(cmd)) {
13122                 String[] newArgs;
13123                 String name;
13124                 if (opti >= args.length) {
13125                     name = null;
13126                     newArgs = EMPTY_STRING_ARRAY;
13127                 } else {
13128                     name = args[opti];
13129                     opti++;
13130                     newArgs = new String[args.length - opti];
13131                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13132                             args.length - opti);
13133                 }
13134                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13135                     pw.println("No services match: " + name);
13136                     pw.println("Use -h for help.");
13137                 }
13138             } else if ("package".equals(cmd)) {
13139                 String[] newArgs;
13140                 if (opti >= args.length) {
13141                     pw.println("package: no package name specified");
13142                     pw.println("Use -h for help.");
13143                 } else {
13144                     dumpPackage = args[opti];
13145                     opti++;
13146                     newArgs = new String[args.length - opti];
13147                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13148                             args.length - opti);
13149                     args = newArgs;
13150                     opti = 0;
13151                     more = true;
13152                 }
13153             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13154                 synchronized (this) {
13155                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13156                 }
13157             } else if ("services".equals(cmd) || "s".equals(cmd)) {
13158                 synchronized (this) {
13159                     mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13160                 }
13161             } else if ("write".equals(cmd)) {
13162                 mTaskPersister.flush();
13163                 pw.println("All tasks persisted.");
13164                 return;
13165             } else if ("track-associations".equals(cmd)) {
13166                 synchronized (this) {
13167                     if (!mTrackingAssociations) {
13168                         mTrackingAssociations = true;
13169                         pw.println("Association tracking started.");
13170                     } else {
13171                         pw.println("Association tracking already enabled.");
13172                     }
13173                 }
13174                 return;
13175             } else if ("untrack-associations".equals(cmd)) {
13176                 synchronized (this) {
13177                     if (mTrackingAssociations) {
13178                         mTrackingAssociations = false;
13179                         mAssociations.clear();
13180                         pw.println("Association tracking stopped.");
13181                     } else {
13182                         pw.println("Association tracking not running.");
13183                     }
13184                 }
13185                 return;
13186             } else {
13187                 // Dumping a single activity?
13188                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13189                     pw.println("Bad activity command, or no activities match: " + cmd);
13190                     pw.println("Use -h for help.");
13191                 }
13192             }
13193             if (!more) {
13194                 Binder.restoreCallingIdentity(origId);
13195                 return;
13196             }
13197         }
13198
13199         // No piece of data specified, dump everything.
13200         synchronized (this) {
13201             dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13202             pw.println();
13203             if (dumpAll) {
13204                 pw.println("-------------------------------------------------------------------------------");
13205             }
13206             dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13207             pw.println();
13208             if (dumpAll) {
13209                 pw.println("-------------------------------------------------------------------------------");
13210             }
13211             dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13212             pw.println();
13213             if (dumpAll) {
13214                 pw.println("-------------------------------------------------------------------------------");
13215             }
13216             dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13217             pw.println();
13218             if (dumpAll) {
13219                 pw.println("-------------------------------------------------------------------------------");
13220             }
13221             mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13222             pw.println();
13223             if (dumpAll) {
13224                 pw.println("-------------------------------------------------------------------------------");
13225             }
13226             dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13227             pw.println();
13228             if (dumpAll) {
13229                 pw.println("-------------------------------------------------------------------------------");
13230             }
13231             dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13232             if (mAssociations.size() > 0) {
13233                 pw.println();
13234                 if (dumpAll) {
13235                     pw.println("-------------------------------------------------------------------------------");
13236                 }
13237                 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13238             }
13239             pw.println();
13240             if (dumpAll) {
13241                 pw.println("-------------------------------------------------------------------------------");
13242             }
13243             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13244         }
13245         Binder.restoreCallingIdentity(origId);
13246     }
13247
13248     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13249             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13250         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13251
13252         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13253                 dumpPackage);
13254         boolean needSep = printedAnything;
13255
13256         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13257                 dumpPackage, needSep, "  mFocusedActivity: ");
13258         if (printed) {
13259             printedAnything = true;
13260             needSep = false;
13261         }
13262
13263         if (dumpPackage == null) {
13264             if (needSep) {
13265                 pw.println();
13266             }
13267             needSep = true;
13268             printedAnything = true;
13269             mStackSupervisor.dump(pw, "  ");
13270         }
13271
13272         if (!printedAnything) {
13273             pw.println("  (nothing)");
13274         }
13275     }
13276
13277     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13278             int opti, boolean dumpAll, String dumpPackage) {
13279         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13280
13281         boolean printedAnything = false;
13282
13283         if (mRecentTasks != null && mRecentTasks.size() > 0) {
13284             boolean printedHeader = false;
13285
13286             final int N = mRecentTasks.size();
13287             for (int i=0; i<N; i++) {
13288                 TaskRecord tr = mRecentTasks.get(i);
13289                 if (dumpPackage != null) {
13290                     if (tr.realActivity == null ||
13291                             !dumpPackage.equals(tr.realActivity)) {
13292                         continue;
13293                     }
13294                 }
13295                 if (!printedHeader) {
13296                     pw.println("  Recent tasks:");
13297                     printedHeader = true;
13298                     printedAnything = true;
13299                 }
13300                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13301                         pw.println(tr);
13302                 if (dumpAll) {
13303                     mRecentTasks.get(i).dump(pw, "    ");
13304                 }
13305             }
13306         }
13307
13308         if (!printedAnything) {
13309             pw.println("  (nothing)");
13310         }
13311     }
13312
13313     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13314             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13315         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13316
13317         int dumpUid = 0;
13318         if (dumpPackage != null) {
13319             IPackageManager pm = AppGlobals.getPackageManager();
13320             try {
13321                 dumpUid = pm.getPackageUid(dumpPackage, 0);
13322             } catch (RemoteException e) {
13323             }
13324         }
13325
13326         boolean printedAnything = false;
13327
13328         final long now = SystemClock.uptimeMillis();
13329
13330         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13331             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13332                     = mAssociations.valueAt(i1);
13333             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13334                 SparseArray<ArrayMap<String, Association>> sourceUids
13335                         = targetComponents.valueAt(i2);
13336                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13337                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13338                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13339                         Association ass = sourceProcesses.valueAt(i4);
13340                         if (dumpPackage != null) {
13341                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13342                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13343                                 continue;
13344                             }
13345                         }
13346                         printedAnything = true;
13347                         pw.print("  ");
13348                         pw.print(ass.mTargetProcess);
13349                         pw.print("/");
13350                         UserHandle.formatUid(pw, ass.mTargetUid);
13351                         pw.print(" <- ");
13352                         pw.print(ass.mSourceProcess);
13353                         pw.print("/");
13354                         UserHandle.formatUid(pw, ass.mSourceUid);
13355                         pw.println();
13356                         pw.print("    via ");
13357                         pw.print(ass.mTargetComponent.flattenToShortString());
13358                         pw.println();
13359                         pw.print("    ");
13360                         long dur = ass.mTime;
13361                         if (ass.mNesting > 0) {
13362                             dur += now - ass.mStartTime;
13363                         }
13364                         TimeUtils.formatDuration(dur, pw);
13365                         pw.print(" (");
13366                         pw.print(ass.mCount);
13367                         pw.println(" times)");
13368                         if (ass.mNesting > 0) {
13369                             pw.print("    ");
13370                             pw.print(" Currently active: ");
13371                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
13372                             pw.println();
13373                         }
13374                     }
13375                 }
13376             }
13377
13378         }
13379
13380         if (!printedAnything) {
13381             pw.println("  (nothing)");
13382         }
13383     }
13384
13385     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13386             int opti, boolean dumpAll, String dumpPackage) {
13387         boolean needSep = false;
13388         boolean printedAnything = false;
13389         int numPers = 0;
13390
13391         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13392
13393         if (dumpAll) {
13394             final int NP = mProcessNames.getMap().size();
13395             for (int ip=0; ip<NP; ip++) {
13396                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13397                 final int NA = procs.size();
13398                 for (int ia=0; ia<NA; ia++) {
13399                     ProcessRecord r = procs.valueAt(ia);
13400                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13401                         continue;
13402                     }
13403                     if (!needSep) {
13404                         pw.println("  All known processes:");
13405                         needSep = true;
13406                         printedAnything = true;
13407                     }
13408                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13409                         pw.print(" UID "); pw.print(procs.keyAt(ia));
13410                         pw.print(" "); pw.println(r);
13411                     r.dump(pw, "    ");
13412                     if (r.persistent) {
13413                         numPers++;
13414                     }
13415                 }
13416             }
13417         }
13418
13419         if (mIsolatedProcesses.size() > 0) {
13420             boolean printed = false;
13421             for (int i=0; i<mIsolatedProcesses.size(); i++) {
13422                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
13423                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13424                     continue;
13425                 }
13426                 if (!printed) {
13427                     if (needSep) {
13428                         pw.println();
13429                     }
13430                     pw.println("  Isolated process list (sorted by uid):");
13431                     printedAnything = true;
13432                     printed = true;
13433                     needSep = true;
13434                 }
13435                 pw.println(String.format("%sIsolated #%2d: %s",
13436                         "    ", i, r.toString()));
13437             }
13438         }
13439
13440         if (mActiveUids.size() > 0) {
13441             if (needSep) {
13442                 pw.println();
13443             }
13444             pw.println("  UID states:");
13445             for (int i=0; i<mActiveUids.size(); i++) {
13446                 UidRecord uidRec = mActiveUids.valueAt(i);
13447                 pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13448                 pw.print(": "); pw.println(uidRec);
13449             }
13450             needSep = true;
13451             printedAnything = true;
13452         }
13453
13454         if (mLruProcesses.size() > 0) {
13455             if (needSep) {
13456                 pw.println();
13457             }
13458             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13459                     pw.print(" total, non-act at ");
13460                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13461                     pw.print(", non-svc at ");
13462                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13463                     pw.println("):");
13464             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13465             needSep = true;
13466             printedAnything = true;
13467         }
13468
13469         if (dumpAll || dumpPackage != null) {
13470             synchronized (mPidsSelfLocked) {
13471                 boolean printed = false;
13472                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
13473                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
13474                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13475                         continue;
13476                     }
13477                     if (!printed) {
13478                         if (needSep) pw.println();
13479                         needSep = true;
13480                         pw.println("  PID mappings:");
13481                         printed = true;
13482                         printedAnything = true;
13483                     }
13484                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13485                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13486                 }
13487             }
13488         }
13489
13490         if (mForegroundProcesses.size() > 0) {
13491             synchronized (mPidsSelfLocked) {
13492                 boolean printed = false;
13493                 for (int i=0; i<mForegroundProcesses.size(); i++) {
13494                     ProcessRecord r = mPidsSelfLocked.get(
13495                             mForegroundProcesses.valueAt(i).pid);
13496                     if (dumpPackage != null && (r == null
13497                             || !r.pkgList.containsKey(dumpPackage))) {
13498                         continue;
13499                     }
13500                     if (!printed) {
13501                         if (needSep) pw.println();
13502                         needSep = true;
13503                         pw.println("  Foreground Processes:");
13504                         printed = true;
13505                         printedAnything = true;
13506                     }
13507                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13508                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13509                 }
13510             }
13511         }
13512
13513         if (mPersistentStartingProcesses.size() > 0) {
13514             if (needSep) pw.println();
13515             needSep = true;
13516             printedAnything = true;
13517             pw.println("  Persisent processes that are starting:");
13518             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13519                     "Starting Norm", "Restarting PERS", dumpPackage);
13520         }
13521
13522         if (mRemovedProcesses.size() > 0) {
13523             if (needSep) pw.println();
13524             needSep = true;
13525             printedAnything = true;
13526             pw.println("  Processes that are being removed:");
13527             dumpProcessList(pw, this, mRemovedProcesses, "    ",
13528                     "Removed Norm", "Removed PERS", dumpPackage);
13529         }
13530
13531         if (mProcessesOnHold.size() > 0) {
13532             if (needSep) pw.println();
13533             needSep = true;
13534             printedAnything = true;
13535             pw.println("  Processes that are on old until the system is ready:");
13536             dumpProcessList(pw, this, mProcessesOnHold, "    ",
13537                     "OnHold Norm", "OnHold PERS", dumpPackage);
13538         }
13539
13540         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13541
13542         if (mProcessCrashTimes.getMap().size() > 0) {
13543             boolean printed = false;
13544             long now = SystemClock.uptimeMillis();
13545             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13546             final int NP = pmap.size();
13547             for (int ip=0; ip<NP; ip++) {
13548                 String pname = pmap.keyAt(ip);
13549                 SparseArray<Long> uids = pmap.valueAt(ip);
13550                 final int N = uids.size();
13551                 for (int i=0; i<N; i++) {
13552                     int puid = uids.keyAt(i);
13553                     ProcessRecord r = mProcessNames.get(pname, puid);
13554                     if (dumpPackage != null && (r == null
13555                             || !r.pkgList.containsKey(dumpPackage))) {
13556                         continue;
13557                     }
13558                     if (!printed) {
13559                         if (needSep) pw.println();
13560                         needSep = true;
13561                         pw.println("  Time since processes crashed:");
13562                         printed = true;
13563                         printedAnything = true;
13564                     }
13565                     pw.print("    Process "); pw.print(pname);
13566                             pw.print(" uid "); pw.print(puid);
13567                             pw.print(": last crashed ");
13568                             TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13569                             pw.println(" ago");
13570                 }
13571             }
13572         }
13573
13574         if (mBadProcesses.getMap().size() > 0) {
13575             boolean printed = false;
13576             final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13577             final int NP = pmap.size();
13578             for (int ip=0; ip<NP; ip++) {
13579                 String pname = pmap.keyAt(ip);
13580                 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13581                 final int N = uids.size();
13582                 for (int i=0; i<N; i++) {
13583                     int puid = uids.keyAt(i);
13584                     ProcessRecord r = mProcessNames.get(pname, puid);
13585                     if (dumpPackage != null && (r == null
13586                             || !r.pkgList.containsKey(dumpPackage))) {
13587                         continue;
13588                     }
13589                     if (!printed) {
13590                         if (needSep) pw.println();
13591                         needSep = true;
13592                         pw.println("  Bad processes:");
13593                         printedAnything = true;
13594                     }
13595                     BadProcessInfo info = uids.valueAt(i);
13596                     pw.print("    Bad process "); pw.print(pname);
13597                             pw.print(" uid "); pw.print(puid);
13598                             pw.print(": crashed at time "); pw.println(info.time);
13599                     if (info.shortMsg != null) {
13600                         pw.print("      Short msg: "); pw.println(info.shortMsg);
13601                     }
13602                     if (info.longMsg != null) {
13603                         pw.print("      Long msg: "); pw.println(info.longMsg);
13604                     }
13605                     if (info.stack != null) {
13606                         pw.println("      Stack:");
13607                         int lastPos = 0;
13608                         for (int pos=0; pos<info.stack.length(); pos++) {
13609                             if (info.stack.charAt(pos) == '\n') {
13610                                 pw.print("        ");
13611                                 pw.write(info.stack, lastPos, pos-lastPos);
13612                                 pw.println();
13613                                 lastPos = pos+1;
13614                             }
13615                         }
13616                         if (lastPos < info.stack.length()) {
13617                             pw.print("        ");
13618                             pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13619                             pw.println();
13620                         }
13621                     }
13622                 }
13623             }
13624         }
13625
13626         if (dumpPackage == null) {
13627             pw.println();
13628             needSep = false;
13629             pw.println("  mStartedUsers:");
13630             for (int i=0; i<mStartedUsers.size(); i++) {
13631                 UserState uss = mStartedUsers.valueAt(i);
13632                 pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
13633                         pw.print(": "); uss.dump("", pw);
13634             }
13635             pw.print("  mStartedUserArray: [");
13636             for (int i=0; i<mStartedUserArray.length; i++) {
13637                 if (i > 0) pw.print(", ");
13638                 pw.print(mStartedUserArray[i]);
13639             }
13640             pw.println("]");
13641             pw.print("  mUserLru: [");
13642             for (int i=0; i<mUserLru.size(); i++) {
13643                 if (i > 0) pw.print(", ");
13644                 pw.print(mUserLru.get(i));
13645             }
13646             pw.println("]");
13647             if (dumpAll) {
13648                 pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13649             }
13650             synchronized (mUserProfileGroupIdsSelfLocked) {
13651                 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13652                     pw.println("  mUserProfileGroupIds:");
13653                     for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13654                         pw.print("    User #");
13655                         pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13656                         pw.print(" -> profile #");
13657                         pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13658                     }
13659                 }
13660             }
13661         }
13662         if (mHomeProcess != null && (dumpPackage == null
13663                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13664             if (needSep) {
13665                 pw.println();
13666                 needSep = false;
13667             }
13668             pw.println("  mHomeProcess: " + mHomeProcess);
13669         }
13670         if (mPreviousProcess != null && (dumpPackage == null
13671                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13672             if (needSep) {
13673                 pw.println();
13674                 needSep = false;
13675             }
13676             pw.println("  mPreviousProcess: " + mPreviousProcess);
13677         }
13678         if (dumpAll) {
13679             StringBuilder sb = new StringBuilder(128);
13680             sb.append("  mPreviousProcessVisibleTime: ");
13681             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13682             pw.println(sb);
13683         }
13684         if (mHeavyWeightProcess != null && (dumpPackage == null
13685                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13686             if (needSep) {
13687                 pw.println();
13688                 needSep = false;
13689             }
13690             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13691         }
13692         if (dumpPackage == null) {
13693             pw.println("  mConfiguration: " + mConfiguration);
13694         }
13695         if (dumpAll) {
13696             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13697             if (mCompatModePackages.getPackages().size() > 0) {
13698                 boolean printed = false;
13699                 for (Map.Entry<String, Integer> entry
13700                         : mCompatModePackages.getPackages().entrySet()) {
13701                     String pkg = entry.getKey();
13702                     int mode = entry.getValue();
13703                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13704                         continue;
13705                     }
13706                     if (!printed) {
13707                         pw.println("  mScreenCompatPackages:");
13708                         printed = true;
13709                     }
13710                     pw.print("    "); pw.print(pkg); pw.print(": ");
13711                             pw.print(mode); pw.println();
13712                 }
13713             }
13714         }
13715         if (dumpPackage == null) {
13716             pw.println("  mWakefulness="
13717                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
13718             pw.println("  mSleepTokens=" + mSleepTokens);
13719             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13720                     + lockScreenShownToString());
13721             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13722             if (mRunningVoice != null) {
13723                 pw.println("  mRunningVoice=" + mRunningVoice);
13724                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13725             }
13726         }
13727         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13728                 || mOrigWaitForDebugger) {
13729             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13730                     || dumpPackage.equals(mOrigDebugApp)) {
13731                 if (needSep) {
13732                     pw.println();
13733                     needSep = false;
13734                 }
13735                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13736                         + " mDebugTransient=" + mDebugTransient
13737                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13738             }
13739         }
13740         if (mCurAppTimeTracker != null) {
13741             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
13742         }
13743         if (mMemWatchProcesses.getMap().size() > 0) {
13744             pw.println("  Mem watch processes:");
13745             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13746                     = mMemWatchProcesses.getMap();
13747             for (int i=0; i<procs.size(); i++) {
13748                 final String proc = procs.keyAt(i);
13749                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13750                 for (int j=0; j<uids.size(); j++) {
13751                     if (needSep) {
13752                         pw.println();
13753                         needSep = false;
13754                     }
13755                     StringBuilder sb = new StringBuilder();
13756                     sb.append("    ").append(proc).append('/');
13757                     UserHandle.formatUid(sb, uids.keyAt(j));
13758                     Pair<Long, String> val = uids.valueAt(j);
13759                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13760                     if (val.second != null) {
13761                         sb.append(", report to ").append(val.second);
13762                     }
13763                     pw.println(sb.toString());
13764                 }
13765             }
13766             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13767             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13768             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13769                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13770         }
13771         if (mOpenGlTraceApp != null) {
13772             if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13773                 if (needSep) {
13774                     pw.println();
13775                     needSep = false;
13776                 }
13777                 pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13778             }
13779         }
13780         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13781                 || mProfileFd != null) {
13782             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13783                 if (needSep) {
13784                     pw.println();
13785                     needSep = false;
13786                 }
13787                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13788                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13789                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13790                         + mAutoStopProfiler);
13791                 pw.println("  mProfileType=" + mProfileType);
13792             }
13793         }
13794         if (dumpPackage == null) {
13795             if (mAlwaysFinishActivities || mController != null) {
13796                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13797                         + " mController=" + mController);
13798             }
13799             if (dumpAll) {
13800                 pw.println("  Total persistent processes: " + numPers);
13801                 pw.println("  mProcessesReady=" + mProcessesReady
13802                         + " mSystemReady=" + mSystemReady
13803                         + " mBooted=" + mBooted
13804                         + " mFactoryTest=" + mFactoryTest);
13805                 pw.println("  mBooting=" + mBooting
13806                         + " mCallFinishBooting=" + mCallFinishBooting
13807                         + " mBootAnimationComplete=" + mBootAnimationComplete);
13808                 pw.print("  mLastPowerCheckRealtime=");
13809                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13810                         pw.println("");
13811                 pw.print("  mLastPowerCheckUptime=");
13812                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13813                         pw.println("");
13814                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13815                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13816                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13817                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13818                         + " (" + mLruProcesses.size() + " total)"
13819                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13820                         + " mNumServiceProcs=" + mNumServiceProcs
13821                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13822                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13823                         + " mLastMemoryLevel" + mLastMemoryLevel
13824                         + " mLastNumProcesses" + mLastNumProcesses);
13825                 long now = SystemClock.uptimeMillis();
13826                 pw.print("  mLastIdleTime=");
13827                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
13828                         pw.print(" mLowRamSinceLastIdle=");
13829                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13830                         pw.println();
13831             }
13832         }
13833
13834         if (!printedAnything) {
13835             pw.println("  (nothing)");
13836         }
13837     }
13838
13839     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13840             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13841         if (mProcessesToGc.size() > 0) {
13842             boolean printed = false;
13843             long now = SystemClock.uptimeMillis();
13844             for (int i=0; i<mProcessesToGc.size(); i++) {
13845                 ProcessRecord proc = mProcessesToGc.get(i);
13846                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13847                     continue;
13848                 }
13849                 if (!printed) {
13850                     if (needSep) pw.println();
13851                     needSep = true;
13852                     pw.println("  Processes that are waiting to GC:");
13853                     printed = true;
13854                 }
13855                 pw.print("    Process "); pw.println(proc);
13856                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13857                         pw.print(", last gced=");
13858                         pw.print(now-proc.lastRequestedGc);
13859                         pw.print(" ms ago, last lowMem=");
13860                         pw.print(now-proc.lastLowMemory);
13861                         pw.println(" ms ago");
13862
13863             }
13864         }
13865         return needSep;
13866     }
13867
13868     void printOomLevel(PrintWriter pw, String name, int adj) {
13869         pw.print("    ");
13870         if (adj >= 0) {
13871             pw.print(' ');
13872             if (adj < 10) pw.print(' ');
13873         } else {
13874             if (adj > -10) pw.print(' ');
13875         }
13876         pw.print(adj);
13877         pw.print(": ");
13878         pw.print(name);
13879         pw.print(" (");
13880         pw.print(mProcessList.getMemLevel(adj)/1024);
13881         pw.println(" kB)");
13882     }
13883
13884     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13885             int opti, boolean dumpAll) {
13886         boolean needSep = false;
13887
13888         if (mLruProcesses.size() > 0) {
13889             if (needSep) pw.println();
13890             needSep = true;
13891             pw.println("  OOM levels:");
13892             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13893             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13894             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13895             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13896             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13897             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13898             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13899             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13900             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13901             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13902             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13903             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13904             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13905             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13906
13907             if (needSep) pw.println();
13908             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13909                     pw.print(" total, non-act at ");
13910                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13911                     pw.print(", non-svc at ");
13912                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13913                     pw.println("):");
13914             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13915             needSep = true;
13916         }
13917
13918         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13919
13920         pw.println();
13921         pw.println("  mHomeProcess: " + mHomeProcess);
13922         pw.println("  mPreviousProcess: " + mPreviousProcess);
13923         if (mHeavyWeightProcess != null) {
13924             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13925         }
13926
13927         return true;
13928     }
13929
13930     /**
13931      * There are three ways to call this:
13932      *  - no provider specified: dump all the providers
13933      *  - a flattened component name that matched an existing provider was specified as the
13934      *    first arg: dump that one provider
13935      *  - the first arg isn't the flattened component name of an existing provider:
13936      *    dump all providers whose component contains the first arg as a substring
13937      */
13938     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13939             int opti, boolean dumpAll) {
13940         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13941     }
13942
13943     static class ItemMatcher {
13944         ArrayList<ComponentName> components;
13945         ArrayList<String> strings;
13946         ArrayList<Integer> objects;
13947         boolean all;
13948
13949         ItemMatcher() {
13950             all = true;
13951         }
13952
13953         void build(String name) {
13954             ComponentName componentName = ComponentName.unflattenFromString(name);
13955             if (componentName != null) {
13956                 if (components == null) {
13957                     components = new ArrayList<ComponentName>();
13958                 }
13959                 components.add(componentName);
13960                 all = false;
13961             } else {
13962                 int objectId = 0;
13963                 // Not a '/' separated full component name; maybe an object ID?
13964                 try {
13965                     objectId = Integer.parseInt(name, 16);
13966                     if (objects == null) {
13967                         objects = new ArrayList<Integer>();
13968                     }
13969                     objects.add(objectId);
13970                     all = false;
13971                 } catch (RuntimeException e) {
13972                     // Not an integer; just do string match.
13973                     if (strings == null) {
13974                         strings = new ArrayList<String>();
13975                     }
13976                     strings.add(name);
13977                     all = false;
13978                 }
13979             }
13980         }
13981
13982         int build(String[] args, int opti) {
13983             for (; opti<args.length; opti++) {
13984                 String name = args[opti];
13985                 if ("--".equals(name)) {
13986                     return opti+1;
13987                 }
13988                 build(name);
13989             }
13990             return opti;
13991         }
13992
13993         boolean match(Object object, ComponentName comp) {
13994             if (all) {
13995                 return true;
13996             }
13997             if (components != null) {
13998                 for (int i=0; i<components.size(); i++) {
13999                     if (components.get(i).equals(comp)) {
14000                         return true;
14001                     }
14002                 }
14003             }
14004             if (objects != null) {
14005                 for (int i=0; i<objects.size(); i++) {
14006                     if (System.identityHashCode(object) == objects.get(i)) {
14007                         return true;
14008                     }
14009                 }
14010             }
14011             if (strings != null) {
14012                 String flat = comp.flattenToString();
14013                 for (int i=0; i<strings.size(); i++) {
14014                     if (flat.contains(strings.get(i))) {
14015                         return true;
14016                     }
14017                 }
14018             }
14019             return false;
14020         }
14021     }
14022
14023     /**
14024      * There are three things that cmd can be:
14025      *  - a flattened component name that matches an existing activity
14026      *  - the cmd arg isn't the flattened component name of an existing activity:
14027      *    dump all activity whose component contains the cmd as a substring
14028      *  - A hex number of the ActivityRecord object instance.
14029      */
14030     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14031             int opti, boolean dumpAll) {
14032         ArrayList<ActivityRecord> activities;
14033
14034         synchronized (this) {
14035             activities = mStackSupervisor.getDumpActivitiesLocked(name);
14036         }
14037
14038         if (activities.size() <= 0) {
14039             return false;
14040         }
14041
14042         String[] newArgs = new String[args.length - opti];
14043         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14044
14045         TaskRecord lastTask = null;
14046         boolean needSep = false;
14047         for (int i=activities.size()-1; i>=0; i--) {
14048             ActivityRecord r = activities.get(i);
14049             if (needSep) {
14050                 pw.println();
14051             }
14052             needSep = true;
14053             synchronized (this) {
14054                 if (lastTask != r.task) {
14055                     lastTask = r.task;
14056                     pw.print("TASK "); pw.print(lastTask.affinity);
14057                             pw.print(" id="); pw.println(lastTask.taskId);
14058                     if (dumpAll) {
14059                         lastTask.dump(pw, "  ");
14060                     }
14061                 }
14062             }
14063             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14064         }
14065         return true;
14066     }
14067
14068     /**
14069      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14070      * there is a thread associated with the activity.
14071      */
14072     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14073             final ActivityRecord r, String[] args, boolean dumpAll) {
14074         String innerPrefix = prefix + "  ";
14075         synchronized (this) {
14076             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14077                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14078                     pw.print(" pid=");
14079                     if (r.app != null) pw.println(r.app.pid);
14080                     else pw.println("(not running)");
14081             if (dumpAll) {
14082                 r.dump(pw, innerPrefix);
14083             }
14084         }
14085         if (r.app != null && r.app.thread != null) {
14086             // flush anything that is already in the PrintWriter since the thread is going
14087             // to write to the file descriptor directly
14088             pw.flush();
14089             try {
14090                 TransferPipe tp = new TransferPipe();
14091                 try {
14092                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14093                             r.appToken, innerPrefix, args);
14094                     tp.go(fd);
14095                 } finally {
14096                     tp.kill();
14097                 }
14098             } catch (IOException e) {
14099                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14100             } catch (RemoteException e) {
14101                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14102             }
14103         }
14104     }
14105
14106     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14107             int opti, boolean dumpAll, String dumpPackage) {
14108         boolean needSep = false;
14109         boolean onlyHistory = false;
14110         boolean printedAnything = false;
14111
14112         if ("history".equals(dumpPackage)) {
14113             if (opti < args.length && "-s".equals(args[opti])) {
14114                 dumpAll = false;
14115             }
14116             onlyHistory = true;
14117             dumpPackage = null;
14118         }
14119
14120         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14121         if (!onlyHistory && dumpAll) {
14122             if (mRegisteredReceivers.size() > 0) {
14123                 boolean printed = false;
14124                 Iterator it = mRegisteredReceivers.values().iterator();
14125                 while (it.hasNext()) {
14126                     ReceiverList r = (ReceiverList)it.next();
14127                     if (dumpPackage != null && (r.app == null ||
14128                             !dumpPackage.equals(r.app.info.packageName))) {
14129                         continue;
14130                     }
14131                     if (!printed) {
14132                         pw.println("  Registered Receivers:");
14133                         needSep = true;
14134                         printed = true;
14135                         printedAnything = true;
14136                     }
14137                     pw.print("  * "); pw.println(r);
14138                     r.dump(pw, "    ");
14139                 }
14140             }
14141
14142             if (mReceiverResolver.dump(pw, needSep ?
14143                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14144                     "    ", dumpPackage, false, false)) {
14145                 needSep = true;
14146                 printedAnything = true;
14147             }
14148         }
14149
14150         for (BroadcastQueue q : mBroadcastQueues) {
14151             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14152             printedAnything |= needSep;
14153         }
14154
14155         needSep = true;
14156
14157         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14158             for (int user=0; user<mStickyBroadcasts.size(); user++) {
14159                 if (needSep) {
14160                     pw.println();
14161                 }
14162                 needSep = true;
14163                 printedAnything = true;
14164                 pw.print("  Sticky broadcasts for user ");
14165                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14166                 StringBuilder sb = new StringBuilder(128);
14167                 for (Map.Entry<String, ArrayList<Intent>> ent
14168                         : mStickyBroadcasts.valueAt(user).entrySet()) {
14169                     pw.print("  * Sticky action "); pw.print(ent.getKey());
14170                     if (dumpAll) {
14171                         pw.println(":");
14172                         ArrayList<Intent> intents = ent.getValue();
14173                         final int N = intents.size();
14174                         for (int i=0; i<N; i++) {
14175                             sb.setLength(0);
14176                             sb.append("    Intent: ");
14177                             intents.get(i).toShortString(sb, false, true, false, false);
14178                             pw.println(sb.toString());
14179                             Bundle bundle = intents.get(i).getExtras();
14180                             if (bundle != null) {
14181                                 pw.print("      ");
14182                                 pw.println(bundle.toString());
14183                             }
14184                         }
14185                     } else {
14186                         pw.println("");
14187                     }
14188                 }
14189             }
14190         }
14191
14192         if (!onlyHistory && dumpAll) {
14193             pw.println();
14194             for (BroadcastQueue queue : mBroadcastQueues) {
14195                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14196                         + queue.mBroadcastsScheduled);
14197             }
14198             pw.println("  mHandler:");
14199             mHandler.dump(new PrintWriterPrinter(pw), "    ");
14200             needSep = true;
14201             printedAnything = true;
14202         }
14203
14204         if (!printedAnything) {
14205             pw.println("  (nothing)");
14206         }
14207     }
14208
14209     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14210             int opti, boolean dumpAll, String dumpPackage) {
14211         boolean needSep;
14212         boolean printedAnything = false;
14213
14214         ItemMatcher matcher = new ItemMatcher();
14215         matcher.build(args, opti);
14216
14217         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14218
14219         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14220         printedAnything |= needSep;
14221
14222         if (mLaunchingProviders.size() > 0) {
14223             boolean printed = false;
14224             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14225                 ContentProviderRecord r = mLaunchingProviders.get(i);
14226                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14227                     continue;
14228                 }
14229                 if (!printed) {
14230                     if (needSep) pw.println();
14231                     needSep = true;
14232                     pw.println("  Launching content providers:");
14233                     printed = true;
14234                     printedAnything = true;
14235                 }
14236                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
14237                         pw.println(r);
14238             }
14239         }
14240
14241         if (!printedAnything) {
14242             pw.println("  (nothing)");
14243         }
14244     }
14245
14246     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14247             int opti, boolean dumpAll, String dumpPackage) {
14248         boolean needSep = false;
14249         boolean printedAnything = false;
14250
14251         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14252
14253         if (mGrantedUriPermissions.size() > 0) {
14254             boolean printed = false;
14255             int dumpUid = -2;
14256             if (dumpPackage != null) {
14257                 try {
14258                     dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14259                 } catch (NameNotFoundException e) {
14260                     dumpUid = -1;
14261                 }
14262             }
14263             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14264                 int uid = mGrantedUriPermissions.keyAt(i);
14265                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14266                     continue;
14267                 }
14268                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14269                 if (!printed) {
14270                     if (needSep) pw.println();
14271                     needSep = true;
14272                     pw.println("  Granted Uri Permissions:");
14273                     printed = true;
14274                     printedAnything = true;
14275                 }
14276                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14277                 for (UriPermission perm : perms.values()) {
14278                     pw.print("    "); pw.println(perm);
14279                     if (dumpAll) {
14280                         perm.dump(pw, "      ");
14281                     }
14282                 }
14283             }
14284         }
14285
14286         if (!printedAnything) {
14287             pw.println("  (nothing)");
14288         }
14289     }
14290
14291     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14292             int opti, boolean dumpAll, String dumpPackage) {
14293         boolean printed = false;
14294
14295         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14296
14297         if (mIntentSenderRecords.size() > 0) {
14298             Iterator<WeakReference<PendingIntentRecord>> it
14299                     = mIntentSenderRecords.values().iterator();
14300             while (it.hasNext()) {
14301                 WeakReference<PendingIntentRecord> ref = it.next();
14302                 PendingIntentRecord rec = ref != null ? ref.get(): null;
14303                 if (dumpPackage != null && (rec == null
14304                         || !dumpPackage.equals(rec.key.packageName))) {
14305                     continue;
14306                 }
14307                 printed = true;
14308                 if (rec != null) {
14309                     pw.print("  * "); pw.println(rec);
14310                     if (dumpAll) {
14311                         rec.dump(pw, "    ");
14312                     }
14313                 } else {
14314                     pw.print("  * "); pw.println(ref);
14315                 }
14316             }
14317         }
14318
14319         if (!printed) {
14320             pw.println("  (nothing)");
14321         }
14322     }
14323
14324     private static final int dumpProcessList(PrintWriter pw,
14325             ActivityManagerService service, List list,
14326             String prefix, String normalLabel, String persistentLabel,
14327             String dumpPackage) {
14328         int numPers = 0;
14329         final int N = list.size()-1;
14330         for (int i=N; i>=0; i--) {
14331             ProcessRecord r = (ProcessRecord)list.get(i);
14332             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14333                 continue;
14334             }
14335             pw.println(String.format("%s%s #%2d: %s",
14336                     prefix, (r.persistent ? persistentLabel : normalLabel),
14337                     i, r.toString()));
14338             if (r.persistent) {
14339                 numPers++;
14340             }
14341         }
14342         return numPers;
14343     }
14344
14345     private static final boolean dumpProcessOomList(PrintWriter pw,
14346             ActivityManagerService service, List<ProcessRecord> origList,
14347             String prefix, String normalLabel, String persistentLabel,
14348             boolean inclDetails, String dumpPackage) {
14349
14350         ArrayList<Pair<ProcessRecord, Integer>> list
14351                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14352         for (int i=0; i<origList.size(); i++) {
14353             ProcessRecord r = origList.get(i);
14354             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14355                 continue;
14356             }
14357             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14358         }
14359
14360         if (list.size() <= 0) {
14361             return false;
14362         }
14363
14364         Comparator<Pair<ProcessRecord, Integer>> comparator
14365                 = new Comparator<Pair<ProcessRecord, Integer>>() {
14366             @Override
14367             public int compare(Pair<ProcessRecord, Integer> object1,
14368                     Pair<ProcessRecord, Integer> object2) {
14369                 if (object1.first.setAdj != object2.first.setAdj) {
14370                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14371                 }
14372                 if (object1.second.intValue() != object2.second.intValue()) {
14373                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14374                 }
14375                 return 0;
14376             }
14377         };
14378
14379         Collections.sort(list, comparator);
14380
14381         final long curRealtime = SystemClock.elapsedRealtime();
14382         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14383         final long curUptime = SystemClock.uptimeMillis();
14384         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14385
14386         for (int i=list.size()-1; i>=0; i--) {
14387             ProcessRecord r = list.get(i).first;
14388             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14389             char schedGroup;
14390             switch (r.setSchedGroup) {
14391                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14392                     schedGroup = 'B';
14393                     break;
14394                 case Process.THREAD_GROUP_DEFAULT:
14395                     schedGroup = 'F';
14396                     break;
14397                 default:
14398                     schedGroup = '?';
14399                     break;
14400             }
14401             char foreground;
14402             if (r.foregroundActivities) {
14403                 foreground = 'A';
14404             } else if (r.foregroundServices) {
14405                 foreground = 'S';
14406             } else {
14407                 foreground = ' ';
14408             }
14409             String procState = ProcessList.makeProcStateString(r.curProcState);
14410             pw.print(prefix);
14411             pw.print(r.persistent ? persistentLabel : normalLabel);
14412             pw.print(" #");
14413             int num = (origList.size()-1)-list.get(i).second;
14414             if (num < 10) pw.print(' ');
14415             pw.print(num);
14416             pw.print(": ");
14417             pw.print(oomAdj);
14418             pw.print(' ');
14419             pw.print(schedGroup);
14420             pw.print('/');
14421             pw.print(foreground);
14422             pw.print('/');
14423             pw.print(procState);
14424             pw.print(" trm:");
14425             if (r.trimMemoryLevel < 10) pw.print(' ');
14426             pw.print(r.trimMemoryLevel);
14427             pw.print(' ');
14428             pw.print(r.toShortString());
14429             pw.print(" (");
14430             pw.print(r.adjType);
14431             pw.println(')');
14432             if (r.adjSource != null || r.adjTarget != null) {
14433                 pw.print(prefix);
14434                 pw.print("    ");
14435                 if (r.adjTarget instanceof ComponentName) {
14436                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14437                 } else if (r.adjTarget != null) {
14438                     pw.print(r.adjTarget.toString());
14439                 } else {
14440                     pw.print("{null}");
14441                 }
14442                 pw.print("<=");
14443                 if (r.adjSource instanceof ProcessRecord) {
14444                     pw.print("Proc{");
14445                     pw.print(((ProcessRecord)r.adjSource).toShortString());
14446                     pw.println("}");
14447                 } else if (r.adjSource != null) {
14448                     pw.println(r.adjSource.toString());
14449                 } else {
14450                     pw.println("{null}");
14451                 }
14452             }
14453             if (inclDetails) {
14454                 pw.print(prefix);
14455                 pw.print("    ");
14456                 pw.print("oom: max="); pw.print(r.maxAdj);
14457                 pw.print(" curRaw="); pw.print(r.curRawAdj);
14458                 pw.print(" setRaw="); pw.print(r.setRawAdj);
14459                 pw.print(" cur="); pw.print(r.curAdj);
14460                 pw.print(" set="); pw.println(r.setAdj);
14461                 pw.print(prefix);
14462                 pw.print("    ");
14463                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14464                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14465                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14466                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14467                 pw.println();
14468                 pw.print(prefix);
14469                 pw.print("    ");
14470                 pw.print("cached="); pw.print(r.cached);
14471                 pw.print(" empty="); pw.print(r.empty);
14472                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14473
14474                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14475                     if (r.lastWakeTime != 0) {
14476                         long wtime;
14477                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14478                         synchronized (stats) {
14479                             wtime = stats.getProcessWakeTime(r.info.uid,
14480                                     r.pid, curRealtime);
14481                         }
14482                         long timeUsed = wtime - r.lastWakeTime;
14483                         pw.print(prefix);
14484                         pw.print("    ");
14485                         pw.print("keep awake over ");
14486                         TimeUtils.formatDuration(realtimeSince, pw);
14487                         pw.print(" used ");
14488                         TimeUtils.formatDuration(timeUsed, pw);
14489                         pw.print(" (");
14490                         pw.print((timeUsed*100)/realtimeSince);
14491                         pw.println("%)");
14492                     }
14493                     if (r.lastCpuTime != 0) {
14494                         long timeUsed = r.curCpuTime - r.lastCpuTime;
14495                         pw.print(prefix);
14496                         pw.print("    ");
14497                         pw.print("run cpu over ");
14498                         TimeUtils.formatDuration(uptimeSince, pw);
14499                         pw.print(" used ");
14500                         TimeUtils.formatDuration(timeUsed, pw);
14501                         pw.print(" (");
14502                         pw.print((timeUsed*100)/uptimeSince);
14503                         pw.println("%)");
14504                     }
14505                 }
14506             }
14507         }
14508         return true;
14509     }
14510
14511     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14512             String[] args) {
14513         ArrayList<ProcessRecord> procs;
14514         synchronized (this) {
14515             if (args != null && args.length > start
14516                     && args[start].charAt(0) != '-') {
14517                 procs = new ArrayList<ProcessRecord>();
14518                 int pid = -1;
14519                 try {
14520                     pid = Integer.parseInt(args[start]);
14521                 } catch (NumberFormatException e) {
14522                 }
14523                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14524                     ProcessRecord proc = mLruProcesses.get(i);
14525                     if (proc.pid == pid) {
14526                         procs.add(proc);
14527                     } else if (allPkgs && proc.pkgList != null
14528                             && proc.pkgList.containsKey(args[start])) {
14529                         procs.add(proc);
14530                     } else if (proc.processName.equals(args[start])) {
14531                         procs.add(proc);
14532                     }
14533                 }
14534                 if (procs.size() <= 0) {
14535                     return null;
14536                 }
14537             } else {
14538                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
14539             }
14540         }
14541         return procs;
14542     }
14543
14544     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14545             PrintWriter pw, String[] args) {
14546         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14547         if (procs == null) {
14548             pw.println("No process found for: " + args[0]);
14549             return;
14550         }
14551
14552         long uptime = SystemClock.uptimeMillis();
14553         long realtime = SystemClock.elapsedRealtime();
14554         pw.println("Applications Graphics Acceleration Info:");
14555         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14556
14557         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14558             ProcessRecord r = procs.get(i);
14559             if (r.thread != null) {
14560                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14561                 pw.flush();
14562                 try {
14563                     TransferPipe tp = new TransferPipe();
14564                     try {
14565                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14566                         tp.go(fd);
14567                     } finally {
14568                         tp.kill();
14569                     }
14570                 } catch (IOException e) {
14571                     pw.println("Failure while dumping the app: " + r);
14572                     pw.flush();
14573                 } catch (RemoteException e) {
14574                     pw.println("Got a RemoteException while dumping the app " + r);
14575                     pw.flush();
14576                 }
14577             }
14578         }
14579     }
14580
14581     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14582         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14583         if (procs == null) {
14584             pw.println("No process found for: " + args[0]);
14585             return;
14586         }
14587
14588         pw.println("Applications Database Info:");
14589
14590         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14591             ProcessRecord r = procs.get(i);
14592             if (r.thread != null) {
14593                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14594                 pw.flush();
14595                 try {
14596                     TransferPipe tp = new TransferPipe();
14597                     try {
14598                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14599                         tp.go(fd);
14600                     } finally {
14601                         tp.kill();
14602                     }
14603                 } catch (IOException e) {
14604                     pw.println("Failure while dumping the app: " + r);
14605                     pw.flush();
14606                 } catch (RemoteException e) {
14607                     pw.println("Got a RemoteException while dumping the app " + r);
14608                     pw.flush();
14609                 }
14610             }
14611         }
14612     }
14613
14614     final static class MemItem {
14615         final boolean isProc;
14616         final String label;
14617         final String shortLabel;
14618         final long pss;
14619         final int id;
14620         final boolean hasActivities;
14621         ArrayList<MemItem> subitems;
14622
14623         public MemItem(String _label, String _shortLabel, long _pss, int _id,
14624                 boolean _hasActivities) {
14625             isProc = true;
14626             label = _label;
14627             shortLabel = _shortLabel;
14628             pss = _pss;
14629             id = _id;
14630             hasActivities = _hasActivities;
14631         }
14632
14633         public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14634             isProc = false;
14635             label = _label;
14636             shortLabel = _shortLabel;
14637             pss = _pss;
14638             id = _id;
14639             hasActivities = false;
14640         }
14641     }
14642
14643     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14644             ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14645         if (sort && !isCompact) {
14646             Collections.sort(items, new Comparator<MemItem>() {
14647                 @Override
14648                 public int compare(MemItem lhs, MemItem rhs) {
14649                     if (lhs.pss < rhs.pss) {
14650                         return 1;
14651                     } else if (lhs.pss > rhs.pss) {
14652                         return -1;
14653                     }
14654                     return 0;
14655                 }
14656             });
14657         }
14658
14659         for (int i=0; i<items.size(); i++) {
14660             MemItem mi = items.get(i);
14661             if (!isCompact) {
14662                 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14663             } else if (mi.isProc) {
14664                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14665                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14666                 pw.println(mi.hasActivities ? ",a" : ",e");
14667             } else {
14668                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14669                 pw.println(mi.pss);
14670             }
14671             if (mi.subitems != null) {
14672                 dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14673                         true, isCompact);
14674             }
14675         }
14676     }
14677
14678     // These are in KB.
14679     static final long[] DUMP_MEM_BUCKETS = new long[] {
14680         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14681         120*1024, 160*1024, 200*1024,
14682         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14683         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14684     };
14685
14686     static final void appendMemBucket(StringBuilder out, long memKB, String label,
14687             boolean stackLike) {
14688         int start = label.lastIndexOf('.');
14689         if (start >= 0) start++;
14690         else start = 0;
14691         int end = label.length();
14692         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14693             if (DUMP_MEM_BUCKETS[i] >= memKB) {
14694                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
14695                 out.append(bucket);
14696                 out.append(stackLike ? "MB." : "MB ");
14697                 out.append(label, start, end);
14698                 return;
14699             }
14700         }
14701         out.append(memKB/1024);
14702         out.append(stackLike ? "MB." : "MB ");
14703         out.append(label, start, end);
14704     }
14705
14706     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14707             ProcessList.NATIVE_ADJ,
14708             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14709             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14710             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14711             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14712             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14713             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14714     };
14715     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14716             "Native",
14717             "System", "Persistent", "Persistent Service", "Foreground",
14718             "Visible", "Perceptible",
14719             "Heavy Weight", "Backup",
14720             "A Services", "Home",
14721             "Previous", "B Services", "Cached"
14722     };
14723     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14724             "native",
14725             "sys", "pers", "persvc", "fore",
14726             "vis", "percept",
14727             "heavy", "backup",
14728             "servicea", "home",
14729             "prev", "serviceb", "cached"
14730     };
14731
14732     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14733             long realtime, boolean isCheckinRequest, boolean isCompact) {
14734         if (isCheckinRequest || isCompact) {
14735             // short checkin version
14736             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14737         } else {
14738             pw.println("Applications Memory Usage (kB):");
14739             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14740         }
14741     }
14742
14743     private static final int KSM_SHARED = 0;
14744     private static final int KSM_SHARING = 1;
14745     private static final int KSM_UNSHARED = 2;
14746     private static final int KSM_VOLATILE = 3;
14747
14748     private final long[] getKsmInfo() {
14749         long[] longOut = new long[4];
14750         final int[] SINGLE_LONG_FORMAT = new int[] {
14751             Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14752         };
14753         long[] longTmp = new long[1];
14754         Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14755                 SINGLE_LONG_FORMAT, null, longTmp, null);
14756         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14757         longTmp[0] = 0;
14758         Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14759                 SINGLE_LONG_FORMAT, null, longTmp, null);
14760         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14761         longTmp[0] = 0;
14762         Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14763                 SINGLE_LONG_FORMAT, null, longTmp, null);
14764         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14765         longTmp[0] = 0;
14766         Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14767                 SINGLE_LONG_FORMAT, null, longTmp, null);
14768         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14769         return longOut;
14770     }
14771
14772     final void dumpApplicationMemoryUsage(FileDescriptor fd,
14773             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14774         boolean dumpDetails = false;
14775         boolean dumpFullDetails = false;
14776         boolean dumpDalvik = false;
14777         boolean dumpSummaryOnly = false;
14778         boolean oomOnly = false;
14779         boolean isCompact = false;
14780         boolean localOnly = false;
14781         boolean packages = false;
14782
14783         int opti = 0;
14784         while (opti < args.length) {
14785             String opt = args[opti];
14786             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14787                 break;
14788             }
14789             opti++;
14790             if ("-a".equals(opt)) {
14791                 dumpDetails = true;
14792                 dumpFullDetails = true;
14793                 dumpDalvik = true;
14794             } else if ("-d".equals(opt)) {
14795                 dumpDalvik = true;
14796             } else if ("-c".equals(opt)) {
14797                 isCompact = true;
14798             } else if ("-s".equals(opt)) {
14799                 dumpDetails = true;
14800                 dumpSummaryOnly = true;
14801             } else if ("--oom".equals(opt)) {
14802                 oomOnly = true;
14803             } else if ("--local".equals(opt)) {
14804                 localOnly = true;
14805             } else if ("--package".equals(opt)) {
14806                 packages = true;
14807             } else if ("-h".equals(opt)) {
14808                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14809                 pw.println("  -a: include all available information for each process.");
14810                 pw.println("  -d: include dalvik details.");
14811                 pw.println("  -c: dump in a compact machine-parseable representation.");
14812                 pw.println("  -s: dump only summary of application memory usage.");
14813                 pw.println("  --oom: only show processes organized by oom adj.");
14814                 pw.println("  --local: only collect details locally, don't call process.");
14815                 pw.println("  --package: interpret process arg as package, dumping all");
14816                 pw.println("             processes that have loaded that package.");
14817                 pw.println("If [process] is specified it can be the name or ");
14818                 pw.println("pid of a specific process to dump.");
14819                 return;
14820             } else {
14821                 pw.println("Unknown argument: " + opt + "; use -h for help");
14822             }
14823         }
14824
14825         final boolean isCheckinRequest = scanArgs(args, "--checkin");
14826         long uptime = SystemClock.uptimeMillis();
14827         long realtime = SystemClock.elapsedRealtime();
14828         final long[] tmpLong = new long[1];
14829
14830         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14831         if (procs == null) {
14832             // No Java processes.  Maybe they want to print a native process.
14833             if (args != null && args.length > opti
14834                     && args[opti].charAt(0) != '-') {
14835                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
14836                         = new ArrayList<ProcessCpuTracker.Stats>();
14837                 updateCpuStatsNow();
14838                 int findPid = -1;
14839                 try {
14840                     findPid = Integer.parseInt(args[opti]);
14841                 } catch (NumberFormatException e) {
14842                 }
14843                 synchronized (mProcessCpuTracker) {
14844                     final int N = mProcessCpuTracker.countStats();
14845                     for (int i=0; i<N; i++) {
14846                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14847                         if (st.pid == findPid || (st.baseName != null
14848                                 && st.baseName.equals(args[opti]))) {
14849                             nativeProcs.add(st);
14850                         }
14851                     }
14852                 }
14853                 if (nativeProcs.size() > 0) {
14854                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14855                             isCompact);
14856                     Debug.MemoryInfo mi = null;
14857                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14858                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14859                         final int pid = r.pid;
14860                         if (!isCheckinRequest && dumpDetails) {
14861                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14862                         }
14863                         if (mi == null) {
14864                             mi = new Debug.MemoryInfo();
14865                         }
14866                         if (dumpDetails || (!brief && !oomOnly)) {
14867                             Debug.getMemoryInfo(pid, mi);
14868                         } else {
14869                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14870                             mi.dalvikPrivateDirty = (int)tmpLong[0];
14871                         }
14872                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14873                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14874                         if (isCheckinRequest) {
14875                             pw.println();
14876                         }
14877                     }
14878                     return;
14879                 }
14880             }
14881             pw.println("No process found for: " + args[opti]);
14882             return;
14883         }
14884
14885         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14886             dumpDetails = true;
14887         }
14888
14889         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14890
14891         String[] innerArgs = new String[args.length-opti];
14892         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14893
14894         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14895         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14896         long nativePss = 0;
14897         long dalvikPss = 0;
14898         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14899                 EmptyArray.LONG;
14900         long otherPss = 0;
14901         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14902
14903         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14904         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14905                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
14906
14907         long totalPss = 0;
14908         long cachedPss = 0;
14909
14910         Debug.MemoryInfo mi = null;
14911         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14912             final ProcessRecord r = procs.get(i);
14913             final IApplicationThread thread;
14914             final int pid;
14915             final int oomAdj;
14916             final boolean hasActivities;
14917             synchronized (this) {
14918                 thread = r.thread;
14919                 pid = r.pid;
14920                 oomAdj = r.getSetAdjWithServices();
14921                 hasActivities = r.activities.size() > 0;
14922             }
14923             if (thread != null) {
14924                 if (!isCheckinRequest && dumpDetails) {
14925                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14926                 }
14927                 if (mi == null) {
14928                     mi = new Debug.MemoryInfo();
14929                 }
14930                 if (dumpDetails || (!brief && !oomOnly)) {
14931                     Debug.getMemoryInfo(pid, mi);
14932                 } else {
14933                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14934                     mi.dalvikPrivateDirty = (int)tmpLong[0];
14935                 }
14936                 if (dumpDetails) {
14937                     if (localOnly) {
14938                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14939                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14940                         if (isCheckinRequest) {
14941                             pw.println();
14942                         }
14943                     } else {
14944                         try {
14945                             pw.flush();
14946                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14947                                     dumpDalvik, dumpSummaryOnly, innerArgs);
14948                         } catch (RemoteException e) {
14949                             if (!isCheckinRequest) {
14950                                 pw.println("Got RemoteException!");
14951                                 pw.flush();
14952                             }
14953                         }
14954                     }
14955                 }
14956
14957                 final long myTotalPss = mi.getTotalPss();
14958                 final long myTotalUss = mi.getTotalUss();
14959
14960                 synchronized (this) {
14961                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14962                         // Record this for posterity if the process has been stable.
14963                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14964                     }
14965                 }
14966
14967                 if (!isCheckinRequest && mi != null) {
14968                     totalPss += myTotalPss;
14969                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14970                             (hasActivities ? " / activities)" : ")"),
14971                             r.processName, myTotalPss, pid, hasActivities);
14972                     procMems.add(pssItem);
14973                     procMemsMap.put(pid, pssItem);
14974
14975                     nativePss += mi.nativePss;
14976                     dalvikPss += mi.dalvikPss;
14977                     for (int j=0; j<dalvikSubitemPss.length; j++) {
14978                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14979                     }
14980                     otherPss += mi.otherPss;
14981                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14982                         long mem = mi.getOtherPss(j);
14983                         miscPss[j] += mem;
14984                         otherPss -= mem;
14985                     }
14986
14987                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14988                         cachedPss += myTotalPss;
14989                     }
14990
14991                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14992                         if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14993                                 || oomIndex == (oomPss.length-1)) {
14994                             oomPss[oomIndex] += myTotalPss;
14995                             if (oomProcs[oomIndex] == null) {
14996                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
14997                             }
14998                             oomProcs[oomIndex].add(pssItem);
14999                             break;
15000                         }
15001                     }
15002                 }
15003             }
15004         }
15005
15006         long nativeProcTotalPss = 0;
15007
15008         if (!isCheckinRequest && procs.size() > 1 && !packages) {
15009             // If we are showing aggregations, also look for native processes to
15010             // include so that our aggregations are more accurate.
15011             updateCpuStatsNow();
15012             mi = null;
15013             synchronized (mProcessCpuTracker) {
15014                 final int N = mProcessCpuTracker.countStats();
15015                 for (int i=0; i<N; i++) {
15016                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15017                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15018                         if (mi == null) {
15019                             mi = new Debug.MemoryInfo();
15020                         }
15021                         if (!brief && !oomOnly) {
15022                             Debug.getMemoryInfo(st.pid, mi);
15023                         } else {
15024                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15025                             mi.nativePrivateDirty = (int)tmpLong[0];
15026                         }
15027
15028                         final long myTotalPss = mi.getTotalPss();
15029                         totalPss += myTotalPss;
15030                         nativeProcTotalPss += myTotalPss;
15031
15032                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15033                                 st.name, myTotalPss, st.pid, false);
15034                         procMems.add(pssItem);
15035
15036                         nativePss += mi.nativePss;
15037                         dalvikPss += mi.dalvikPss;
15038                         for (int j=0; j<dalvikSubitemPss.length; j++) {
15039                             dalvikSubitemPss[j] += mi.getOtherPss(
15040                                     Debug.MemoryInfo.NUM_OTHER_STATS + j);
15041                         }
15042                         otherPss += mi.otherPss;
15043                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15044                             long mem = mi.getOtherPss(j);
15045                             miscPss[j] += mem;
15046                             otherPss -= mem;
15047                         }
15048                         oomPss[0] += myTotalPss;
15049                         if (oomProcs[0] == null) {
15050                             oomProcs[0] = new ArrayList<MemItem>();
15051                         }
15052                         oomProcs[0].add(pssItem);
15053                     }
15054                 }
15055             }
15056
15057             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15058
15059             catMems.add(new MemItem("Native", "Native", nativePss, -1));
15060             final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
15061             if (dalvikSubitemPss.length > 0) {
15062                 dalvikItem.subitems = new ArrayList<MemItem>();
15063                 for (int j=0; j<dalvikSubitemPss.length; j++) {
15064                     final String name = Debug.MemoryInfo.getOtherLabel(
15065                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
15066                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
15067                 }
15068             }
15069             catMems.add(dalvikItem);
15070             catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
15071             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15072                 String label = Debug.MemoryInfo.getOtherLabel(j);
15073                 catMems.add(new MemItem(label, label, miscPss[j], j));
15074             }
15075
15076             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15077             for (int j=0; j<oomPss.length; j++) {
15078                 if (oomPss[j] != 0) {
15079                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15080                             : DUMP_MEM_OOM_LABEL[j];
15081                     MemItem item = new MemItem(label, label, oomPss[j],
15082                             DUMP_MEM_OOM_ADJ[j]);
15083                     item.subitems = oomProcs[j];
15084                     oomMems.add(item);
15085                 }
15086             }
15087
15088             if (!brief && !oomOnly && !isCompact) {
15089                 pw.println();
15090                 pw.println("Total PSS by process:");
15091                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
15092                 pw.println();
15093             }
15094             if (!isCompact) {
15095                 pw.println("Total PSS by OOM adjustment:");
15096             }
15097             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
15098             if (!brief && !oomOnly) {
15099                 PrintWriter out = categoryPw != null ? categoryPw : pw;
15100                 if (!isCompact) {
15101                     out.println();
15102                     out.println("Total PSS by category:");
15103                 }
15104                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
15105             }
15106             if (!isCompact) {
15107                 pw.println();
15108             }
15109             MemInfoReader memInfo = new MemInfoReader();
15110             memInfo.readMemInfo();
15111             if (nativeProcTotalPss > 0) {
15112                 synchronized (this) {
15113                     final long cachedKb = memInfo.getCachedSizeKb();
15114                     final long freeKb = memInfo.getFreeSizeKb();
15115                     final long zramKb = memInfo.getZramTotalSizeKb();
15116                     final long kernelKb = memInfo.getKernelUsedSizeKb();
15117                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15118                             kernelKb*1024, nativeProcTotalPss*1024);
15119                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15120                             nativeProcTotalPss);
15121                 }
15122             }
15123             if (!brief) {
15124                 if (!isCompact) {
15125                     pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
15126                     pw.print(" kB (status ");
15127                     switch (mLastMemoryLevel) {
15128                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15129                             pw.println("normal)");
15130                             break;
15131                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15132                             pw.println("moderate)");
15133                             break;
15134                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
15135                             pw.println("low)");
15136                             break;
15137                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15138                             pw.println("critical)");
15139                             break;
15140                         default:
15141                             pw.print(mLastMemoryLevel);
15142                             pw.println(")");
15143                             break;
15144                     }
15145                     pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
15146                             + memInfo.getFreeSizeKb()); pw.print(" kB (");
15147                             pw.print(cachedPss); pw.print(" cached pss + ");
15148                             pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
15149                             pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
15150                 } else {
15151                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15152                     pw.print(cachedPss + memInfo.getCachedSizeKb()
15153                             + memInfo.getFreeSizeKb()); pw.print(",");
15154                     pw.println(totalPss - cachedPss);
15155                 }
15156             }
15157             if (!isCompact) {
15158                 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
15159                         + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
15160                         pw.print(totalPss - cachedPss); pw.print(" used pss + ");
15161                         pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
15162                 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
15163                         - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15164                         - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
15165             } else {
15166                 pw.print("lostram,"); pw.println(memInfo.getTotalSizeKb()
15167                         - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15168                         - memInfo.getKernelUsedSizeKb());
15169             }
15170             if (!brief) {
15171                 if (memInfo.getZramTotalSizeKb() != 0) {
15172                     if (!isCompact) {
15173                         pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
15174                                 pw.print(" kB physical used for ");
15175                                 pw.print(memInfo.getSwapTotalSizeKb()
15176                                         - memInfo.getSwapFreeSizeKb());
15177                                 pw.print(" kB in swap (");
15178                                 pw.print(memInfo.getSwapTotalSizeKb());
15179                                 pw.println(" kB total swap)");
15180                     } else {
15181                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15182                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15183                                 pw.println(memInfo.getSwapFreeSizeKb());
15184                     }
15185                 }
15186                 final long[] ksm = getKsmInfo();
15187                 if (!isCompact) {
15188                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15189                             || ksm[KSM_VOLATILE] != 0) {
15190                         pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
15191                                 pw.print(" kB saved from shared ");
15192                                 pw.print(ksm[KSM_SHARED]); pw.println(" kB");
15193                         pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
15194                                 pw.print(" kB unshared; ");
15195                                 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
15196                     }
15197                     pw.print("   Tuning: ");
15198                     pw.print(ActivityManager.staticGetMemoryClass());
15199                     pw.print(" (large ");
15200                     pw.print(ActivityManager.staticGetLargeMemoryClass());
15201                     pw.print("), oom ");
15202                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15203                     pw.print(" kB");
15204                     pw.print(", restore limit ");
15205                     pw.print(mProcessList.getCachedRestoreThresholdKb());
15206                     pw.print(" kB");
15207                     if (ActivityManager.isLowRamDeviceStatic()) {
15208                         pw.print(" (low-ram)");
15209                     }
15210                     if (ActivityManager.isHighEndGfx()) {
15211                         pw.print(" (high-end-gfx)");
15212                     }
15213                     pw.println();
15214                 } else {
15215                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15216                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15217                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15218                     pw.print("tuning,");
15219                     pw.print(ActivityManager.staticGetMemoryClass());
15220                     pw.print(',');
15221                     pw.print(ActivityManager.staticGetLargeMemoryClass());
15222                     pw.print(',');
15223                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15224                     if (ActivityManager.isLowRamDeviceStatic()) {
15225                         pw.print(",low-ram");
15226                     }
15227                     if (ActivityManager.isHighEndGfx()) {
15228                         pw.print(",high-end-gfx");
15229                     }
15230                     pw.println();
15231                 }
15232             }
15233         }
15234     }
15235
15236     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15237             long memtrack, String name) {
15238         sb.append("  ");
15239         sb.append(ProcessList.makeOomAdjString(oomAdj));
15240         sb.append(' ');
15241         sb.append(ProcessList.makeProcStateString(procState));
15242         sb.append(' ');
15243         ProcessList.appendRamKb(sb, pss);
15244         sb.append(" kB: ");
15245         sb.append(name);
15246         if (memtrack > 0) {
15247             sb.append(" (");
15248             sb.append(memtrack);
15249             sb.append(" kB memtrack)");
15250         }
15251     }
15252
15253     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15254         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15255         sb.append(" (pid ");
15256         sb.append(mi.pid);
15257         sb.append(") ");
15258         sb.append(mi.adjType);
15259         sb.append('\n');
15260         if (mi.adjReason != null) {
15261             sb.append("                      ");
15262             sb.append(mi.adjReason);
15263             sb.append('\n');
15264         }
15265     }
15266
15267     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15268         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15269         for (int i=0, N=memInfos.size(); i<N; i++) {
15270             ProcessMemInfo mi = memInfos.get(i);
15271             infoMap.put(mi.pid, mi);
15272         }
15273         updateCpuStatsNow();
15274         long[] memtrackTmp = new long[1];
15275         synchronized (mProcessCpuTracker) {
15276             final int N = mProcessCpuTracker.countStats();
15277             for (int i=0; i<N; i++) {
15278                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15279                 if (st.vsize > 0) {
15280                     long pss = Debug.getPss(st.pid, null, memtrackTmp);
15281                     if (pss > 0) {
15282                         if (infoMap.indexOfKey(st.pid) < 0) {
15283                             ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15284                                     ProcessList.NATIVE_ADJ, -1, "native", null);
15285                             mi.pss = pss;
15286                             mi.memtrack = memtrackTmp[0];
15287                             memInfos.add(mi);
15288                         }
15289                     }
15290                 }
15291             }
15292         }
15293
15294         long totalPss = 0;
15295         long totalMemtrack = 0;
15296         for (int i=0, N=memInfos.size(); i<N; i++) {
15297             ProcessMemInfo mi = memInfos.get(i);
15298             if (mi.pss == 0) {
15299                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15300                 mi.memtrack = memtrackTmp[0];
15301             }
15302             totalPss += mi.pss;
15303             totalMemtrack += mi.memtrack;
15304         }
15305         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15306             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15307                 if (lhs.oomAdj != rhs.oomAdj) {
15308                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15309                 }
15310                 if (lhs.pss != rhs.pss) {
15311                     return lhs.pss < rhs.pss ? 1 : -1;
15312                 }
15313                 return 0;
15314             }
15315         });
15316
15317         StringBuilder tag = new StringBuilder(128);
15318         StringBuilder stack = new StringBuilder(128);
15319         tag.append("Low on memory -- ");
15320         appendMemBucket(tag, totalPss, "total", false);
15321         appendMemBucket(stack, totalPss, "total", true);
15322
15323         StringBuilder fullNativeBuilder = new StringBuilder(1024);
15324         StringBuilder shortNativeBuilder = new StringBuilder(1024);
15325         StringBuilder fullJavaBuilder = new StringBuilder(1024);
15326
15327         boolean firstLine = true;
15328         int lastOomAdj = Integer.MIN_VALUE;
15329         long extraNativeRam = 0;
15330         long extraNativeMemtrack = 0;
15331         long cachedPss = 0;
15332         for (int i=0, N=memInfos.size(); i<N; i++) {
15333             ProcessMemInfo mi = memInfos.get(i);
15334
15335             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15336                 cachedPss += mi.pss;
15337             }
15338
15339             if (mi.oomAdj != ProcessList.NATIVE_ADJ
15340                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
15341                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
15342                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15343                 if (lastOomAdj != mi.oomAdj) {
15344                     lastOomAdj = mi.oomAdj;
15345                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15346                         tag.append(" / ");
15347                     }
15348                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15349                         if (firstLine) {
15350                             stack.append(":");
15351                             firstLine = false;
15352                         }
15353                         stack.append("\n\t at ");
15354                     } else {
15355                         stack.append("$");
15356                     }
15357                 } else {
15358                     tag.append(" ");
15359                     stack.append("$");
15360                 }
15361                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15362                     appendMemBucket(tag, mi.pss, mi.name, false);
15363                 }
15364                 appendMemBucket(stack, mi.pss, mi.name, true);
15365                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15366                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15367                     stack.append("(");
15368                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15369                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15370                             stack.append(DUMP_MEM_OOM_LABEL[k]);
15371                             stack.append(":");
15372                             stack.append(DUMP_MEM_OOM_ADJ[k]);
15373                         }
15374                     }
15375                     stack.append(")");
15376                 }
15377             }
15378
15379             appendMemInfo(fullNativeBuilder, mi);
15380             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15381                 // The short form only has native processes that are >= 512K.
15382                 if (mi.pss >= 512) {
15383                     appendMemInfo(shortNativeBuilder, mi);
15384                 } else {
15385                     extraNativeRam += mi.pss;
15386                     extraNativeMemtrack += mi.memtrack;
15387                 }
15388             } else {
15389                 // Short form has all other details, but if we have collected RAM
15390                 // from smaller native processes let's dump a summary of that.
15391                 if (extraNativeRam > 0) {
15392                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15393                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15394                     shortNativeBuilder.append('\n');
15395                     extraNativeRam = 0;
15396                 }
15397                 appendMemInfo(fullJavaBuilder, mi);
15398             }
15399         }
15400
15401         fullJavaBuilder.append("           ");
15402         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15403         fullJavaBuilder.append(" kB: TOTAL");
15404         if (totalMemtrack > 0) {
15405             fullJavaBuilder.append(" (");
15406             fullJavaBuilder.append(totalMemtrack);
15407             fullJavaBuilder.append(" kB memtrack)");
15408         } else {
15409         }
15410         fullJavaBuilder.append("\n");
15411
15412         MemInfoReader memInfo = new MemInfoReader();
15413         memInfo.readMemInfo();
15414         final long[] infos = memInfo.getRawInfo();
15415
15416         StringBuilder memInfoBuilder = new StringBuilder(1024);
15417         Debug.getMemInfo(infos);
15418         memInfoBuilder.append("  MemInfo: ");
15419         memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15420         memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15421         memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15422         memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15423         memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15424         memInfoBuilder.append("           ");
15425         memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15426         memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15427         memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15428         memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15429         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15430             memInfoBuilder.append("  ZRAM: ");
15431             memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15432             memInfoBuilder.append(" kB RAM, ");
15433             memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15434             memInfoBuilder.append(" kB swap total, ");
15435             memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15436             memInfoBuilder.append(" kB swap free\n");
15437         }
15438         final long[] ksm = getKsmInfo();
15439         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15440                 || ksm[KSM_VOLATILE] != 0) {
15441             memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15442             memInfoBuilder.append(" kB saved from shared ");
15443             memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15444             memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15445             memInfoBuilder.append(" kB unshared; ");
15446             memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15447         }
15448         memInfoBuilder.append("  Free RAM: ");
15449         memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15450                 + memInfo.getFreeSizeKb());
15451         memInfoBuilder.append(" kB\n");
15452         memInfoBuilder.append("  Used RAM: ");
15453         memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15454         memInfoBuilder.append(" kB\n");
15455         memInfoBuilder.append("  Lost RAM: ");
15456         memInfoBuilder.append(memInfo.getTotalSizeKb()
15457                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15458                 - memInfo.getKernelUsedSizeKb());
15459         memInfoBuilder.append(" kB\n");
15460         Slog.i(TAG, "Low on memory:");
15461         Slog.i(TAG, shortNativeBuilder.toString());
15462         Slog.i(TAG, fullJavaBuilder.toString());
15463         Slog.i(TAG, memInfoBuilder.toString());
15464
15465         StringBuilder dropBuilder = new StringBuilder(1024);
15466         /*
15467         StringWriter oomSw = new StringWriter();
15468         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15469         StringWriter catSw = new StringWriter();
15470         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15471         String[] emptyArgs = new String[] { };
15472         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15473         oomPw.flush();
15474         String oomString = oomSw.toString();
15475         */
15476         dropBuilder.append("Low on memory:");
15477         dropBuilder.append(stack);
15478         dropBuilder.append('\n');
15479         dropBuilder.append(fullNativeBuilder);
15480         dropBuilder.append(fullJavaBuilder);
15481         dropBuilder.append('\n');
15482         dropBuilder.append(memInfoBuilder);
15483         dropBuilder.append('\n');
15484         /*
15485         dropBuilder.append(oomString);
15486         dropBuilder.append('\n');
15487         */
15488         StringWriter catSw = new StringWriter();
15489         synchronized (ActivityManagerService.this) {
15490             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15491             String[] emptyArgs = new String[] { };
15492             catPw.println();
15493             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15494             catPw.println();
15495             mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15496                     false, false, null);
15497             catPw.println();
15498             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15499             catPw.flush();
15500         }
15501         dropBuilder.append(catSw.toString());
15502         addErrorToDropBox("lowmem", null, "system_server", null,
15503                 null, tag.toString(), dropBuilder.toString(), null, null);
15504         //Slog.i(TAG, "Sent to dropbox:");
15505         //Slog.i(TAG, dropBuilder.toString());
15506         synchronized (ActivityManagerService.this) {
15507             long now = SystemClock.uptimeMillis();
15508             if (mLastMemUsageReportTime < now) {
15509                 mLastMemUsageReportTime = now;
15510             }
15511         }
15512     }
15513
15514     /**
15515      * Searches array of arguments for the specified string
15516      * @param args array of argument strings
15517      * @param value value to search for
15518      * @return true if the value is contained in the array
15519      */
15520     private static boolean scanArgs(String[] args, String value) {
15521         if (args != null) {
15522             for (String arg : args) {
15523                 if (value.equals(arg)) {
15524                     return true;
15525                 }
15526             }
15527         }
15528         return false;
15529     }
15530
15531     private final boolean removeDyingProviderLocked(ProcessRecord proc,
15532             ContentProviderRecord cpr, boolean always) {
15533         final boolean inLaunching = mLaunchingProviders.contains(cpr);
15534
15535         if (!inLaunching || always) {
15536             synchronized (cpr) {
15537                 cpr.launchingApp = null;
15538                 cpr.notifyAll();
15539             }
15540             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15541             String names[] = cpr.info.authority.split(";");
15542             for (int j = 0; j < names.length; j++) {
15543                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15544             }
15545         }
15546
15547         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15548             ContentProviderConnection conn = cpr.connections.get(i);
15549             if (conn.waiting) {
15550                 // If this connection is waiting for the provider, then we don't
15551                 // need to mess with its process unless we are always removing
15552                 // or for some reason the provider is not currently launching.
15553                 if (inLaunching && !always) {
15554                     continue;
15555                 }
15556             }
15557             ProcessRecord capp = conn.client;
15558             conn.dead = true;
15559             if (conn.stableCount > 0) {
15560                 if (!capp.persistent && capp.thread != null
15561                         && capp.pid != 0
15562                         && capp.pid != MY_PID) {
15563                     capp.kill("depends on provider "
15564                             + cpr.name.flattenToShortString()
15565                             + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15566                 }
15567             } else if (capp.thread != null && conn.provider.provider != null) {
15568                 try {
15569                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15570                 } catch (RemoteException e) {
15571                 }
15572                 // In the protocol here, we don't expect the client to correctly
15573                 // clean up this connection, we'll just remove it.
15574                 cpr.connections.remove(i);
15575                 if (conn.client.conProviders.remove(conn)) {
15576                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15577                 }
15578             }
15579         }
15580
15581         if (inLaunching && always) {
15582             mLaunchingProviders.remove(cpr);
15583         }
15584         return inLaunching;
15585     }
15586
15587     /**
15588      * Main code for cleaning up a process when it has gone away.  This is
15589      * called both as a result of the process dying, or directly when stopping
15590      * a process when running in single process mode.
15591      *
15592      * @return Returns true if the given process has been restarted, so the
15593      * app that was passed in must remain on the process lists.
15594      */
15595     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15596             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
15597         Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
15598         if (index >= 0) {
15599             removeLruProcessLocked(app);
15600             ProcessList.remove(app.pid);
15601         }
15602
15603         mProcessesToGc.remove(app);
15604         mPendingPssProcesses.remove(app);
15605
15606         // Dismiss any open dialogs.
15607         if (app.crashDialog != null && !app.forceCrashReport) {
15608             app.crashDialog.dismiss();
15609             app.crashDialog = null;
15610         }
15611         if (app.anrDialog != null) {
15612             app.anrDialog.dismiss();
15613             app.anrDialog = null;
15614         }
15615         if (app.waitDialog != null) {
15616             app.waitDialog.dismiss();
15617             app.waitDialog = null;
15618         }
15619
15620         app.crashing = false;
15621         app.notResponding = false;
15622
15623         app.resetPackageList(mProcessStats);
15624         app.unlinkDeathRecipient();
15625         app.makeInactive(mProcessStats);
15626         app.waitingToKill = null;
15627         app.forcingToForeground = null;
15628         updateProcessForegroundLocked(app, false, false);
15629         app.foregroundActivities = false;
15630         app.hasShownUi = false;
15631         app.treatLikeActivity = false;
15632         app.hasAboveClient = false;
15633         app.hasClientActivities = false;
15634
15635         mServices.killServicesLocked(app, allowRestart);
15636
15637         boolean restart = false;
15638
15639         // Remove published content providers.
15640         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15641             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15642             final boolean always = app.bad || !allowRestart;
15643             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15644             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15645                 // We left the provider in the launching list, need to
15646                 // restart it.
15647                 restart = true;
15648             }
15649
15650             cpr.provider = null;
15651             cpr.proc = null;
15652         }
15653         app.pubProviders.clear();
15654
15655         // Take care of any launching providers waiting for this process.
15656         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
15657             restart = true;
15658         }
15659
15660         // Unregister from connected content providers.
15661         if (!app.conProviders.isEmpty()) {
15662             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15663                 ContentProviderConnection conn = app.conProviders.get(i);
15664                 conn.provider.connections.remove(conn);
15665                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15666                         conn.provider.name);
15667             }
15668             app.conProviders.clear();
15669         }
15670
15671         // At this point there may be remaining entries in mLaunchingProviders
15672         // where we were the only one waiting, so they are no longer of use.
15673         // Look for these and clean up if found.
15674         // XXX Commented out for now.  Trying to figure out a way to reproduce
15675         // the actual situation to identify what is actually going on.
15676         if (false) {
15677             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15678                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
15679                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15680                     synchronized (cpr) {
15681                         cpr.launchingApp = null;
15682                         cpr.notifyAll();
15683                     }
15684                 }
15685             }
15686         }
15687
15688         skipCurrentReceiverLocked(app);
15689
15690         // Unregister any receivers.
15691         for (int i = app.receivers.size() - 1; i >= 0; i--) {
15692             removeReceiverLocked(app.receivers.valueAt(i));
15693         }
15694         app.receivers.clear();
15695
15696         // If the app is undergoing backup, tell the backup manager about it
15697         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15698             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15699                     + mBackupTarget.appInfo + " died during backup");
15700             try {
15701                 IBackupManager bm = IBackupManager.Stub.asInterface(
15702                         ServiceManager.getService(Context.BACKUP_SERVICE));
15703                 bm.agentDisconnected(app.info.packageName);
15704             } catch (RemoteException e) {
15705                 // can't happen; backup manager is local
15706             }
15707         }
15708
15709         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15710             ProcessChangeItem item = mPendingProcessChanges.get(i);
15711             if (item.pid == app.pid) {
15712                 mPendingProcessChanges.remove(i);
15713                 mAvailProcessChanges.add(item);
15714             }
15715         }
15716         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15717
15718         // If the caller is restarting this app, then leave it in its
15719         // current lists and let the caller take care of it.
15720         if (restarting) {
15721             return false;
15722         }
15723
15724         if (!app.persistent || app.isolated) {
15725             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15726                     "Removing non-persistent process during cleanup: " + app);
15727             if (!replacingPid) {
15728                 removeProcessNameLocked(app.processName, app.uid);
15729             }
15730             if (mHeavyWeightProcess == app) {
15731                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15732                         mHeavyWeightProcess.userId, 0));
15733                 mHeavyWeightProcess = null;
15734             }
15735         } else if (!app.removed) {
15736             // This app is persistent, so we need to keep its record around.
15737             // If it is not already on the pending app list, add it there
15738             // and start a new process for it.
15739             if (mPersistentStartingProcesses.indexOf(app) < 0) {
15740                 mPersistentStartingProcesses.add(app);
15741                 restart = true;
15742             }
15743         }
15744         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15745                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
15746         mProcessesOnHold.remove(app);
15747
15748         if (app == mHomeProcess) {
15749             mHomeProcess = null;
15750         }
15751         if (app == mPreviousProcess) {
15752             mPreviousProcess = null;
15753         }
15754
15755         if (restart && !app.isolated) {
15756             // We have components that still need to be running in the
15757             // process, so re-launch it.
15758             if (index < 0) {
15759                 ProcessList.remove(app.pid);
15760             }
15761             addProcessNameLocked(app);
15762             startProcessLocked(app, "restart", app.processName);
15763             return true;
15764         } else if (app.pid > 0 && app.pid != MY_PID) {
15765             // Goodbye!
15766             boolean removed;
15767             synchronized (mPidsSelfLocked) {
15768                 mPidsSelfLocked.remove(app.pid);
15769                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15770             }
15771             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15772             if (app.isolated) {
15773                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15774             }
15775             app.setPid(0);
15776         }
15777         return false;
15778     }
15779
15780     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
15781         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15782             ContentProviderRecord cpr = mLaunchingProviders.get(i);
15783             if (cpr.launchingApp == app) {
15784                 return true;
15785             }
15786         }
15787         return false;
15788     }
15789
15790     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15791         // Look through the content providers we are waiting to have launched,
15792         // and if any run in this process then either schedule a restart of
15793         // the process or kill the client waiting for it if this process has
15794         // gone bad.
15795         boolean restart = false;
15796         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15797             ContentProviderRecord cpr = mLaunchingProviders.get(i);
15798             if (cpr.launchingApp == app) {
15799                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15800                     restart = true;
15801                 } else {
15802                     removeDyingProviderLocked(app, cpr, true);
15803                 }
15804             }
15805         }
15806         return restart;
15807     }
15808
15809     // =========================================================
15810     // SERVICES
15811     // =========================================================
15812
15813     @Override
15814     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15815             int flags) {
15816         enforceNotIsolatedCaller("getServices");
15817         synchronized (this) {
15818             return mServices.getRunningServiceInfoLocked(maxNum, flags);
15819         }
15820     }
15821
15822     @Override
15823     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15824         enforceNotIsolatedCaller("getRunningServiceControlPanel");
15825         synchronized (this) {
15826             return mServices.getRunningServiceControlPanelLocked(name);
15827         }
15828     }
15829
15830     @Override
15831     public ComponentName startService(IApplicationThread caller, Intent service,
15832             String resolvedType, String callingPackage, int userId)
15833             throws TransactionTooLargeException {
15834         enforceNotIsolatedCaller("startService");
15835         // Refuse possible leaked file descriptors
15836         if (service != null && service.hasFileDescriptors() == true) {
15837             throw new IllegalArgumentException("File descriptors passed in Intent");
15838         }
15839
15840         if (callingPackage == null) {
15841             throw new IllegalArgumentException("callingPackage cannot be null");
15842         }
15843
15844         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15845                 "startService: " + service + " type=" + resolvedType);
15846         synchronized(this) {
15847             final int callingPid = Binder.getCallingPid();
15848             final int callingUid = Binder.getCallingUid();
15849             final long origId = Binder.clearCallingIdentity();
15850             ComponentName res = mServices.startServiceLocked(caller, service,
15851                     resolvedType, callingPid, callingUid, callingPackage, userId);
15852             Binder.restoreCallingIdentity(origId);
15853             return res;
15854         }
15855     }
15856
15857     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
15858             String callingPackage, int userId)
15859             throws TransactionTooLargeException {
15860         synchronized(this) {
15861             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15862                     "startServiceInPackage: " + service + " type=" + resolvedType);
15863             final long origId = Binder.clearCallingIdentity();
15864             ComponentName res = mServices.startServiceLocked(null, service,
15865                     resolvedType, -1, uid, callingPackage, userId);
15866             Binder.restoreCallingIdentity(origId);
15867             return res;
15868         }
15869     }
15870
15871     @Override
15872     public int stopService(IApplicationThread caller, Intent service,
15873             String resolvedType, int userId) {
15874         enforceNotIsolatedCaller("stopService");
15875         // Refuse possible leaked file descriptors
15876         if (service != null && service.hasFileDescriptors() == true) {
15877             throw new IllegalArgumentException("File descriptors passed in Intent");
15878         }
15879
15880         synchronized(this) {
15881             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15882         }
15883     }
15884
15885     @Override
15886     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
15887         enforceNotIsolatedCaller("peekService");
15888         // Refuse possible leaked file descriptors
15889         if (service != null && service.hasFileDescriptors() == true) {
15890             throw new IllegalArgumentException("File descriptors passed in Intent");
15891         }
15892
15893         if (callingPackage == null) {
15894             throw new IllegalArgumentException("callingPackage cannot be null");
15895         }
15896
15897         synchronized(this) {
15898             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
15899         }
15900     }
15901
15902     @Override
15903     public boolean stopServiceToken(ComponentName className, IBinder token,
15904             int startId) {
15905         synchronized(this) {
15906             return mServices.stopServiceTokenLocked(className, token, startId);
15907         }
15908     }
15909
15910     @Override
15911     public void setServiceForeground(ComponentName className, IBinder token,
15912             int id, Notification notification, boolean removeNotification) {
15913         synchronized(this) {
15914             mServices.setServiceForegroundLocked(className, token, id, notification,
15915                     removeNotification);
15916         }
15917     }
15918
15919     @Override
15920     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15921             boolean requireFull, String name, String callerPackage) {
15922         return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15923                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15924     }
15925
15926     int unsafeConvertIncomingUser(int userId) {
15927         return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15928                 ? mCurrentUserId : userId;
15929     }
15930
15931     int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15932             int allowMode, String name, String callerPackage) {
15933         final int callingUserId = UserHandle.getUserId(callingUid);
15934         if (callingUserId == userId) {
15935             return userId;
15936         }
15937
15938         // Note that we may be accessing mCurrentUserId outside of a lock...
15939         // shouldn't be a big deal, if this is being called outside
15940         // of a locked context there is intrinsically a race with
15941         // the value the caller will receive and someone else changing it.
15942         // We assume that USER_CURRENT_OR_SELF will use the current user; later
15943         // we will switch to the calling user if access to the current user fails.
15944         int targetUserId = unsafeConvertIncomingUser(userId);
15945
15946         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15947             final boolean allow;
15948             if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15949                     callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15950                 // If the caller has this permission, they always pass go.  And collect $200.
15951                 allow = true;
15952             } else if (allowMode == ALLOW_FULL_ONLY) {
15953                 // We require full access, sucks to be you.
15954                 allow = false;
15955             } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15956                     callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15957                 // If the caller does not have either permission, they are always doomed.
15958                 allow = false;
15959             } else if (allowMode == ALLOW_NON_FULL) {
15960                 // We are blanket allowing non-full access, you lucky caller!
15961                 allow = true;
15962             } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15963                 // We may or may not allow this depending on whether the two users are
15964                 // in the same profile.
15965                 synchronized (mUserProfileGroupIdsSelfLocked) {
15966                     int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15967                             UserInfo.NO_PROFILE_GROUP_ID);
15968                     int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15969                             UserInfo.NO_PROFILE_GROUP_ID);
15970                     allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15971                             && callingProfile == targetProfile;
15972                 }
15973             } else {
15974                 throw new IllegalArgumentException("Unknown mode: " + allowMode);
15975             }
15976             if (!allow) {
15977                 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15978                     // In this case, they would like to just execute as their
15979                     // owner user instead of failing.
15980                     targetUserId = callingUserId;
15981                 } else {
15982                     StringBuilder builder = new StringBuilder(128);
15983                     builder.append("Permission Denial: ");
15984                     builder.append(name);
15985                     if (callerPackage != null) {
15986                         builder.append(" from ");
15987                         builder.append(callerPackage);
15988                     }
15989                     builder.append(" asks to run as user ");
15990                     builder.append(userId);
15991                     builder.append(" but is calling from user ");
15992                     builder.append(UserHandle.getUserId(callingUid));
15993                     builder.append("; this requires ");
15994                     builder.append(INTERACT_ACROSS_USERS_FULL);
15995                     if (allowMode != ALLOW_FULL_ONLY) {
15996                         builder.append(" or ");
15997                         builder.append(INTERACT_ACROSS_USERS);
15998                     }
15999                     String msg = builder.toString();
16000                     Slog.w(TAG, msg);
16001                     throw new SecurityException(msg);
16002                 }
16003             }
16004         }
16005         if (!allowAll && targetUserId < 0) {
16006             throw new IllegalArgumentException(
16007                     "Call does not support special user #" + targetUserId);
16008         }
16009         // Check shell permission
16010         if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
16011             if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
16012                     targetUserId)) {
16013                 throw new SecurityException("Shell does not have permission to access user "
16014                         + targetUserId + "\n " + Debug.getCallers(3));
16015             }
16016         }
16017         return targetUserId;
16018     }
16019
16020     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16021             String className, int flags) {
16022         boolean result = false;
16023         // For apps that don't have pre-defined UIDs, check for permission
16024         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16025             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16026                 if (ActivityManager.checkUidPermission(
16027                         INTERACT_ACROSS_USERS,
16028                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16029                     ComponentName comp = new ComponentName(aInfo.packageName, className);
16030                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
16031                             + " requests FLAG_SINGLE_USER, but app does not hold "
16032                             + INTERACT_ACROSS_USERS;
16033                     Slog.w(TAG, msg);
16034                     throw new SecurityException(msg);
16035                 }
16036                 // Permission passed
16037                 result = true;
16038             }
16039         } else if ("system".equals(componentProcessName)) {
16040             result = true;
16041         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16042             // Phone app and persistent apps are allowed to export singleuser providers.
16043             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16044                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16045         }
16046         if (DEBUG_MU) Slog.v(TAG_MU,
16047                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16048                 + Integer.toHexString(flags) + ") = " + result);
16049         return result;
16050     }
16051
16052     /**
16053      * Checks to see if the caller is in the same app as the singleton
16054      * component, or the component is in a special app. It allows special apps
16055      * to export singleton components but prevents exporting singleton
16056      * components for regular apps.
16057      */
16058     boolean isValidSingletonCall(int callingUid, int componentUid) {
16059         int componentAppId = UserHandle.getAppId(componentUid);
16060         return UserHandle.isSameApp(callingUid, componentUid)
16061                 || componentAppId == Process.SYSTEM_UID
16062                 || componentAppId == Process.PHONE_UID
16063                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16064                         == PackageManager.PERMISSION_GRANTED;
16065     }
16066
16067     public int bindService(IApplicationThread caller, IBinder token, Intent service,
16068             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16069             int userId) throws TransactionTooLargeException {
16070         enforceNotIsolatedCaller("bindService");
16071
16072         // Refuse possible leaked file descriptors
16073         if (service != null && service.hasFileDescriptors() == true) {
16074             throw new IllegalArgumentException("File descriptors passed in Intent");
16075         }
16076
16077         if (callingPackage == null) {
16078             throw new IllegalArgumentException("callingPackage cannot be null");
16079         }
16080
16081         synchronized(this) {
16082             return mServices.bindServiceLocked(caller, token, service,
16083                     resolvedType, connection, flags, callingPackage, userId);
16084         }
16085     }
16086
16087     public boolean unbindService(IServiceConnection connection) {
16088         synchronized (this) {
16089             return mServices.unbindServiceLocked(connection);
16090         }
16091     }
16092
16093     public void publishService(IBinder token, Intent intent, IBinder service) {
16094         // Refuse possible leaked file descriptors
16095         if (intent != null && intent.hasFileDescriptors() == true) {
16096             throw new IllegalArgumentException("File descriptors passed in Intent");
16097         }
16098
16099         synchronized(this) {
16100             if (!(token instanceof ServiceRecord)) {
16101                 throw new IllegalArgumentException("Invalid service token");
16102             }
16103             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16104         }
16105     }
16106
16107     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16108         // Refuse possible leaked file descriptors
16109         if (intent != null && intent.hasFileDescriptors() == true) {
16110             throw new IllegalArgumentException("File descriptors passed in Intent");
16111         }
16112
16113         synchronized(this) {
16114             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16115         }
16116     }
16117
16118     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16119         synchronized(this) {
16120             if (!(token instanceof ServiceRecord)) {
16121                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16122                 throw new IllegalArgumentException("Invalid service token");
16123             }
16124             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16125         }
16126     }
16127
16128     // =========================================================
16129     // BACKUP AND RESTORE
16130     // =========================================================
16131
16132     // Cause the target app to be launched if necessary and its backup agent
16133     // instantiated.  The backup agent will invoke backupAgentCreated() on the
16134     // activity manager to announce its creation.
16135     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
16136         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
16137         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16138
16139         IPackageManager pm = AppGlobals.getPackageManager();
16140         ApplicationInfo app = null;
16141         try {
16142             app = pm.getApplicationInfo(packageName, 0, userId);
16143         } catch (RemoteException e) {
16144             // can't happen; package manager is process-local
16145         }
16146         if (app == null) {
16147             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
16148             return false;
16149         }
16150
16151         synchronized(this) {
16152             // !!! TODO: currently no check here that we're already bound
16153             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16154             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16155             synchronized (stats) {
16156                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16157             }
16158
16159             // Backup agent is now in use, its package can't be stopped.
16160             try {
16161                 AppGlobals.getPackageManager().setPackageStoppedState(
16162                         app.packageName, false, UserHandle.getUserId(app.uid));
16163             } catch (RemoteException e) {
16164             } catch (IllegalArgumentException e) {
16165                 Slog.w(TAG, "Failed trying to unstop package "
16166                         + app.packageName + ": " + e);
16167             }
16168
16169             BackupRecord r = new BackupRecord(ss, app, backupMode);
16170             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16171                     ? new ComponentName(app.packageName, app.backupAgentName)
16172                     : new ComponentName("android", "FullBackupAgent");
16173             // startProcessLocked() returns existing proc's record if it's already running
16174             ProcessRecord proc = startProcessLocked(app.processName, app,
16175                     false, 0, "backup", hostingName, false, false, false);
16176             if (proc == null) {
16177                 Slog.e(TAG, "Unable to start backup agent process " + r);
16178                 return false;
16179             }
16180
16181             r.app = proc;
16182             mBackupTarget = r;
16183             mBackupAppName = app.packageName;
16184
16185             // Try not to kill the process during backup
16186             updateOomAdjLocked(proc);
16187
16188             // If the process is already attached, schedule the creation of the backup agent now.
16189             // If it is not yet live, this will be done when it attaches to the framework.
16190             if (proc.thread != null) {
16191                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16192                 try {
16193                     proc.thread.scheduleCreateBackupAgent(app,
16194                             compatibilityInfoForPackageLocked(app), backupMode);
16195                 } catch (RemoteException e) {
16196                     // Will time out on the backup manager side
16197                 }
16198             } else {
16199                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16200             }
16201             // Invariants: at this point, the target app process exists and the application
16202             // is either already running or in the process of coming up.  mBackupTarget and
16203             // mBackupAppName describe the app, so that when it binds back to the AM we
16204             // know that it's scheduled for a backup-agent operation.
16205         }
16206
16207         return true;
16208     }
16209
16210     @Override
16211     public void clearPendingBackup() {
16212         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16213         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16214
16215         synchronized (this) {
16216             mBackupTarget = null;
16217             mBackupAppName = null;
16218         }
16219     }
16220
16221     // A backup agent has just come up
16222     public void backupAgentCreated(String agentPackageName, IBinder agent) {
16223         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16224                 + " = " + agent);
16225
16226         synchronized(this) {
16227             if (!agentPackageName.equals(mBackupAppName)) {
16228                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16229                 return;
16230             }
16231         }
16232
16233         long oldIdent = Binder.clearCallingIdentity();
16234         try {
16235             IBackupManager bm = IBackupManager.Stub.asInterface(
16236                     ServiceManager.getService(Context.BACKUP_SERVICE));
16237             bm.agentConnected(agentPackageName, agent);
16238         } catch (RemoteException e) {
16239             // can't happen; the backup manager service is local
16240         } catch (Exception e) {
16241             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16242             e.printStackTrace();
16243         } finally {
16244             Binder.restoreCallingIdentity(oldIdent);
16245         }
16246     }
16247
16248     // done with this agent
16249     public void unbindBackupAgent(ApplicationInfo appInfo) {
16250         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16251         if (appInfo == null) {
16252             Slog.w(TAG, "unbind backup agent for null app");
16253             return;
16254         }
16255
16256         synchronized(this) {
16257             try {
16258                 if (mBackupAppName == null) {
16259                     Slog.w(TAG, "Unbinding backup agent with no active backup");
16260                     return;
16261                 }
16262
16263                 if (!mBackupAppName.equals(appInfo.packageName)) {
16264                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16265                     return;
16266                 }
16267
16268                 // Not backing this app up any more; reset its OOM adjustment
16269                 final ProcessRecord proc = mBackupTarget.app;
16270                 updateOomAdjLocked(proc);
16271
16272                 // If the app crashed during backup, 'thread' will be null here
16273                 if (proc.thread != null) {
16274                     try {
16275                         proc.thread.scheduleDestroyBackupAgent(appInfo,
16276                                 compatibilityInfoForPackageLocked(appInfo));
16277                     } catch (Exception e) {
16278                         Slog.e(TAG, "Exception when unbinding backup agent:");
16279                         e.printStackTrace();
16280                     }
16281                 }
16282             } finally {
16283                 mBackupTarget = null;
16284                 mBackupAppName = null;
16285             }
16286         }
16287     }
16288     // =========================================================
16289     // BROADCASTS
16290     // =========================================================
16291
16292     boolean isPendingBroadcastProcessLocked(int pid) {
16293         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16294                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16295     }
16296
16297     void skipPendingBroadcastLocked(int pid) {
16298             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16299             for (BroadcastQueue queue : mBroadcastQueues) {
16300                 queue.skipPendingBroadcastLocked(pid);
16301             }
16302     }
16303
16304     // The app just attached; send any pending broadcasts that it should receive
16305     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16306         boolean didSomething = false;
16307         for (BroadcastQueue queue : mBroadcastQueues) {
16308             didSomething |= queue.sendPendingBroadcastsLocked(app);
16309         }
16310         return didSomething;
16311     }
16312
16313     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16314             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16315         enforceNotIsolatedCaller("registerReceiver");
16316         ArrayList<Intent> stickyIntents = null;
16317         ProcessRecord callerApp = null;
16318         int callingUid;
16319         int callingPid;
16320         synchronized(this) {
16321             if (caller != null) {
16322                 callerApp = getRecordForAppLocked(caller);
16323                 if (callerApp == null) {
16324                     throw new SecurityException(
16325                             "Unable to find app for caller " + caller
16326                             + " (pid=" + Binder.getCallingPid()
16327                             + ") when registering receiver " + receiver);
16328                 }
16329                 if (callerApp.info.uid != Process.SYSTEM_UID &&
16330                         !callerApp.pkgList.containsKey(callerPackage) &&
16331                         !"android".equals(callerPackage)) {
16332                     throw new SecurityException("Given caller package " + callerPackage
16333                             + " is not running in process " + callerApp);
16334                 }
16335                 callingUid = callerApp.info.uid;
16336                 callingPid = callerApp.pid;
16337             } else {
16338                 callerPackage = null;
16339                 callingUid = Binder.getCallingUid();
16340                 callingPid = Binder.getCallingPid();
16341             }
16342
16343             userId = handleIncomingUser(callingPid, callingUid, userId,
16344                     true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16345
16346             Iterator<String> actions = filter.actionsIterator();
16347             if (actions == null) {
16348                 ArrayList<String> noAction = new ArrayList<String>(1);
16349                 noAction.add(null);
16350                 actions = noAction.iterator();
16351             }
16352
16353             // Collect stickies of users
16354             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16355             while (actions.hasNext()) {
16356                 String action = actions.next();
16357                 for (int id : userIds) {
16358                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16359                     if (stickies != null) {
16360                         ArrayList<Intent> intents = stickies.get(action);
16361                         if (intents != null) {
16362                             if (stickyIntents == null) {
16363                                 stickyIntents = new ArrayList<Intent>();
16364                             }
16365                             stickyIntents.addAll(intents);
16366                         }
16367                     }
16368                 }
16369             }
16370         }
16371
16372         ArrayList<Intent> allSticky = null;
16373         if (stickyIntents != null) {
16374             final ContentResolver resolver = mContext.getContentResolver();
16375             // Look for any matching sticky broadcasts...
16376             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16377                 Intent intent = stickyIntents.get(i);
16378                 // If intent has scheme "content", it will need to acccess
16379                 // provider that needs to lock mProviderMap in ActivityThread
16380                 // and also it may need to wait application response, so we
16381                 // cannot lock ActivityManagerService here.
16382                 if (filter.match(resolver, intent, true, TAG) >= 0) {
16383                     if (allSticky == null) {
16384                         allSticky = new ArrayList<Intent>();
16385                     }
16386                     allSticky.add(intent);
16387                 }
16388             }
16389         }
16390
16391         // The first sticky in the list is returned directly back to the client.
16392         Intent sticky = allSticky != null ? allSticky.get(0) : null;
16393         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16394         if (receiver == null) {
16395             return sticky;
16396         }
16397
16398         synchronized (this) {
16399             if (callerApp != null && (callerApp.thread == null
16400                     || callerApp.thread.asBinder() != caller.asBinder())) {
16401                 // Original caller already died
16402                 return null;
16403             }
16404             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16405             if (rl == null) {
16406                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16407                         userId, receiver);
16408                 if (rl.app != null) {
16409                     rl.app.receivers.add(rl);
16410                 } else {
16411                     try {
16412                         receiver.asBinder().linkToDeath(rl, 0);
16413                     } catch (RemoteException e) {
16414                         return sticky;
16415                     }
16416                     rl.linkedToDeath = true;
16417                 }
16418                 mRegisteredReceivers.put(receiver.asBinder(), rl);
16419             } else if (rl.uid != callingUid) {
16420                 throw new IllegalArgumentException(
16421                         "Receiver requested to register for uid " + callingUid
16422                         + " was previously registered for uid " + rl.uid);
16423             } else if (rl.pid != callingPid) {
16424                 throw new IllegalArgumentException(
16425                         "Receiver requested to register for pid " + callingPid
16426                         + " was previously registered for pid " + rl.pid);
16427             } else if (rl.userId != userId) {
16428                 throw new IllegalArgumentException(
16429                         "Receiver requested to register for user " + userId
16430                         + " was previously registered for user " + rl.userId);
16431             }
16432             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16433                     permission, callingUid, userId);
16434             rl.add(bf);
16435             if (!bf.debugCheck()) {
16436                 Slog.w(TAG, "==> For Dynamic broadcast");
16437             }
16438             mReceiverResolver.addFilter(bf);
16439
16440             // Enqueue broadcasts for all existing stickies that match
16441             // this filter.
16442             if (allSticky != null) {
16443                 ArrayList receivers = new ArrayList();
16444                 receivers.add(bf);
16445
16446                 final int stickyCount = allSticky.size();
16447                 for (int i = 0; i < stickyCount; i++) {
16448                     Intent intent = allSticky.get(i);
16449                     BroadcastQueue queue = broadcastQueueForIntent(intent);
16450                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16451                             null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16452                             null, 0, null, null, false, true, true, -1);
16453                     queue.enqueueParallelBroadcastLocked(r);
16454                     queue.scheduleBroadcastsLocked();
16455                 }
16456             }
16457
16458             return sticky;
16459         }
16460     }
16461
16462     public void unregisterReceiver(IIntentReceiver receiver) {
16463         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16464
16465         final long origId = Binder.clearCallingIdentity();
16466         try {
16467             boolean doTrim = false;
16468
16469             synchronized(this) {
16470                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16471                 if (rl != null) {
16472                     final BroadcastRecord r = rl.curBroadcast;
16473                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16474                         final boolean doNext = r.queue.finishReceiverLocked(
16475                                 r, r.resultCode, r.resultData, r.resultExtras,
16476                                 r.resultAbort, false);
16477                         if (doNext) {
16478                             doTrim = true;
16479                             r.queue.processNextBroadcast(false);
16480                         }
16481                     }
16482
16483                     if (rl.app != null) {
16484                         rl.app.receivers.remove(rl);
16485                     }
16486                     removeReceiverLocked(rl);
16487                     if (rl.linkedToDeath) {
16488                         rl.linkedToDeath = false;
16489                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
16490                     }
16491                 }
16492             }
16493
16494             // If we actually concluded any broadcasts, we might now be able
16495             // to trim the recipients' apps from our working set
16496             if (doTrim) {
16497                 trimApplications();
16498                 return;
16499             }
16500
16501         } finally {
16502             Binder.restoreCallingIdentity(origId);
16503         }
16504     }
16505
16506     void removeReceiverLocked(ReceiverList rl) {
16507         mRegisteredReceivers.remove(rl.receiver.asBinder());
16508         for (int i = rl.size() - 1; i >= 0; i--) {
16509             mReceiverResolver.removeFilter(rl.get(i));
16510         }
16511     }
16512
16513     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16514         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16515             ProcessRecord r = mLruProcesses.get(i);
16516             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16517                 try {
16518                     r.thread.dispatchPackageBroadcast(cmd, packages);
16519                 } catch (RemoteException ex) {
16520                 }
16521             }
16522         }
16523     }
16524
16525     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16526             int callingUid, int[] users) {
16527         List<ResolveInfo> receivers = null;
16528         try {
16529             HashSet<ComponentName> singleUserReceivers = null;
16530             boolean scannedFirstReceivers = false;
16531             for (int user : users) {
16532                 // Skip users that have Shell restrictions
16533                 if (callingUid == Process.SHELL_UID
16534                         && getUserManagerLocked().hasUserRestriction(
16535                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16536                     continue;
16537                 }
16538                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16539                         .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16540                 if (user != UserHandle.USER_OWNER && newReceivers != null) {
16541                     // If this is not the primary user, we need to check for
16542                     // any receivers that should be filtered out.
16543                     for (int i=0; i<newReceivers.size(); i++) {
16544                         ResolveInfo ri = newReceivers.get(i);
16545                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16546                             newReceivers.remove(i);
16547                             i--;
16548                         }
16549                     }
16550                 }
16551                 if (newReceivers != null && newReceivers.size() == 0) {
16552                     newReceivers = null;
16553                 }
16554                 if (receivers == null) {
16555                     receivers = newReceivers;
16556                 } else if (newReceivers != null) {
16557                     // We need to concatenate the additional receivers
16558                     // found with what we have do far.  This would be easy,
16559                     // but we also need to de-dup any receivers that are
16560                     // singleUser.
16561                     if (!scannedFirstReceivers) {
16562                         // Collect any single user receivers we had already retrieved.
16563                         scannedFirstReceivers = true;
16564                         for (int i=0; i<receivers.size(); i++) {
16565                             ResolveInfo ri = receivers.get(i);
16566                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16567                                 ComponentName cn = new ComponentName(
16568                                         ri.activityInfo.packageName, ri.activityInfo.name);
16569                                 if (singleUserReceivers == null) {
16570                                     singleUserReceivers = new HashSet<ComponentName>();
16571                                 }
16572                                 singleUserReceivers.add(cn);
16573                             }
16574                         }
16575                     }
16576                     // Add the new results to the existing results, tracking
16577                     // and de-dupping single user receivers.
16578                     for (int i=0; i<newReceivers.size(); i++) {
16579                         ResolveInfo ri = newReceivers.get(i);
16580                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16581                             ComponentName cn = new ComponentName(
16582                                     ri.activityInfo.packageName, ri.activityInfo.name);
16583                             if (singleUserReceivers == null) {
16584                                 singleUserReceivers = new HashSet<ComponentName>();
16585                             }
16586                             if (!singleUserReceivers.contains(cn)) {
16587                                 singleUserReceivers.add(cn);
16588                                 receivers.add(ri);
16589                             }
16590                         } else {
16591                             receivers.add(ri);
16592                         }
16593                     }
16594                 }
16595             }
16596         } catch (RemoteException ex) {
16597             // pm is in same process, this will never happen.
16598         }
16599         return receivers;
16600     }
16601
16602     private final int broadcastIntentLocked(ProcessRecord callerApp,
16603             String callerPackage, Intent intent, String resolvedType,
16604             IIntentReceiver resultTo, int resultCode, String resultData,
16605             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle options,
16606             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16607         intent = new Intent(intent);
16608
16609         // By default broadcasts do not go to stopped apps.
16610         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16611
16612         // If we have not finished booting, don't allow this to launch new processes.
16613         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16614             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16615         }
16616
16617         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16618                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16619                 + " ordered=" + ordered + " userid=" + userId);
16620         if ((resultTo != null) && !ordered) {
16621             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16622         }
16623
16624         userId = handleIncomingUser(callingPid, callingUid, userId,
16625                 true, ALLOW_NON_FULL, "broadcast", callerPackage);
16626
16627         // Make sure that the user who is receiving this broadcast is running.
16628         // If not, we will just skip it. Make an exception for shutdown broadcasts
16629         // and upgrade steps.
16630
16631         if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16632             if ((callingUid != Process.SYSTEM_UID
16633                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16634                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16635                 Slog.w(TAG, "Skipping broadcast of " + intent
16636                         + ": user " + userId + " is stopped");
16637                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16638             }
16639         }
16640
16641         BroadcastOptions brOptions = null;
16642         if (options != null) {
16643             brOptions = new BroadcastOptions(options);
16644             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16645                 // See if the caller is allowed to do this.  Note we are checking against
16646                 // the actual real caller (not whoever provided the operation as say a
16647                 // PendingIntent), because that who is actually supplied the arguments.
16648                 if (checkComponentPermission(
16649                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16650                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16651                         != PackageManager.PERMISSION_GRANTED) {
16652                     String msg = "Permission Denial: " + intent.getAction()
16653                             + " broadcast from " + callerPackage + " (pid=" + callingPid
16654                             + ", uid=" + callingUid + ")"
16655                             + " requires "
16656                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16657                     Slog.w(TAG, msg);
16658                     throw new SecurityException(msg);
16659                 }
16660             }
16661         }
16662
16663         /*
16664          * Prevent non-system code (defined here to be non-persistent
16665          * processes) from sending protected broadcasts.
16666          */
16667         int callingAppId = UserHandle.getAppId(callingUid);
16668         if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16669             || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16670             || callingAppId == Process.NFC_UID || callingUid == 0) {
16671             // Always okay.
16672         } else if (callerApp == null || !callerApp.persistent) {
16673             try {
16674                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
16675                         intent.getAction())) {
16676                     String msg = "Permission Denial: not allowed to send broadcast "
16677                             + intent.getAction() + " from pid="
16678                             + callingPid + ", uid=" + callingUid;
16679                     Slog.w(TAG, msg);
16680                     throw new SecurityException(msg);
16681                 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16682                     // Special case for compatibility: we don't want apps to send this,
16683                     // but historically it has not been protected and apps may be using it
16684                     // to poke their own app widget.  So, instead of making it protected,
16685                     // just limit it to the caller.
16686                     if (callerApp == null) {
16687                         String msg = "Permission Denial: not allowed to send broadcast "
16688                                 + intent.getAction() + " from unknown caller.";
16689                         Slog.w(TAG, msg);
16690                         throw new SecurityException(msg);
16691                     } else if (intent.getComponent() != null) {
16692                         // They are good enough to send to an explicit component...  verify
16693                         // it is being sent to the calling app.
16694                         if (!intent.getComponent().getPackageName().equals(
16695                                 callerApp.info.packageName)) {
16696                             String msg = "Permission Denial: not allowed to send broadcast "
16697                                     + intent.getAction() + " to "
16698                                     + intent.getComponent().getPackageName() + " from "
16699                                     + callerApp.info.packageName;
16700                             Slog.w(TAG, msg);
16701                             throw new SecurityException(msg);
16702                         }
16703                     } else {
16704                         // Limit broadcast to their own package.
16705                         intent.setPackage(callerApp.info.packageName);
16706                     }
16707                 }
16708             } catch (RemoteException e) {
16709                 Slog.w(TAG, "Remote exception", e);
16710                 return ActivityManager.BROADCAST_SUCCESS;
16711             }
16712         }
16713
16714         final String action = intent.getAction();
16715         if (action != null) {
16716             switch (action) {
16717                 case Intent.ACTION_UID_REMOVED:
16718                 case Intent.ACTION_PACKAGE_REMOVED:
16719                 case Intent.ACTION_PACKAGE_CHANGED:
16720                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16721                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16722                     // Handle special intents: if this broadcast is from the package
16723                     // manager about a package being removed, we need to remove all of
16724                     // its activities from the history stack.
16725                     if (checkComponentPermission(
16726                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16727                             callingPid, callingUid, -1, true)
16728                             != PackageManager.PERMISSION_GRANTED) {
16729                         String msg = "Permission Denial: " + intent.getAction()
16730                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
16731                                 + ", uid=" + callingUid + ")"
16732                                 + " requires "
16733                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16734                         Slog.w(TAG, msg);
16735                         throw new SecurityException(msg);
16736                     }
16737                     switch (action) {
16738                         case Intent.ACTION_UID_REMOVED:
16739                             final Bundle intentExtras = intent.getExtras();
16740                             final int uid = intentExtras != null
16741                                     ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16742                             if (uid >= 0) {
16743                                 mBatteryStatsService.removeUid(uid);
16744                                 mAppOpsService.uidRemoved(uid);
16745                             }
16746                             break;
16747                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16748                             // If resources are unavailable just force stop all those packages
16749                             // and flush the attribute cache as well.
16750                             String list[] =
16751                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16752                             if (list != null && list.length > 0) {
16753                                 for (int i = 0; i < list.length; i++) {
16754                                     forceStopPackageLocked(list[i], -1, false, true, true,
16755                                             false, false, userId, "storage unmount");
16756                                 }
16757                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16758                                 sendPackageBroadcastLocked(
16759                                         IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16760                                         userId);
16761                             }
16762                             break;
16763                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16764                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16765                             break;
16766                         case Intent.ACTION_PACKAGE_REMOVED:
16767                         case Intent.ACTION_PACKAGE_CHANGED:
16768                             Uri data = intent.getData();
16769                             String ssp;
16770                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16771                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16772                                 boolean fullUninstall = removed &&
16773                                         !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16774                                 final boolean killProcess =
16775                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
16776                                 if (killProcess) {
16777                                     forceStopPackageLocked(ssp, UserHandle.getAppId(
16778                                             intent.getIntExtra(Intent.EXTRA_UID, -1)),
16779                                             false, true, true, false, fullUninstall, userId,
16780                                             removed ? "pkg removed" : "pkg changed");
16781                                 }
16782                                 if (removed) {
16783                                     sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16784                                             new String[] {ssp}, userId);
16785                                     if (fullUninstall) {
16786                                         mAppOpsService.packageRemoved(
16787                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16788
16789                                         // Remove all permissions granted from/to this package
16790                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
16791
16792                                         removeTasksByPackageNameLocked(ssp, userId);
16793                                         mBatteryStatsService.notePackageUninstalled(ssp);
16794                                     }
16795                                 } else {
16796                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
16797                                             intent.getStringArrayExtra(
16798                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16799                                 }
16800                             }
16801                             break;
16802                     }
16803                     break;
16804                 case Intent.ACTION_PACKAGE_ADDED:
16805                     // Special case for adding a package: by default turn on compatibility mode.
16806                     Uri data = intent.getData();
16807                     String ssp;
16808                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16809                         final boolean replacing =
16810                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16811                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16812
16813                         try {
16814                             ApplicationInfo ai = AppGlobals.getPackageManager().
16815                                     getApplicationInfo(ssp, 0, 0);
16816                             mBatteryStatsService.notePackageInstalled(ssp,
16817                                     ai != null ? ai.versionCode : 0);
16818                         } catch (RemoteException e) {
16819                         }
16820                     }
16821                     break;
16822                 case Intent.ACTION_TIMEZONE_CHANGED:
16823                     // If this is the time zone changed action, queue up a message that will reset
16824                     // the timezone of all currently running processes. This message will get
16825                     // queued up before the broadcast happens.
16826                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16827                     break;
16828                 case Intent.ACTION_TIME_CHANGED:
16829                     // If the user set the time, let all running processes know.
16830                     final int is24Hour =
16831                             intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16832                                     : 0;
16833                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16834                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16835                     synchronized (stats) {
16836                         stats.noteCurrentTimeChangedLocked();
16837                     }
16838                     break;
16839                 case Intent.ACTION_CLEAR_DNS_CACHE:
16840                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16841                     break;
16842                 case Proxy.PROXY_CHANGE_ACTION:
16843                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16844                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16845                     break;
16846             }
16847         }
16848
16849         // Add to the sticky list if requested.
16850         if (sticky) {
16851             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16852                     callingPid, callingUid)
16853                     != PackageManager.PERMISSION_GRANTED) {
16854                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16855                         + callingPid + ", uid=" + callingUid
16856                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16857                 Slog.w(TAG, msg);
16858                 throw new SecurityException(msg);
16859             }
16860             if (requiredPermissions != null && requiredPermissions.length > 0) {
16861                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
16862                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
16863                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16864             }
16865             if (intent.getComponent() != null) {
16866                 throw new SecurityException(
16867                         "Sticky broadcasts can't target a specific component");
16868             }
16869             // We use userId directly here, since the "all" target is maintained
16870             // as a separate set of sticky broadcasts.
16871             if (userId != UserHandle.USER_ALL) {
16872                 // But first, if this is not a broadcast to all users, then
16873                 // make sure it doesn't conflict with an existing broadcast to
16874                 // all users.
16875                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16876                         UserHandle.USER_ALL);
16877                 if (stickies != null) {
16878                     ArrayList<Intent> list = stickies.get(intent.getAction());
16879                     if (list != null) {
16880                         int N = list.size();
16881                         int i;
16882                         for (i=0; i<N; i++) {
16883                             if (intent.filterEquals(list.get(i))) {
16884                                 throw new IllegalArgumentException(
16885                                         "Sticky broadcast " + intent + " for user "
16886                                         + userId + " conflicts with existing global broadcast");
16887                             }
16888                         }
16889                     }
16890                 }
16891             }
16892             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16893             if (stickies == null) {
16894                 stickies = new ArrayMap<>();
16895                 mStickyBroadcasts.put(userId, stickies);
16896             }
16897             ArrayList<Intent> list = stickies.get(intent.getAction());
16898             if (list == null) {
16899                 list = new ArrayList<>();
16900                 stickies.put(intent.getAction(), list);
16901             }
16902             final int stickiesCount = list.size();
16903             int i;
16904             for (i = 0; i < stickiesCount; i++) {
16905                 if (intent.filterEquals(list.get(i))) {
16906                     // This sticky already exists, replace it.
16907                     list.set(i, new Intent(intent));
16908                     break;
16909                 }
16910             }
16911             if (i >= stickiesCount) {
16912                 list.add(new Intent(intent));
16913             }
16914         }
16915
16916         int[] users;
16917         if (userId == UserHandle.USER_ALL) {
16918             // Caller wants broadcast to go to all started users.
16919             users = mStartedUserArray;
16920         } else {
16921             // Caller wants broadcast to go to one specific user.
16922             users = new int[] {userId};
16923         }
16924
16925         // Figure out who all will receive this broadcast.
16926         List receivers = null;
16927         List<BroadcastFilter> registeredReceivers = null;
16928         // Need to resolve the intent to interested receivers...
16929         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16930                  == 0) {
16931             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16932         }
16933         if (intent.getComponent() == null) {
16934             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16935                 // Query one target user at a time, excluding shell-restricted users
16936                 UserManagerService ums = getUserManagerLocked();
16937                 for (int i = 0; i < users.length; i++) {
16938                     if (ums.hasUserRestriction(
16939                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16940                         continue;
16941                     }
16942                     List<BroadcastFilter> registeredReceiversForUser =
16943                             mReceiverResolver.queryIntent(intent,
16944                                     resolvedType, false, users[i]);
16945                     if (registeredReceivers == null) {
16946                         registeredReceivers = registeredReceiversForUser;
16947                     } else if (registeredReceiversForUser != null) {
16948                         registeredReceivers.addAll(registeredReceiversForUser);
16949                     }
16950                 }
16951             } else {
16952                 registeredReceivers = mReceiverResolver.queryIntent(intent,
16953                         resolvedType, false, userId);
16954             }
16955         }
16956
16957         final boolean replacePending =
16958                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16959
16960         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16961                 + " replacePending=" + replacePending);
16962
16963         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16964         if (!ordered && NR > 0) {
16965             // If we are not serializing this broadcast, then send the
16966             // registered receivers separately so they don't wait for the
16967             // components to be launched.
16968             final BroadcastQueue queue = broadcastQueueForIntent(intent);
16969             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16970                     callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
16971                     appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
16972                     resultExtras, ordered, sticky, false, userId);
16973             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16974             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16975             if (!replaced) {
16976                 queue.enqueueParallelBroadcastLocked(r);
16977                 queue.scheduleBroadcastsLocked();
16978             }
16979             registeredReceivers = null;
16980             NR = 0;
16981         }
16982
16983         // Merge into one list.
16984         int ir = 0;
16985         if (receivers != null) {
16986             // A special case for PACKAGE_ADDED: do not allow the package
16987             // being added to see this broadcast.  This prevents them from
16988             // using this as a back door to get run as soon as they are
16989             // installed.  Maybe in the future we want to have a special install
16990             // broadcast or such for apps, but we'd like to deliberately make
16991             // this decision.
16992             String skipPackages[] = null;
16993             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16994                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16995                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16996                 Uri data = intent.getData();
16997                 if (data != null) {
16998                     String pkgName = data.getSchemeSpecificPart();
16999                     if (pkgName != null) {
17000                         skipPackages = new String[] { pkgName };
17001                     }
17002                 }
17003             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17004                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17005             }
17006             if (skipPackages != null && (skipPackages.length > 0)) {
17007                 for (String skipPackage : skipPackages) {
17008                     if (skipPackage != null) {
17009                         int NT = receivers.size();
17010                         for (int it=0; it<NT; it++) {
17011                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
17012                             if (curt.activityInfo.packageName.equals(skipPackage)) {
17013                                 receivers.remove(it);
17014                                 it--;
17015                                 NT--;
17016                             }
17017                         }
17018                     }
17019                 }
17020             }
17021
17022             int NT = receivers != null ? receivers.size() : 0;
17023             int it = 0;
17024             ResolveInfo curt = null;
17025             BroadcastFilter curr = null;
17026             while (it < NT && ir < NR) {
17027                 if (curt == null) {
17028                     curt = (ResolveInfo)receivers.get(it);
17029                 }
17030                 if (curr == null) {
17031                     curr = registeredReceivers.get(ir);
17032                 }
17033                 if (curr.getPriority() >= curt.priority) {
17034                     // Insert this broadcast record into the final list.
17035                     receivers.add(it, curr);
17036                     ir++;
17037                     curr = null;
17038                     it++;
17039                     NT++;
17040                 } else {
17041                     // Skip to the next ResolveInfo in the final list.
17042                     it++;
17043                     curt = null;
17044                 }
17045             }
17046         }
17047         while (ir < NR) {
17048             if (receivers == null) {
17049                 receivers = new ArrayList();
17050             }
17051             receivers.add(registeredReceivers.get(ir));
17052             ir++;
17053         }
17054
17055         if ((receivers != null && receivers.size() > 0)
17056                 || resultTo != null) {
17057             BroadcastQueue queue = broadcastQueueForIntent(intent);
17058             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17059                     callerPackage, callingPid, callingUid, resolvedType,
17060                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17061                     resultData, resultExtras, ordered, sticky, false, userId);
17062
17063             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17064                     + ": prev had " + queue.mOrderedBroadcasts.size());
17065             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17066                     "Enqueueing broadcast " + r.intent.getAction());
17067
17068             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17069             if (!replaced) {
17070                 queue.enqueueOrderedBroadcastLocked(r);
17071                 queue.scheduleBroadcastsLocked();
17072             }
17073         }
17074
17075         return ActivityManager.BROADCAST_SUCCESS;
17076     }
17077
17078     final Intent verifyBroadcastLocked(Intent intent) {
17079         // Refuse possible leaked file descriptors
17080         if (intent != null && intent.hasFileDescriptors() == true) {
17081             throw new IllegalArgumentException("File descriptors passed in Intent");
17082         }
17083
17084         int flags = intent.getFlags();
17085
17086         if (!mProcessesReady) {
17087             // if the caller really truly claims to know what they're doing, go
17088             // ahead and allow the broadcast without launching any receivers
17089             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17090                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17091             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17092                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17093                         + " before boot completion");
17094                 throw new IllegalStateException("Cannot broadcast before boot completed");
17095             }
17096         }
17097
17098         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17099             throw new IllegalArgumentException(
17100                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17101         }
17102
17103         return intent;
17104     }
17105
17106     public final int broadcastIntent(IApplicationThread caller,
17107             Intent intent, String resolvedType, IIntentReceiver resultTo,
17108             int resultCode, String resultData, Bundle resultExtras,
17109             String[] requiredPermissions, int appOp, Bundle options,
17110             boolean serialized, boolean sticky, int userId) {
17111         enforceNotIsolatedCaller("broadcastIntent");
17112         synchronized(this) {
17113             intent = verifyBroadcastLocked(intent);
17114
17115             final ProcessRecord callerApp = getRecordForAppLocked(caller);
17116             final int callingPid = Binder.getCallingPid();
17117             final int callingUid = Binder.getCallingUid();
17118             final long origId = Binder.clearCallingIdentity();
17119             int res = broadcastIntentLocked(callerApp,
17120                     callerApp != null ? callerApp.info.packageName : null,
17121                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17122                     requiredPermissions, appOp, null, serialized, sticky,
17123                     callingPid, callingUid, userId);
17124             Binder.restoreCallingIdentity(origId);
17125             return res;
17126         }
17127     }
17128
17129
17130     int broadcastIntentInPackage(String packageName, int uid,
17131             Intent intent, String resolvedType, IIntentReceiver resultTo,
17132             int resultCode, String resultData, Bundle resultExtras,
17133             String requiredPermission, Bundle options, boolean serialized, boolean sticky,
17134             int userId) {
17135         synchronized(this) {
17136             intent = verifyBroadcastLocked(intent);
17137
17138             final long origId = Binder.clearCallingIdentity();
17139             String[] requiredPermissions = requiredPermission == null ? null
17140                     : new String[] {requiredPermission};
17141             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17142                     resultTo, resultCode, resultData, resultExtras,
17143                     requiredPermissions, AppOpsManager.OP_NONE, options, serialized,
17144                     sticky, -1, uid, userId);
17145             Binder.restoreCallingIdentity(origId);
17146             return res;
17147         }
17148     }
17149
17150     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17151         // Refuse possible leaked file descriptors
17152         if (intent != null && intent.hasFileDescriptors() == true) {
17153             throw new IllegalArgumentException("File descriptors passed in Intent");
17154         }
17155
17156         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17157                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17158
17159         synchronized(this) {
17160             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17161                     != PackageManager.PERMISSION_GRANTED) {
17162                 String msg = "Permission Denial: unbroadcastIntent() from pid="
17163                         + Binder.getCallingPid()
17164                         + ", uid=" + Binder.getCallingUid()
17165                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17166                 Slog.w(TAG, msg);
17167                 throw new SecurityException(msg);
17168             }
17169             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17170             if (stickies != null) {
17171                 ArrayList<Intent> list = stickies.get(intent.getAction());
17172                 if (list != null) {
17173                     int N = list.size();
17174                     int i;
17175                     for (i=0; i<N; i++) {
17176                         if (intent.filterEquals(list.get(i))) {
17177                             list.remove(i);
17178                             break;
17179                         }
17180                     }
17181                     if (list.size() <= 0) {
17182                         stickies.remove(intent.getAction());
17183                     }
17184                 }
17185                 if (stickies.size() <= 0) {
17186                     mStickyBroadcasts.remove(userId);
17187                 }
17188             }
17189         }
17190     }
17191
17192     void backgroundServicesFinishedLocked(int userId) {
17193         for (BroadcastQueue queue : mBroadcastQueues) {
17194             queue.backgroundServicesFinishedLocked(userId);
17195         }
17196     }
17197
17198     public void finishReceiver(IBinder who, int resultCode, String resultData,
17199             Bundle resultExtras, boolean resultAbort, int flags) {
17200         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17201
17202         // Refuse possible leaked file descriptors
17203         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17204             throw new IllegalArgumentException("File descriptors passed in Bundle");
17205         }
17206
17207         final long origId = Binder.clearCallingIdentity();
17208         try {
17209             boolean doNext = false;
17210             BroadcastRecord r;
17211
17212             synchronized(this) {
17213                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17214                         ? mFgBroadcastQueue : mBgBroadcastQueue;
17215                 r = queue.getMatchingOrderedReceiver(who);
17216                 if (r != null) {
17217                     doNext = r.queue.finishReceiverLocked(r, resultCode,
17218                         resultData, resultExtras, resultAbort, true);
17219                 }
17220             }
17221
17222             if (doNext) {
17223                 r.queue.processNextBroadcast(false);
17224             }
17225             trimApplications();
17226         } finally {
17227             Binder.restoreCallingIdentity(origId);
17228         }
17229     }
17230
17231     // =========================================================
17232     // INSTRUMENTATION
17233     // =========================================================
17234
17235     public boolean startInstrumentation(ComponentName className,
17236             String profileFile, int flags, Bundle arguments,
17237             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17238             int userId, String abiOverride) {
17239         enforceNotIsolatedCaller("startInstrumentation");
17240         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17241                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17242         // Refuse possible leaked file descriptors
17243         if (arguments != null && arguments.hasFileDescriptors()) {
17244             throw new IllegalArgumentException("File descriptors passed in Bundle");
17245         }
17246
17247         synchronized(this) {
17248             InstrumentationInfo ii = null;
17249             ApplicationInfo ai = null;
17250             try {
17251                 ii = mContext.getPackageManager().getInstrumentationInfo(
17252                     className, STOCK_PM_FLAGS);
17253                 ai = AppGlobals.getPackageManager().getApplicationInfo(
17254                         ii.targetPackage, STOCK_PM_FLAGS, userId);
17255             } catch (PackageManager.NameNotFoundException e) {
17256             } catch (RemoteException e) {
17257             }
17258             if (ii == null) {
17259                 reportStartInstrumentationFailure(watcher, className,
17260                         "Unable to find instrumentation info for: " + className);
17261                 return false;
17262             }
17263             if (ai == null) {
17264                 reportStartInstrumentationFailure(watcher, className,
17265                         "Unable to find instrumentation target package: " + ii.targetPackage);
17266                 return false;
17267             }
17268
17269             int match = mContext.getPackageManager().checkSignatures(
17270                     ii.targetPackage, ii.packageName);
17271             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17272                 String msg = "Permission Denial: starting instrumentation "
17273                         + className + " from pid="
17274                         + Binder.getCallingPid()
17275                         + ", uid=" + Binder.getCallingPid()
17276                         + " not allowed because package " + ii.packageName
17277                         + " does not have a signature matching the target "
17278                         + ii.targetPackage;
17279                 reportStartInstrumentationFailure(watcher, className, msg);
17280                 throw new SecurityException(msg);
17281             }
17282
17283             final long origId = Binder.clearCallingIdentity();
17284             // Instrumentation can kill and relaunch even persistent processes
17285             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17286                     "start instr");
17287             ProcessRecord app = addAppLocked(ai, false, abiOverride);
17288             app.instrumentationClass = className;
17289             app.instrumentationInfo = ai;
17290             app.instrumentationProfileFile = profileFile;
17291             app.instrumentationArguments = arguments;
17292             app.instrumentationWatcher = watcher;
17293             app.instrumentationUiAutomationConnection = uiAutomationConnection;
17294             app.instrumentationResultClass = className;
17295             Binder.restoreCallingIdentity(origId);
17296         }
17297
17298         return true;
17299     }
17300
17301     /**
17302      * Report errors that occur while attempting to start Instrumentation.  Always writes the
17303      * error to the logs, but if somebody is watching, send the report there too.  This enables
17304      * the "am" command to report errors with more information.
17305      *
17306      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17307      * @param cn The component name of the instrumentation.
17308      * @param report The error report.
17309      */
17310     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17311             ComponentName cn, String report) {
17312         Slog.w(TAG, report);
17313         try {
17314             if (watcher != null) {
17315                 Bundle results = new Bundle();
17316                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17317                 results.putString("Error", report);
17318                 watcher.instrumentationStatus(cn, -1, results);
17319             }
17320         } catch (RemoteException e) {
17321             Slog.w(TAG, e);
17322         }
17323     }
17324
17325     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17326         if (app.instrumentationWatcher != null) {
17327             try {
17328                 // NOTE:  IInstrumentationWatcher *must* be oneway here
17329                 app.instrumentationWatcher.instrumentationFinished(
17330                     app.instrumentationClass,
17331                     resultCode,
17332                     results);
17333             } catch (RemoteException e) {
17334             }
17335         }
17336
17337         // Can't call out of the system process with a lock held, so post a message.
17338         if (app.instrumentationUiAutomationConnection != null) {
17339             mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17340                     app.instrumentationUiAutomationConnection).sendToTarget();
17341         }
17342
17343         app.instrumentationWatcher = null;
17344         app.instrumentationUiAutomationConnection = null;
17345         app.instrumentationClass = null;
17346         app.instrumentationInfo = null;
17347         app.instrumentationProfileFile = null;
17348         app.instrumentationArguments = null;
17349
17350         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17351                 "finished inst");
17352     }
17353
17354     public void finishInstrumentation(IApplicationThread target,
17355             int resultCode, Bundle results) {
17356         int userId = UserHandle.getCallingUserId();
17357         // Refuse possible leaked file descriptors
17358         if (results != null && results.hasFileDescriptors()) {
17359             throw new IllegalArgumentException("File descriptors passed in Intent");
17360         }
17361
17362         synchronized(this) {
17363             ProcessRecord app = getRecordForAppLocked(target);
17364             if (app == null) {
17365                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
17366                 return;
17367             }
17368             final long origId = Binder.clearCallingIdentity();
17369             finishInstrumentationLocked(app, resultCode, results);
17370             Binder.restoreCallingIdentity(origId);
17371         }
17372     }
17373
17374     // =========================================================
17375     // CONFIGURATION
17376     // =========================================================
17377
17378     public ConfigurationInfo getDeviceConfigurationInfo() {
17379         ConfigurationInfo config = new ConfigurationInfo();
17380         synchronized (this) {
17381             config.reqTouchScreen = mConfiguration.touchscreen;
17382             config.reqKeyboardType = mConfiguration.keyboard;
17383             config.reqNavigation = mConfiguration.navigation;
17384             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17385                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17386                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17387             }
17388             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17389                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17390                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17391             }
17392             config.reqGlEsVersion = GL_ES_VERSION;
17393         }
17394         return config;
17395     }
17396
17397     ActivityStack getFocusedStack() {
17398         return mStackSupervisor.getFocusedStack();
17399     }
17400
17401     @Override
17402     public int getFocusedStackId() throws RemoteException {
17403         ActivityStack focusedStack = getFocusedStack();
17404         if (focusedStack != null) {
17405             return focusedStack.getStackId();
17406         }
17407         return -1;
17408     }
17409
17410     public Configuration getConfiguration() {
17411         Configuration ci;
17412         synchronized(this) {
17413             ci = new Configuration(mConfiguration);
17414             ci.userSetLocale = false;
17415         }
17416         return ci;
17417     }
17418
17419     public void updatePersistentConfiguration(Configuration values) {
17420         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17421                 "updateConfiguration()");
17422         enforceWriteSettingsPermission("updateConfiguration()");
17423         if (values == null) {
17424             throw new NullPointerException("Configuration must not be null");
17425         }
17426
17427         synchronized(this) {
17428             final long origId = Binder.clearCallingIdentity();
17429             updateConfigurationLocked(values, null, true, false);
17430             Binder.restoreCallingIdentity(origId);
17431         }
17432     }
17433
17434     private void enforceWriteSettingsPermission(String func) {
17435         int uid = Binder.getCallingUid();
17436         if (uid == Process.ROOT_UID) {
17437             return;
17438         }
17439
17440         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17441                 Settings.getPackageNameForUid(mContext, uid), false)) {
17442             return;
17443         }
17444
17445         String msg = "Permission Denial: " + func + " from pid="
17446                 + Binder.getCallingPid()
17447                 + ", uid=" + uid
17448                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17449         Slog.w(TAG, msg);
17450         throw new SecurityException(msg);
17451     }
17452
17453     public void updateConfiguration(Configuration values) {
17454         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17455                 "updateConfiguration()");
17456
17457         synchronized(this) {
17458             if (values == null && mWindowManager != null) {
17459                 // sentinel: fetch the current configuration from the window manager
17460                 values = mWindowManager.computeNewConfiguration();
17461             }
17462
17463             if (mWindowManager != null) {
17464                 mProcessList.applyDisplaySize(mWindowManager);
17465             }
17466
17467             final long origId = Binder.clearCallingIdentity();
17468             if (values != null) {
17469                 Settings.System.clearConfiguration(values);
17470             }
17471             updateConfigurationLocked(values, null, false, false);
17472             Binder.restoreCallingIdentity(origId);
17473         }
17474     }
17475
17476     /**
17477      * Do either or both things: (1) change the current configuration, and (2)
17478      * make sure the given activity is running with the (now) current
17479      * configuration.  Returns true if the activity has been left running, or
17480      * false if <var>starting</var> is being destroyed to match the new
17481      * configuration.
17482      * @param persistent TODO
17483      */
17484     boolean updateConfigurationLocked(Configuration values,
17485             ActivityRecord starting, boolean persistent, boolean initLocale) {
17486         int changes = 0;
17487
17488         if (values != null) {
17489             Configuration newConfig = new Configuration(mConfiguration);
17490             changes = newConfig.updateFrom(values);
17491             if (changes != 0) {
17492                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17493                         "Updating configuration to: " + values);
17494
17495                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17496
17497                 if (!initLocale && values.locale != null && values.userSetLocale) {
17498                     final String languageTag = values.locale.toLanguageTag();
17499                     SystemProperties.set("persist.sys.locale", languageTag);
17500                     mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17501                             values.locale));
17502                 }
17503
17504                 mConfigurationSeq++;
17505                 if (mConfigurationSeq <= 0) {
17506                     mConfigurationSeq = 1;
17507                 }
17508                 newConfig.seq = mConfigurationSeq;
17509                 mConfiguration = newConfig;
17510                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17511                 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17512                 //mUsageStatsService.noteStartConfig(newConfig);
17513
17514                 final Configuration configCopy = new Configuration(mConfiguration);
17515
17516                 // TODO: If our config changes, should we auto dismiss any currently
17517                 // showing dialogs?
17518                 mShowDialogs = shouldShowDialogs(newConfig);
17519
17520                 AttributeCache ac = AttributeCache.instance();
17521                 if (ac != null) {
17522                     ac.updateConfiguration(configCopy);
17523                 }
17524
17525                 // Make sure all resources in our process are updated
17526                 // right now, so that anyone who is going to retrieve
17527                 // resource values after we return will be sure to get
17528                 // the new ones.  This is especially important during
17529                 // boot, where the first config change needs to guarantee
17530                 // all resources have that config before following boot
17531                 // code is executed.
17532                 mSystemThread.applyConfigurationToResources(configCopy);
17533
17534                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17535                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17536                     msg.obj = new Configuration(configCopy);
17537                     mHandler.sendMessage(msg);
17538                 }
17539
17540                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
17541                     ProcessRecord app = mLruProcesses.get(i);
17542                     try {
17543                         if (app.thread != null) {
17544                             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17545                                     + app.processName + " new config " + mConfiguration);
17546                             app.thread.scheduleConfigurationChanged(configCopy);
17547                         }
17548                     } catch (Exception e) {
17549                     }
17550                 }
17551                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17552                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17553                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
17554                         | Intent.FLAG_RECEIVER_FOREGROUND);
17555                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17556                         null, AppOpsManager.OP_NONE, null, false, false,
17557                         MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17558                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17559                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17560                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17561                     if (!mProcessesReady) {
17562                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17563                     }
17564                     broadcastIntentLocked(null, null, intent,
17565                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17566                             null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17567                 }
17568             }
17569         }
17570
17571         boolean kept = true;
17572         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17573         // mainStack is null during startup.
17574         if (mainStack != null) {
17575             if (changes != 0 && starting == null) {
17576                 // If the configuration changed, and the caller is not already
17577                 // in the process of starting an activity, then find the top
17578                 // activity to check if its configuration needs to change.
17579                 starting = mainStack.topRunningActivityLocked(null);
17580             }
17581
17582             if (starting != null) {
17583                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17584                 // And we need to make sure at this point that all other activities
17585                 // are made visible with the correct configuration.
17586                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17587             }
17588         }
17589
17590         if (values != null && mWindowManager != null) {
17591             mWindowManager.setNewConfiguration(mConfiguration);
17592         }
17593
17594         return kept;
17595     }
17596
17597     /**
17598      * Decide based on the configuration whether we should shouw the ANR,
17599      * crash, etc dialogs.  The idea is that if there is no affordnace to
17600      * press the on-screen buttons, we shouldn't show the dialog.
17601      *
17602      * A thought: SystemUI might also want to get told about this, the Power
17603      * dialog / global actions also might want different behaviors.
17604      */
17605     private static final boolean shouldShowDialogs(Configuration config) {
17606         return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17607                 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17608                 && config.navigation == Configuration.NAVIGATION_NONAV);
17609     }
17610
17611     @Override
17612     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17613         synchronized (this) {
17614             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17615             if (srec != null) {
17616                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17617             }
17618         }
17619         return false;
17620     }
17621
17622     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17623             Intent resultData) {
17624
17625         synchronized (this) {
17626             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17627             if (r != null) {
17628                 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17629             }
17630             return false;
17631         }
17632     }
17633
17634     public int getLaunchedFromUid(IBinder activityToken) {
17635         ActivityRecord srec;
17636         synchronized (this) {
17637             srec = ActivityRecord.forTokenLocked(activityToken);
17638         }
17639         if (srec == null) {
17640             return -1;
17641         }
17642         return srec.launchedFromUid;
17643     }
17644
17645     public String getLaunchedFromPackage(IBinder activityToken) {
17646         ActivityRecord srec;
17647         synchronized (this) {
17648             srec = ActivityRecord.forTokenLocked(activityToken);
17649         }
17650         if (srec == null) {
17651             return null;
17652         }
17653         return srec.launchedFromPackage;
17654     }
17655
17656     // =========================================================
17657     // LIFETIME MANAGEMENT
17658     // =========================================================
17659
17660     // Returns which broadcast queue the app is the current [or imminent] receiver
17661     // on, or 'null' if the app is not an active broadcast recipient.
17662     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17663         BroadcastRecord r = app.curReceiver;
17664         if (r != null) {
17665             return r.queue;
17666         }
17667
17668         // It's not the current receiver, but it might be starting up to become one
17669         synchronized (this) {
17670             for (BroadcastQueue queue : mBroadcastQueues) {
17671                 r = queue.mPendingBroadcast;
17672                 if (r != null && r.curApp == app) {
17673                     // found it; report which queue it's in
17674                     return queue;
17675                 }
17676             }
17677         }
17678
17679         return null;
17680     }
17681
17682     Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17683             ComponentName targetComponent, String targetProcess) {
17684         if (!mTrackingAssociations) {
17685             return null;
17686         }
17687         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17688                 = mAssociations.get(targetUid);
17689         if (components == null) {
17690             components = new ArrayMap<>();
17691             mAssociations.put(targetUid, components);
17692         }
17693         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17694         if (sourceUids == null) {
17695             sourceUids = new SparseArray<>();
17696             components.put(targetComponent, sourceUids);
17697         }
17698         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17699         if (sourceProcesses == null) {
17700             sourceProcesses = new ArrayMap<>();
17701             sourceUids.put(sourceUid, sourceProcesses);
17702         }
17703         Association ass = sourceProcesses.get(sourceProcess);
17704         if (ass == null) {
17705             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17706                     targetProcess);
17707             sourceProcesses.put(sourceProcess, ass);
17708         }
17709         ass.mCount++;
17710         ass.mNesting++;
17711         if (ass.mNesting == 1) {
17712             ass.mStartTime = SystemClock.uptimeMillis();
17713         }
17714         return ass;
17715     }
17716
17717     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17718             ComponentName targetComponent) {
17719         if (!mTrackingAssociations) {
17720             return;
17721         }
17722         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17723                 = mAssociations.get(targetUid);
17724         if (components == null) {
17725             return;
17726         }
17727         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17728         if (sourceUids == null) {
17729             return;
17730         }
17731         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17732         if (sourceProcesses == null) {
17733             return;
17734         }
17735         Association ass = sourceProcesses.get(sourceProcess);
17736         if (ass == null || ass.mNesting <= 0) {
17737             return;
17738         }
17739         ass.mNesting--;
17740         if (ass.mNesting == 0) {
17741             ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17742         }
17743     }
17744
17745     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17746             boolean doingAll, long now) {
17747         if (mAdjSeq == app.adjSeq) {
17748             // This adjustment has already been computed.
17749             return app.curRawAdj;
17750         }
17751
17752         if (app.thread == null) {
17753             app.adjSeq = mAdjSeq;
17754             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17755             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17756             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17757         }
17758
17759         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17760         app.adjSource = null;
17761         app.adjTarget = null;
17762         app.empty = false;
17763         app.cached = false;
17764
17765         final int activitiesSize = app.activities.size();
17766
17767         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17768             // The max adjustment doesn't allow this app to be anything
17769             // below foreground, so it is not worth doing work for it.
17770             app.adjType = "fixed";
17771             app.adjSeq = mAdjSeq;
17772             app.curRawAdj = app.maxAdj;
17773             app.foregroundActivities = false;
17774             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17775             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17776             // System processes can do UI, and when they do we want to have
17777             // them trim their memory after the user leaves the UI.  To
17778             // facilitate this, here we need to determine whether or not it
17779             // is currently showing UI.
17780             app.systemNoUi = true;
17781             if (app == TOP_APP) {
17782                 app.systemNoUi = false;
17783             } else if (activitiesSize > 0) {
17784                 for (int j = 0; j < activitiesSize; j++) {
17785                     final ActivityRecord r = app.activities.get(j);
17786                     if (r.visible) {
17787                         app.systemNoUi = false;
17788                     }
17789                 }
17790             }
17791             if (!app.systemNoUi) {
17792                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17793             }
17794             return (app.curAdj=app.maxAdj);
17795         }
17796
17797         app.systemNoUi = false;
17798
17799         final int PROCESS_STATE_TOP = mTopProcessState;
17800
17801         // Determine the importance of the process, starting with most
17802         // important to least, and assign an appropriate OOM adjustment.
17803         int adj;
17804         int schedGroup;
17805         int procState;
17806         boolean foregroundActivities = false;
17807         BroadcastQueue queue;
17808         if (app == TOP_APP) {
17809             // The last app on the list is the foreground app.
17810             adj = ProcessList.FOREGROUND_APP_ADJ;
17811             schedGroup = Process.THREAD_GROUP_DEFAULT;
17812             app.adjType = "top-activity";
17813             foregroundActivities = true;
17814             procState = PROCESS_STATE_TOP;
17815         } else if (app.instrumentationClass != null) {
17816             // Don't want to kill running instrumentation.
17817             adj = ProcessList.FOREGROUND_APP_ADJ;
17818             schedGroup = Process.THREAD_GROUP_DEFAULT;
17819             app.adjType = "instrumentation";
17820             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17821         } else if ((queue = isReceivingBroadcast(app)) != null) {
17822             // An app that is currently receiving a broadcast also
17823             // counts as being in the foreground for OOM killer purposes.
17824             // It's placed in a sched group based on the nature of the
17825             // broadcast as reflected by which queue it's active in.
17826             adj = ProcessList.FOREGROUND_APP_ADJ;
17827             schedGroup = (queue == mFgBroadcastQueue)
17828                     ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17829             app.adjType = "broadcast";
17830             procState = ActivityManager.PROCESS_STATE_RECEIVER;
17831         } else if (app.executingServices.size() > 0) {
17832             // An app that is currently executing a service callback also
17833             // counts as being in the foreground.
17834             adj = ProcessList.FOREGROUND_APP_ADJ;
17835             schedGroup = app.execServicesFg ?
17836                     Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17837             app.adjType = "exec-service";
17838             procState = ActivityManager.PROCESS_STATE_SERVICE;
17839             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17840         } else {
17841             // As far as we know the process is empty.  We may change our mind later.
17842             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17843             // At this point we don't actually know the adjustment.  Use the cached adj
17844             // value that the caller wants us to.
17845             adj = cachedAdj;
17846             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17847             app.cached = true;
17848             app.empty = true;
17849             app.adjType = "cch-empty";
17850         }
17851
17852         // Examine all activities if not already foreground.
17853         if (!foregroundActivities && activitiesSize > 0) {
17854             for (int j = 0; j < activitiesSize; j++) {
17855                 final ActivityRecord r = app.activities.get(j);
17856                 if (r.app != app) {
17857                     Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17858                             + app + "?!? Using " + r.app + " instead.");
17859                     continue;
17860                 }
17861                 if (r.visible) {
17862                     // App has a visible activity; only upgrade adjustment.
17863                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
17864                         adj = ProcessList.VISIBLE_APP_ADJ;
17865                         app.adjType = "visible";
17866                     }
17867                     if (procState > PROCESS_STATE_TOP) {
17868                         procState = PROCESS_STATE_TOP;
17869                     }
17870                     schedGroup = Process.THREAD_GROUP_DEFAULT;
17871                     app.cached = false;
17872                     app.empty = false;
17873                     foregroundActivities = true;
17874                     break;
17875                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17876                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17877                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17878                         app.adjType = "pausing";
17879                     }
17880                     if (procState > PROCESS_STATE_TOP) {
17881                         procState = PROCESS_STATE_TOP;
17882                     }
17883                     schedGroup = Process.THREAD_GROUP_DEFAULT;
17884                     app.cached = false;
17885                     app.empty = false;
17886                     foregroundActivities = true;
17887                 } else if (r.state == ActivityState.STOPPING) {
17888                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17889                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17890                         app.adjType = "stopping";
17891                     }
17892                     // For the process state, we will at this point consider the
17893                     // process to be cached.  It will be cached either as an activity
17894                     // or empty depending on whether the activity is finishing.  We do
17895                     // this so that we can treat the process as cached for purposes of
17896                     // memory trimming (determing current memory level, trim command to
17897                     // send to process) since there can be an arbitrary number of stopping
17898                     // processes and they should soon all go into the cached state.
17899                     if (!r.finishing) {
17900                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17901                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17902                         }
17903                     }
17904                     app.cached = false;
17905                     app.empty = false;
17906                     foregroundActivities = true;
17907                 } else {
17908                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17909                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17910                         app.adjType = "cch-act";
17911                     }
17912                 }
17913             }
17914         }
17915
17916         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17917             if (app.foregroundServices) {
17918                 // The user is aware of this app, so make it visible.
17919                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17920                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17921                 app.cached = false;
17922                 app.adjType = "fg-service";
17923                 schedGroup = Process.THREAD_GROUP_DEFAULT;
17924             } else if (app.forcingToForeground != null) {
17925                 // The user is aware of this app, so make it visible.
17926                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17927                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17928                 app.cached = false;
17929                 app.adjType = "force-fg";
17930                 app.adjSource = app.forcingToForeground;
17931                 schedGroup = Process.THREAD_GROUP_DEFAULT;
17932             }
17933         }
17934
17935         if (app == mHeavyWeightProcess) {
17936             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17937                 // We don't want to kill the current heavy-weight process.
17938                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17939                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17940                 app.cached = false;
17941                 app.adjType = "heavy";
17942             }
17943             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17944                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17945             }
17946         }
17947
17948         if (app == mHomeProcess) {
17949             if (adj > ProcessList.HOME_APP_ADJ) {
17950                 // This process is hosting what we currently consider to be the
17951                 // home app, so we don't want to let it go into the background.
17952                 adj = ProcessList.HOME_APP_ADJ;
17953                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17954                 app.cached = false;
17955                 app.adjType = "home";
17956             }
17957             if (procState > ActivityManager.PROCESS_STATE_HOME) {
17958                 procState = ActivityManager.PROCESS_STATE_HOME;
17959             }
17960         }
17961
17962         if (app == mPreviousProcess && app.activities.size() > 0) {
17963             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17964                 // This was the previous process that showed UI to the user.
17965                 // We want to try to keep it around more aggressively, to give
17966                 // a good experience around switching between two apps.
17967                 adj = ProcessList.PREVIOUS_APP_ADJ;
17968                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17969                 app.cached = false;
17970                 app.adjType = "previous";
17971             }
17972             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17973                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17974             }
17975         }
17976
17977         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17978                 + " reason=" + app.adjType);
17979
17980         // By default, we use the computed adjustment.  It may be changed if
17981         // there are applications dependent on our services or providers, but
17982         // this gives us a baseline and makes sure we don't get into an
17983         // infinite recursion.
17984         app.adjSeq = mAdjSeq;
17985         app.curRawAdj = adj;
17986         app.hasStartedServices = false;
17987
17988         if (mBackupTarget != null && app == mBackupTarget.app) {
17989             // If possible we want to avoid killing apps while they're being backed up
17990             if (adj > ProcessList.BACKUP_APP_ADJ) {
17991                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17992                 adj = ProcessList.BACKUP_APP_ADJ;
17993                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17994                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17995                 }
17996                 app.adjType = "backup";
17997                 app.cached = false;
17998             }
17999             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18000                 procState = ActivityManager.PROCESS_STATE_BACKUP;
18001             }
18002         }
18003
18004         boolean mayBeTop = false;
18005
18006         for (int is = app.services.size()-1;
18007                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18008                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18009                         || procState > ActivityManager.PROCESS_STATE_TOP);
18010                 is--) {
18011             ServiceRecord s = app.services.valueAt(is);
18012             if (s.startRequested) {
18013                 app.hasStartedServices = true;
18014                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18015                     procState = ActivityManager.PROCESS_STATE_SERVICE;
18016                 }
18017                 if (app.hasShownUi && app != mHomeProcess) {
18018                     // If this process has shown some UI, let it immediately
18019                     // go to the LRU list because it may be pretty heavy with
18020                     // UI stuff.  We'll tag it with a label just to help
18021                     // debug and understand what is going on.
18022                     if (adj > ProcessList.SERVICE_ADJ) {
18023                         app.adjType = "cch-started-ui-services";
18024                     }
18025                 } else {
18026                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18027                         // This service has seen some activity within
18028                         // recent memory, so we will keep its process ahead
18029                         // of the background processes.
18030                         if (adj > ProcessList.SERVICE_ADJ) {
18031                             adj = ProcessList.SERVICE_ADJ;
18032                             app.adjType = "started-services";
18033                             app.cached = false;
18034                         }
18035                     }
18036                     // If we have let the service slide into the background
18037                     // state, still have some text describing what it is doing
18038                     // even though the service no longer has an impact.
18039                     if (adj > ProcessList.SERVICE_ADJ) {
18040                         app.adjType = "cch-started-services";
18041                     }
18042                 }
18043             }
18044             for (int conni = s.connections.size()-1;
18045                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18046                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18047                             || procState > ActivityManager.PROCESS_STATE_TOP);
18048                     conni--) {
18049                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18050                 for (int i = 0;
18051                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18052                                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18053                                 || procState > ActivityManager.PROCESS_STATE_TOP);
18054                         i++) {
18055                     // XXX should compute this based on the max of
18056                     // all connected clients.
18057                     ConnectionRecord cr = clist.get(i);
18058                     if (cr.binding.client == app) {
18059                         // Binding to ourself is not interesting.
18060                         continue;
18061                     }
18062                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18063                         ProcessRecord client = cr.binding.client;
18064                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
18065                                 TOP_APP, doingAll, now);
18066                         int clientProcState = client.curProcState;
18067                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18068                             // If the other app is cached for any reason, for purposes here
18069                             // we are going to consider it empty.  The specific cached state
18070                             // doesn't propagate except under certain conditions.
18071                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18072                         }
18073                         String adjType = null;
18074                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18075                             // Not doing bind OOM management, so treat
18076                             // this guy more like a started service.
18077                             if (app.hasShownUi && app != mHomeProcess) {
18078                                 // If this process has shown some UI, let it immediately
18079                                 // go to the LRU list because it may be pretty heavy with
18080                                 // UI stuff.  We'll tag it with a label just to help
18081                                 // debug and understand what is going on.
18082                                 if (adj > clientAdj) {
18083                                     adjType = "cch-bound-ui-services";
18084                                 }
18085                                 app.cached = false;
18086                                 clientAdj = adj;
18087                                 clientProcState = procState;
18088                             } else {
18089                                 if (now >= (s.lastActivity
18090                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18091                                     // This service has not seen activity within
18092                                     // recent memory, so allow it to drop to the
18093                                     // LRU list if there is no other reason to keep
18094                                     // it around.  We'll also tag it with a label just
18095                                     // to help debug and undertand what is going on.
18096                                     if (adj > clientAdj) {
18097                                         adjType = "cch-bound-services";
18098                                     }
18099                                     clientAdj = adj;
18100                                 }
18101                             }
18102                         }
18103                         if (adj > clientAdj) {
18104                             // If this process has recently shown UI, and
18105                             // the process that is binding to it is less
18106                             // important than being visible, then we don't
18107                             // care about the binding as much as we care
18108                             // about letting this process get into the LRU
18109                             // list to be killed and restarted if needed for
18110                             // memory.
18111                             if (app.hasShownUi && app != mHomeProcess
18112                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18113                                 adjType = "cch-bound-ui-services";
18114                             } else {
18115                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18116                                         |Context.BIND_IMPORTANT)) != 0) {
18117                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18118                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18119                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18120                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18121                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18122                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18123                                 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
18124                                     adj = clientAdj;
18125                                 } else {
18126                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
18127                                         adj = ProcessList.VISIBLE_APP_ADJ;
18128                                     }
18129                                 }
18130                                 if (!client.cached) {
18131                                     app.cached = false;
18132                                 }
18133                                 adjType = "service";
18134                             }
18135                         }
18136                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18137                             if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18138                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
18139                             }
18140                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18141                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18142                                     // Special handling of clients who are in the top state.
18143                                     // We *may* want to consider this process to be in the
18144                                     // top state as well, but only if there is not another
18145                                     // reason for it to be running.  Being on the top is a
18146                                     // special state, meaning you are specifically running
18147                                     // for the current top app.  If the process is already
18148                                     // running in the background for some other reason, it
18149                                     // is more important to continue considering it to be
18150                                     // in the background state.
18151                                     mayBeTop = true;
18152                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18153                                 } else {
18154                                     // Special handling for above-top states (persistent
18155                                     // processes).  These should not bring the current process
18156                                     // into the top state, since they are not on top.  Instead
18157                                     // give them the best state after that.
18158                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18159                                         clientProcState =
18160                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18161                                     } else if (mWakefulness
18162                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18163                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18164                                                     != 0) {
18165                                         clientProcState =
18166                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18167                                     } else {
18168                                         clientProcState =
18169                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18170                                     }
18171                                 }
18172                             }
18173                         } else {
18174                             if (clientProcState <
18175                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18176                                 clientProcState =
18177                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18178                             }
18179                         }
18180                         if (procState > clientProcState) {
18181                             procState = clientProcState;
18182                         }
18183                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18184                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18185                             app.pendingUiClean = true;
18186                         }
18187                         if (adjType != null) {
18188                             app.adjType = adjType;
18189                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18190                                     .REASON_SERVICE_IN_USE;
18191                             app.adjSource = cr.binding.client;
18192                             app.adjSourceProcState = clientProcState;
18193                             app.adjTarget = s.name;
18194                         }
18195                     }
18196                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18197                         app.treatLikeActivity = true;
18198                     }
18199                     final ActivityRecord a = cr.activity;
18200                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18201                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18202                                 (a.visible || a.state == ActivityState.RESUMED
18203                                  || a.state == ActivityState.PAUSING)) {
18204                             adj = ProcessList.FOREGROUND_APP_ADJ;
18205                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18206                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
18207                             }
18208                             app.cached = false;
18209                             app.adjType = "service";
18210                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18211                                     .REASON_SERVICE_IN_USE;
18212                             app.adjSource = a;
18213                             app.adjSourceProcState = procState;
18214                             app.adjTarget = s.name;
18215                         }
18216                     }
18217                 }
18218             }
18219         }
18220
18221         for (int provi = app.pubProviders.size()-1;
18222                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18223                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18224                         || procState > ActivityManager.PROCESS_STATE_TOP);
18225                 provi--) {
18226             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18227             for (int i = cpr.connections.size()-1;
18228                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18229                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18230                             || procState > ActivityManager.PROCESS_STATE_TOP);
18231                     i--) {
18232                 ContentProviderConnection conn = cpr.connections.get(i);
18233                 ProcessRecord client = conn.client;
18234                 if (client == app) {
18235                     // Being our own client is not interesting.
18236                     continue;
18237                 }
18238                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18239                 int clientProcState = client.curProcState;
18240                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18241                     // If the other app is cached for any reason, for purposes here
18242                     // we are going to consider it empty.
18243                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18244                 }
18245                 if (adj > clientAdj) {
18246                     if (app.hasShownUi && app != mHomeProcess
18247                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18248                         app.adjType = "cch-ui-provider";
18249                     } else {
18250                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18251                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18252                         app.adjType = "provider";
18253                     }
18254                     app.cached &= client.cached;
18255                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18256                             .REASON_PROVIDER_IN_USE;
18257                     app.adjSource = client;
18258                     app.adjSourceProcState = clientProcState;
18259                     app.adjTarget = cpr.name;
18260                 }
18261                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18262                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18263                         // Special handling of clients who are in the top state.
18264                         // We *may* want to consider this process to be in the
18265                         // top state as well, but only if there is not another
18266                         // reason for it to be running.  Being on the top is a
18267                         // special state, meaning you are specifically running
18268                         // for the current top app.  If the process is already
18269                         // running in the background for some other reason, it
18270                         // is more important to continue considering it to be
18271                         // in the background state.
18272                         mayBeTop = true;
18273                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18274                     } else {
18275                         // Special handling for above-top states (persistent
18276                         // processes).  These should not bring the current process
18277                         // into the top state, since they are not on top.  Instead
18278                         // give them the best state after that.
18279                         clientProcState =
18280                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18281                     }
18282                 }
18283                 if (procState > clientProcState) {
18284                     procState = clientProcState;
18285                 }
18286                 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18287                     schedGroup = Process.THREAD_GROUP_DEFAULT;
18288                 }
18289             }
18290             // If the provider has external (non-framework) process
18291             // dependencies, ensure that its adjustment is at least
18292             // FOREGROUND_APP_ADJ.
18293             if (cpr.hasExternalProcessHandles()) {
18294                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18295                     adj = ProcessList.FOREGROUND_APP_ADJ;
18296                     schedGroup = Process.THREAD_GROUP_DEFAULT;
18297                     app.cached = false;
18298                     app.adjType = "provider";
18299                     app.adjTarget = cpr.name;
18300                 }
18301                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18302                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18303                 }
18304             }
18305         }
18306
18307         if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
18308             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18309                 adj = ProcessList.PREVIOUS_APP_ADJ;
18310                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18311                 app.cached = false;
18312                 app.adjType = "provider";
18313             }
18314             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18315                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18316             }
18317         }
18318
18319         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18320             // A client of one of our services or providers is in the top state.  We
18321             // *may* want to be in the top state, but not if we are already running in
18322             // the background for some other reason.  For the decision here, we are going
18323             // to pick out a few specific states that we want to remain in when a client
18324             // is top (states that tend to be longer-term) and otherwise allow it to go
18325             // to the top state.
18326             switch (procState) {
18327                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18328                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18329                 case ActivityManager.PROCESS_STATE_SERVICE:
18330                     // These all are longer-term states, so pull them up to the top
18331                     // of the background states, but not all the way to the top state.
18332                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18333                     break;
18334                 default:
18335                     // Otherwise, top is a better choice, so take it.
18336                     procState = ActivityManager.PROCESS_STATE_TOP;
18337                     break;
18338             }
18339         }
18340
18341         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18342             if (app.hasClientActivities) {
18343                 // This is a cached process, but with client activities.  Mark it so.
18344                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18345                 app.adjType = "cch-client-act";
18346             } else if (app.treatLikeActivity) {
18347                 // This is a cached process, but somebody wants us to treat it like it has
18348                 // an activity, okay!
18349                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18350                 app.adjType = "cch-as-act";
18351             }
18352         }
18353
18354         if (adj == ProcessList.SERVICE_ADJ) {
18355             if (doingAll) {
18356                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18357                 mNewNumServiceProcs++;
18358                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18359                 if (!app.serviceb) {
18360                     // This service isn't far enough down on the LRU list to
18361                     // normally be a B service, but if we are low on RAM and it
18362                     // is large we want to force it down since we would prefer to
18363                     // keep launcher over it.
18364                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18365                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18366                         app.serviceHighRam = true;
18367                         app.serviceb = true;
18368                         //Slog.i(TAG, "ADJ " + app + " high ram!");
18369                     } else {
18370                         mNewNumAServiceProcs++;
18371                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
18372                     }
18373                 } else {
18374                     app.serviceHighRam = false;
18375                 }
18376             }
18377             if (app.serviceb) {
18378                 adj = ProcessList.SERVICE_B_ADJ;
18379             }
18380         }
18381
18382         app.curRawAdj = adj;
18383
18384         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18385         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18386         if (adj > app.maxAdj) {
18387             adj = app.maxAdj;
18388             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18389                 schedGroup = Process.THREAD_GROUP_DEFAULT;
18390             }
18391         }
18392
18393         // Do final modification to adj.  Everything we do between here and applying
18394         // the final setAdj must be done in this function, because we will also use
18395         // it when computing the final cached adj later.  Note that we don't need to
18396         // worry about this for max adj above, since max adj will always be used to
18397         // keep it out of the cached vaues.
18398         app.curAdj = app.modifyRawOomAdj(adj);
18399         app.curSchedGroup = schedGroup;
18400         app.curProcState = procState;
18401         app.foregroundActivities = foregroundActivities;
18402
18403         return app.curRawAdj;
18404     }
18405
18406     /**
18407      * Record new PSS sample for a process.
18408      */
18409     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18410         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18411         proc.lastPssTime = now;
18412         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18413         if (DEBUG_PSS) Slog.d(TAG_PSS,
18414                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18415                 + " state=" + ProcessList.makeProcStateString(procState));
18416         if (proc.initialIdlePss == 0) {
18417             proc.initialIdlePss = pss;
18418         }
18419         proc.lastPss = pss;
18420         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18421             proc.lastCachedPss = pss;
18422         }
18423
18424         final SparseArray<Pair<Long, String>> watchUids
18425                 = mMemWatchProcesses.getMap().get(proc.processName);
18426         Long check = null;
18427         if (watchUids != null) {
18428             Pair<Long, String> val = watchUids.get(proc.uid);
18429             if (val == null) {
18430                 val = watchUids.get(0);
18431             }
18432             if (val != null) {
18433                 check = val.first;
18434             }
18435         }
18436         if (check != null) {
18437             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18438                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18439                 if (!isDebuggable) {
18440                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18441                         isDebuggable = true;
18442                     }
18443                 }
18444                 if (isDebuggable) {
18445                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18446                     final ProcessRecord myProc = proc;
18447                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
18448                     mMemWatchDumpProcName = proc.processName;
18449                     mMemWatchDumpFile = heapdumpFile.toString();
18450                     mMemWatchDumpPid = proc.pid;
18451                     mMemWatchDumpUid = proc.uid;
18452                     BackgroundThread.getHandler().post(new Runnable() {
18453                         @Override
18454                         public void run() {
18455                             revokeUriPermission(ActivityThread.currentActivityThread()
18456                                             .getApplicationThread(),
18457                                     DumpHeapActivity.JAVA_URI,
18458                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
18459                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18460                                     UserHandle.myUserId());
18461                             ParcelFileDescriptor fd = null;
18462                             try {
18463                                 heapdumpFile.delete();
18464                                 fd = ParcelFileDescriptor.open(heapdumpFile,
18465                                         ParcelFileDescriptor.MODE_CREATE |
18466                                                 ParcelFileDescriptor.MODE_TRUNCATE |
18467                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
18468                                                 ParcelFileDescriptor.MODE_APPEND);
18469                                 IApplicationThread thread = myProc.thread;
18470                                 if (thread != null) {
18471                                     try {
18472                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
18473                                                 "Requesting dump heap from "
18474                                                 + myProc + " to " + heapdumpFile);
18475                                         thread.dumpHeap(true, heapdumpFile.toString(), fd);
18476                                     } catch (RemoteException e) {
18477                                     }
18478                                 }
18479                             } catch (FileNotFoundException e) {
18480                                 e.printStackTrace();
18481                             } finally {
18482                                 if (fd != null) {
18483                                     try {
18484                                         fd.close();
18485                                     } catch (IOException e) {
18486                                     }
18487                                 }
18488                             }
18489                         }
18490                     });
18491                 } else {
18492                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18493                             + ", but debugging not enabled");
18494                 }
18495             }
18496         }
18497     }
18498
18499     /**
18500      * Schedule PSS collection of a process.
18501      */
18502     void requestPssLocked(ProcessRecord proc, int procState) {
18503         if (mPendingPssProcesses.contains(proc)) {
18504             return;
18505         }
18506         if (mPendingPssProcesses.size() == 0) {
18507             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18508         }
18509         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18510         proc.pssProcState = procState;
18511         mPendingPssProcesses.add(proc);
18512     }
18513
18514     /**
18515      * Schedule PSS collection of all processes.
18516      */
18517     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18518         if (!always) {
18519             if (now < (mLastFullPssTime +
18520                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18521                 return;
18522             }
18523         }
18524         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18525         mLastFullPssTime = now;
18526         mFullPssPending = true;
18527         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18528         mPendingPssProcesses.clear();
18529         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18530             ProcessRecord app = mLruProcesses.get(i);
18531             if (app.thread == null
18532                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18533                 continue;
18534             }
18535             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18536                 app.pssProcState = app.setProcState;
18537                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18538                         mTestPssMode, isSleeping(), now);
18539                 mPendingPssProcesses.add(app);
18540             }
18541         }
18542         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18543     }
18544
18545     public void setTestPssMode(boolean enabled) {
18546         synchronized (this) {
18547             mTestPssMode = enabled;
18548             if (enabled) {
18549                 // Whenever we enable the mode, we want to take a snapshot all of current
18550                 // process mem use.
18551                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18552             }
18553         }
18554     }
18555
18556     /**
18557      * Ask a given process to GC right now.
18558      */
18559     final void performAppGcLocked(ProcessRecord app) {
18560         try {
18561             app.lastRequestedGc = SystemClock.uptimeMillis();
18562             if (app.thread != null) {
18563                 if (app.reportLowMemory) {
18564                     app.reportLowMemory = false;
18565                     app.thread.scheduleLowMemory();
18566                 } else {
18567                     app.thread.processInBackground();
18568                 }
18569             }
18570         } catch (Exception e) {
18571             // whatever.
18572         }
18573     }
18574
18575     /**
18576      * Returns true if things are idle enough to perform GCs.
18577      */
18578     private final boolean canGcNowLocked() {
18579         boolean processingBroadcasts = false;
18580         for (BroadcastQueue q : mBroadcastQueues) {
18581             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18582                 processingBroadcasts = true;
18583             }
18584         }
18585         return !processingBroadcasts
18586                 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18587     }
18588
18589     /**
18590      * Perform GCs on all processes that are waiting for it, but only
18591      * if things are idle.
18592      */
18593     final void performAppGcsLocked() {
18594         final int N = mProcessesToGc.size();
18595         if (N <= 0) {
18596             return;
18597         }
18598         if (canGcNowLocked()) {
18599             while (mProcessesToGc.size() > 0) {
18600                 ProcessRecord proc = mProcessesToGc.remove(0);
18601                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18602                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18603                             <= SystemClock.uptimeMillis()) {
18604                         // To avoid spamming the system, we will GC processes one
18605                         // at a time, waiting a few seconds between each.
18606                         performAppGcLocked(proc);
18607                         scheduleAppGcsLocked();
18608                         return;
18609                     } else {
18610                         // It hasn't been long enough since we last GCed this
18611                         // process...  put it in the list to wait for its time.
18612                         addProcessToGcListLocked(proc);
18613                         break;
18614                     }
18615                 }
18616             }
18617
18618             scheduleAppGcsLocked();
18619         }
18620     }
18621
18622     /**
18623      * If all looks good, perform GCs on all processes waiting for them.
18624      */
18625     final void performAppGcsIfAppropriateLocked() {
18626         if (canGcNowLocked()) {
18627             performAppGcsLocked();
18628             return;
18629         }
18630         // Still not idle, wait some more.
18631         scheduleAppGcsLocked();
18632     }
18633
18634     /**
18635      * Schedule the execution of all pending app GCs.
18636      */
18637     final void scheduleAppGcsLocked() {
18638         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18639
18640         if (mProcessesToGc.size() > 0) {
18641             // Schedule a GC for the time to the next process.
18642             ProcessRecord proc = mProcessesToGc.get(0);
18643             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18644
18645             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18646             long now = SystemClock.uptimeMillis();
18647             if (when < (now+GC_TIMEOUT)) {
18648                 when = now + GC_TIMEOUT;
18649             }
18650             mHandler.sendMessageAtTime(msg, when);
18651         }
18652     }
18653
18654     /**
18655      * Add a process to the array of processes waiting to be GCed.  Keeps the
18656      * list in sorted order by the last GC time.  The process can't already be
18657      * on the list.
18658      */
18659     final void addProcessToGcListLocked(ProcessRecord proc) {
18660         boolean added = false;
18661         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18662             if (mProcessesToGc.get(i).lastRequestedGc <
18663                     proc.lastRequestedGc) {
18664                 added = true;
18665                 mProcessesToGc.add(i+1, proc);
18666                 break;
18667             }
18668         }
18669         if (!added) {
18670             mProcessesToGc.add(0, proc);
18671         }
18672     }
18673
18674     /**
18675      * Set up to ask a process to GC itself.  This will either do it
18676      * immediately, or put it on the list of processes to gc the next
18677      * time things are idle.
18678      */
18679     final void scheduleAppGcLocked(ProcessRecord app) {
18680         long now = SystemClock.uptimeMillis();
18681         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18682             return;
18683         }
18684         if (!mProcessesToGc.contains(app)) {
18685             addProcessToGcListLocked(app);
18686             scheduleAppGcsLocked();
18687         }
18688     }
18689
18690     final void checkExcessivePowerUsageLocked(boolean doKills) {
18691         updateCpuStatsNow();
18692
18693         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18694         boolean doWakeKills = doKills;
18695         boolean doCpuKills = doKills;
18696         if (mLastPowerCheckRealtime == 0) {
18697             doWakeKills = false;
18698         }
18699         if (mLastPowerCheckUptime == 0) {
18700             doCpuKills = false;
18701         }
18702         if (stats.isScreenOn()) {
18703             doWakeKills = false;
18704         }
18705         final long curRealtime = SystemClock.elapsedRealtime();
18706         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18707         final long curUptime = SystemClock.uptimeMillis();
18708         final long uptimeSince = curUptime - mLastPowerCheckUptime;
18709         mLastPowerCheckRealtime = curRealtime;
18710         mLastPowerCheckUptime = curUptime;
18711         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18712             doWakeKills = false;
18713         }
18714         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18715             doCpuKills = false;
18716         }
18717         int i = mLruProcesses.size();
18718         while (i > 0) {
18719             i--;
18720             ProcessRecord app = mLruProcesses.get(i);
18721             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18722                 long wtime;
18723                 synchronized (stats) {
18724                     wtime = stats.getProcessWakeTime(app.info.uid,
18725                             app.pid, curRealtime);
18726                 }
18727                 long wtimeUsed = wtime - app.lastWakeTime;
18728                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18729                 if (DEBUG_POWER) {
18730                     StringBuilder sb = new StringBuilder(128);
18731                     sb.append("Wake for ");
18732                     app.toShortString(sb);
18733                     sb.append(": over ");
18734                     TimeUtils.formatDuration(realtimeSince, sb);
18735                     sb.append(" used ");
18736                     TimeUtils.formatDuration(wtimeUsed, sb);
18737                     sb.append(" (");
18738                     sb.append((wtimeUsed*100)/realtimeSince);
18739                     sb.append("%)");
18740                     Slog.i(TAG_POWER, sb.toString());
18741                     sb.setLength(0);
18742                     sb.append("CPU for ");
18743                     app.toShortString(sb);
18744                     sb.append(": over ");
18745                     TimeUtils.formatDuration(uptimeSince, sb);
18746                     sb.append(" used ");
18747                     TimeUtils.formatDuration(cputimeUsed, sb);
18748                     sb.append(" (");
18749                     sb.append((cputimeUsed*100)/uptimeSince);
18750                     sb.append("%)");
18751                     Slog.i(TAG_POWER, sb.toString());
18752                 }
18753                 // If a process has held a wake lock for more
18754                 // than 50% of the time during this period,
18755                 // that sounds bad.  Kill!
18756                 if (doWakeKills && realtimeSince > 0
18757                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
18758                     synchronized (stats) {
18759                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18760                                 realtimeSince, wtimeUsed);
18761                     }
18762                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18763                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18764                 } else if (doCpuKills && uptimeSince > 0
18765                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
18766                     synchronized (stats) {
18767                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18768                                 uptimeSince, cputimeUsed);
18769                     }
18770                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18771                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18772                 } else {
18773                     app.lastWakeTime = wtime;
18774                     app.lastCpuTime = app.curCpuTime;
18775                 }
18776             }
18777         }
18778     }
18779
18780     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
18781             long nowElapsed) {
18782         boolean success = true;
18783
18784         if (app.curRawAdj != app.setRawAdj) {
18785             app.setRawAdj = app.curRawAdj;
18786         }
18787
18788         int changes = 0;
18789
18790         if (app.curAdj != app.setAdj) {
18791             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18792             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18793                     "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18794                     + app.adjType);
18795             app.setAdj = app.curAdj;
18796         }
18797
18798         if (app.setSchedGroup != app.curSchedGroup) {
18799             app.setSchedGroup = app.curSchedGroup;
18800             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18801                     "Setting process group of " + app.processName
18802                     + " to " + app.curSchedGroup);
18803             if (app.waitingToKill != null && app.curReceiver == null
18804                     && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18805                 app.kill(app.waitingToKill, true);
18806                 success = false;
18807             } else {
18808                 if (true) {
18809                     long oldId = Binder.clearCallingIdentity();
18810                     try {
18811                         Process.setProcessGroup(app.pid, app.curSchedGroup);
18812                     } catch (Exception e) {
18813                         Slog.w(TAG, "Failed setting process group of " + app.pid
18814                                 + " to " + app.curSchedGroup);
18815                         e.printStackTrace();
18816                     } finally {
18817                         Binder.restoreCallingIdentity(oldId);
18818                     }
18819                 } else {
18820                     if (app.thread != null) {
18821                         try {
18822                             app.thread.setSchedulingGroup(app.curSchedGroup);
18823                         } catch (RemoteException e) {
18824                         }
18825                     }
18826                 }
18827                 Process.setSwappiness(app.pid,
18828                         app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18829             }
18830         }
18831         if (app.repForegroundActivities != app.foregroundActivities) {
18832             app.repForegroundActivities = app.foregroundActivities;
18833             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18834         }
18835         if (app.repProcState != app.curProcState) {
18836             app.repProcState = app.curProcState;
18837             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18838             if (app.thread != null) {
18839                 try {
18840                     if (false) {
18841                         //RuntimeException h = new RuntimeException("here");
18842                         Slog.i(TAG, "Sending new process state " + app.repProcState
18843                                 + " to " + app /*, h*/);
18844                     }
18845                     app.thread.setProcessState(app.repProcState);
18846                 } catch (RemoteException e) {
18847                 }
18848             }
18849         }
18850         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18851                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18852             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18853                 // Experimental code to more aggressively collect pss while
18854                 // running test...  the problem is that this tends to collect
18855                 // the data right when a process is transitioning between process
18856                 // states, which well tend to give noisy data.
18857                 long start = SystemClock.uptimeMillis();
18858                 long pss = Debug.getPss(app.pid, mTmpLong, null);
18859                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18860                 mPendingPssProcesses.remove(app);
18861                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18862                         + " to " + app.curProcState + ": "
18863                         + (SystemClock.uptimeMillis()-start) + "ms");
18864             }
18865             app.lastStateTime = now;
18866             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18867                     mTestPssMode, isSleeping(), now);
18868             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18869                     + ProcessList.makeProcStateString(app.setProcState) + " to "
18870                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18871                     + (app.nextPssTime-now) + ": " + app);
18872         } else {
18873             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18874                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18875                     mTestPssMode)))) {
18876                 requestPssLocked(app, app.setProcState);
18877                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18878                         mTestPssMode, isSleeping(), now);
18879             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18880                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18881         }
18882         if (app.setProcState != app.curProcState) {
18883             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18884                     "Proc state change of " + app.processName
18885                             + " to " + app.curProcState);
18886             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18887             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18888             if (setImportant && !curImportant) {
18889                 // This app is no longer something we consider important enough to allow to
18890                 // use arbitrary amounts of battery power.  Note
18891                 // its current wake lock time to later know to kill it if
18892                 // it is not behaving well.
18893                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18894                 synchronized (stats) {
18895                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18896                             app.pid, nowElapsed);
18897                 }
18898                 app.lastCpuTime = app.curCpuTime;
18899
18900             }
18901             // Inform UsageStats of important process state change
18902             // Must be called before updating setProcState
18903             maybeUpdateUsageStatsLocked(app, nowElapsed);
18904
18905             app.setProcState = app.curProcState;
18906             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18907                 app.notCachedSinceIdle = false;
18908             }
18909             if (!doingAll) {
18910                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18911             } else {
18912                 app.procStateChanged = true;
18913             }
18914         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
18915                 > USAGE_STATS_INTERACTION_INTERVAL) {
18916             // For apps that sit around for a long time in the interactive state, we need
18917             // to report this at least once a day so they don't go idle.
18918             maybeUpdateUsageStatsLocked(app, nowElapsed);
18919         }
18920
18921         if (changes != 0) {
18922             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18923                     "Changes in " + app + ": " + changes);
18924             int i = mPendingProcessChanges.size()-1;
18925             ProcessChangeItem item = null;
18926             while (i >= 0) {
18927                 item = mPendingProcessChanges.get(i);
18928                 if (item.pid == app.pid) {
18929                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18930                             "Re-using existing item: " + item);
18931                     break;
18932                 }
18933                 i--;
18934             }
18935             if (i < 0) {
18936                 // No existing item in pending changes; need a new one.
18937                 final int NA = mAvailProcessChanges.size();
18938                 if (NA > 0) {
18939                     item = mAvailProcessChanges.remove(NA-1);
18940                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18941                             "Retrieving available item: " + item);
18942                 } else {
18943                     item = new ProcessChangeItem();
18944                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18945                             "Allocating new item: " + item);
18946                 }
18947                 item.changes = 0;
18948                 item.pid = app.pid;
18949                 item.uid = app.info.uid;
18950                 if (mPendingProcessChanges.size() == 0) {
18951                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18952                             "*** Enqueueing dispatch processes changed!");
18953                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18954                 }
18955                 mPendingProcessChanges.add(item);
18956             }
18957             item.changes |= changes;
18958             item.processState = app.repProcState;
18959             item.foregroundActivities = app.repForegroundActivities;
18960             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18961                     "Item " + Integer.toHexString(System.identityHashCode(item))
18962                     + " " + app.toShortString() + ": changes=" + item.changes
18963                     + " procState=" + item.processState
18964                     + " foreground=" + item.foregroundActivities
18965                     + " type=" + app.adjType + " source=" + app.adjSource
18966                     + " target=" + app.adjTarget);
18967         }
18968
18969         return success;
18970     }
18971
18972     private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18973         if (uidRec.pendingChange == null) {
18974             if (mPendingUidChanges.size() == 0) {
18975                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18976                         "*** Enqueueing dispatch uid changed!");
18977                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
18978             }
18979             final int NA = mAvailUidChanges.size();
18980             if (NA > 0) {
18981                 uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18982                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18983                         "Retrieving available item: " + uidRec.pendingChange);
18984             } else {
18985                 uidRec.pendingChange = new UidRecord.ChangeItem();
18986                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18987                         "Allocating new item: " + uidRec.pendingChange);
18988             }
18989             uidRec.pendingChange.uidRecord = uidRec;
18990             uidRec.pendingChange.uid = uidRec.uid;
18991             mPendingUidChanges.add(uidRec.pendingChange);
18992         }
18993         uidRec.pendingChange.gone = gone;
18994         uidRec.pendingChange.processState = uidRec.setProcState;
18995     }
18996
18997     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
18998             String authority) {
18999         if (app == null) return;
19000         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19001             UserState userState = mStartedUsers.get(app.userId);
19002             if (userState == null) return;
19003             final long now = SystemClock.elapsedRealtime();
19004             Long lastReported = userState.mProviderLastReportedFg.get(authority);
19005             if (lastReported == null || lastReported < now - 60 * 1000L) {
19006                 mUsageStatsService.reportContentProviderUsage(
19007                         authority, providerPkgName, app.userId);
19008                 userState.mProviderLastReportedFg.put(authority, now);
19009             }
19010         }
19011     }
19012
19013     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19014         if (DEBUG_USAGE_STATS) {
19015             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19016                     + "] state changes: old = " + app.setProcState + ", new = "
19017                     + app.curProcState);
19018         }
19019         if (mUsageStatsService == null) {
19020             return;
19021         }
19022         boolean isInteraction;
19023         // To avoid some abuse patterns, we are going to be careful about what we consider
19024         // to be an app interaction.  Being the top activity doesn't count while the display
19025         // is sleeping, nor do short foreground services.
19026         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19027             isInteraction = true;
19028             app.fgInteractionTime = 0;
19029         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19030             if (app.fgInteractionTime == 0) {
19031                 app.fgInteractionTime = nowElapsed;
19032                 isInteraction = false;
19033             } else {
19034                 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19035             }
19036         } else {
19037             isInteraction = app.curProcState
19038                     <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19039             app.fgInteractionTime = 0;
19040         }
19041         if (isInteraction && (!app.reportedInteraction
19042                 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19043             app.interactionEventTime = nowElapsed;
19044             String[] packages = app.getPackageList();
19045             if (packages != null) {
19046                 for (int i = 0; i < packages.length; i++) {
19047                     mUsageStatsService.reportEvent(packages[i], app.userId,
19048                             UsageEvents.Event.SYSTEM_INTERACTION);
19049                 }
19050             }
19051         }
19052         app.reportedInteraction = isInteraction;
19053         if (!isInteraction) {
19054             app.interactionEventTime = 0;
19055         }
19056     }
19057
19058     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19059         if (proc.thread != null) {
19060             if (proc.baseProcessTracker != null) {
19061                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19062             }
19063             if (proc.repProcState >= 0) {
19064                 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
19065                         proc.repProcState);
19066             }
19067         }
19068     }
19069
19070     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19071             ProcessRecord TOP_APP, boolean doingAll, long now) {
19072         if (app.thread == null) {
19073             return false;
19074         }
19075
19076         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19077
19078         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19079     }
19080
19081     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19082             boolean oomAdj) {
19083         if (isForeground != proc.foregroundServices) {
19084             proc.foregroundServices = isForeground;
19085             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19086                     proc.info.uid);
19087             if (isForeground) {
19088                 if (curProcs == null) {
19089                     curProcs = new ArrayList<ProcessRecord>();
19090                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19091                 }
19092                 if (!curProcs.contains(proc)) {
19093                     curProcs.add(proc);
19094                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19095                             proc.info.packageName, proc.info.uid);
19096                 }
19097             } else {
19098                 if (curProcs != null) {
19099                     if (curProcs.remove(proc)) {
19100                         mBatteryStatsService.noteEvent(
19101                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19102                                 proc.info.packageName, proc.info.uid);
19103                         if (curProcs.size() <= 0) {
19104                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19105                         }
19106                     }
19107                 }
19108             }
19109             if (oomAdj) {
19110                 updateOomAdjLocked();
19111             }
19112         }
19113     }
19114
19115     private final ActivityRecord resumedAppLocked() {
19116         ActivityRecord act = mStackSupervisor.resumedAppLocked();
19117         String pkg;
19118         int uid;
19119         if (act != null) {
19120             pkg = act.packageName;
19121             uid = act.info.applicationInfo.uid;
19122         } else {
19123             pkg = null;
19124             uid = -1;
19125         }
19126         // Has the UID or resumed package name changed?
19127         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19128                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19129             if (mCurResumedPackage != null) {
19130                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19131                         mCurResumedPackage, mCurResumedUid);
19132             }
19133             mCurResumedPackage = pkg;
19134             mCurResumedUid = uid;
19135             if (mCurResumedPackage != null) {
19136                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19137                         mCurResumedPackage, mCurResumedUid);
19138             }
19139         }
19140         return act;
19141     }
19142
19143     final boolean updateOomAdjLocked(ProcessRecord app) {
19144         final ActivityRecord TOP_ACT = resumedAppLocked();
19145         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19146         final boolean wasCached = app.cached;
19147
19148         mAdjSeq++;
19149
19150         // This is the desired cached adjusment we want to tell it to use.
19151         // If our app is currently cached, we know it, and that is it.  Otherwise,
19152         // we don't know it yet, and it needs to now be cached we will then
19153         // need to do a complete oom adj.
19154         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19155                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19156         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19157                 SystemClock.uptimeMillis());
19158         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19159             // Changed to/from cached state, so apps after it in the LRU
19160             // list may also be changed.
19161             updateOomAdjLocked();
19162         }
19163         return success;
19164     }
19165
19166     final void updateOomAdjLocked() {
19167         final ActivityRecord TOP_ACT = resumedAppLocked();
19168         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19169         final long now = SystemClock.uptimeMillis();
19170         final long nowElapsed = SystemClock.elapsedRealtime();
19171         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19172         final int N = mLruProcesses.size();
19173
19174         if (false) {
19175             RuntimeException e = new RuntimeException();
19176             e.fillInStackTrace();
19177             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19178         }
19179
19180         // Reset state in all uid records.
19181         for (int i=mActiveUids.size()-1; i>=0; i--) {
19182             final UidRecord uidRec = mActiveUids.valueAt(i);
19183             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19184                     "Starting update of " + uidRec);
19185             uidRec.reset();
19186         }
19187
19188         mAdjSeq++;
19189         mNewNumServiceProcs = 0;
19190         mNewNumAServiceProcs = 0;
19191
19192         final int emptyProcessLimit;
19193         final int cachedProcessLimit;
19194         if (mProcessLimit <= 0) {
19195             emptyProcessLimit = cachedProcessLimit = 0;
19196         } else if (mProcessLimit == 1) {
19197             emptyProcessLimit = 1;
19198             cachedProcessLimit = 0;
19199         } else {
19200             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19201             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19202         }
19203
19204         // Let's determine how many processes we have running vs.
19205         // how many slots we have for background processes; we may want
19206         // to put multiple processes in a slot of there are enough of
19207         // them.
19208         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19209                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19210         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19211         if (numEmptyProcs > cachedProcessLimit) {
19212             // If there are more empty processes than our limit on cached
19213             // processes, then use the cached process limit for the factor.
19214             // This ensures that the really old empty processes get pushed
19215             // down to the bottom, so if we are running low on memory we will
19216             // have a better chance at keeping around more cached processes
19217             // instead of a gazillion empty processes.
19218             numEmptyProcs = cachedProcessLimit;
19219         }
19220         int emptyFactor = numEmptyProcs/numSlots;
19221         if (emptyFactor < 1) emptyFactor = 1;
19222         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19223         if (cachedFactor < 1) cachedFactor = 1;
19224         int stepCached = 0;
19225         int stepEmpty = 0;
19226         int numCached = 0;
19227         int numEmpty = 0;
19228         int numTrimming = 0;
19229
19230         mNumNonCachedProcs = 0;
19231         mNumCachedHiddenProcs = 0;
19232
19233         // First update the OOM adjustment for each of the
19234         // application processes based on their current state.
19235         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19236         int nextCachedAdj = curCachedAdj+1;
19237         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19238         int nextEmptyAdj = curEmptyAdj+2;
19239         for (int i=N-1; i>=0; i--) {
19240             ProcessRecord app = mLruProcesses.get(i);
19241             if (!app.killedByAm && app.thread != null) {
19242                 app.procStateChanged = false;
19243                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19244
19245                 // If we haven't yet assigned the final cached adj
19246                 // to the process, do that now.
19247                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19248                     switch (app.curProcState) {
19249                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19250                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19251                             // This process is a cached process holding activities...
19252                             // assign it the next cached value for that type, and then
19253                             // step that cached level.
19254                             app.curRawAdj = curCachedAdj;
19255                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19256                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19257                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19258                                     + ")");
19259                             if (curCachedAdj != nextCachedAdj) {
19260                                 stepCached++;
19261                                 if (stepCached >= cachedFactor) {
19262                                     stepCached = 0;
19263                                     curCachedAdj = nextCachedAdj;
19264                                     nextCachedAdj += 2;
19265                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19266                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19267                                     }
19268                                 }
19269                             }
19270                             break;
19271                         default:
19272                             // For everything else, assign next empty cached process
19273                             // level and bump that up.  Note that this means that
19274                             // long-running services that have dropped down to the
19275                             // cached level will be treated as empty (since their process
19276                             // state is still as a service), which is what we want.
19277                             app.curRawAdj = curEmptyAdj;
19278                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19279                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19280                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19281                                     + ")");
19282                             if (curEmptyAdj != nextEmptyAdj) {
19283                                 stepEmpty++;
19284                                 if (stepEmpty >= emptyFactor) {
19285                                     stepEmpty = 0;
19286                                     curEmptyAdj = nextEmptyAdj;
19287                                     nextEmptyAdj += 2;
19288                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19289                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19290                                     }
19291                                 }
19292                             }
19293                             break;
19294                     }
19295                 }
19296
19297                 applyOomAdjLocked(app, true, now, nowElapsed);
19298
19299                 // Count the number of process types.
19300                 switch (app.curProcState) {
19301                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19302                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19303                         mNumCachedHiddenProcs++;
19304                         numCached++;
19305                         if (numCached > cachedProcessLimit) {
19306                             app.kill("cached #" + numCached, true);
19307                         }
19308                         break;
19309                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19310                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19311                                 && app.lastActivityTime < oldTime) {
19312                             app.kill("empty for "
19313                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19314                                     / 1000) + "s", true);
19315                         } else {
19316                             numEmpty++;
19317                             if (numEmpty > emptyProcessLimit) {
19318                                 app.kill("empty #" + numEmpty, true);
19319                             }
19320                         }
19321                         break;
19322                     default:
19323                         mNumNonCachedProcs++;
19324                         break;
19325                 }
19326
19327                 if (app.isolated && app.services.size() <= 0) {
19328                     // If this is an isolated process, and there are no
19329                     // services running in it, then the process is no longer
19330                     // needed.  We agressively kill these because we can by
19331                     // definition not re-use the same process again, and it is
19332                     // good to avoid having whatever code was running in them
19333                     // left sitting around after no longer needed.
19334                     app.kill("isolated not needed", true);
19335                 } else {
19336                     // Keeping this process, update its uid.
19337                     final UidRecord uidRec = app.uidRecord;
19338                     if (uidRec != null && uidRec.curProcState > app.curProcState) {
19339                         uidRec.curProcState = app.curProcState;
19340                     }
19341                 }
19342
19343                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19344                         && !app.killedByAm) {
19345                     numTrimming++;
19346                 }
19347             }
19348         }
19349
19350         mNumServiceProcs = mNewNumServiceProcs;
19351
19352         // Now determine the memory trimming level of background processes.
19353         // Unfortunately we need to start at the back of the list to do this
19354         // properly.  We only do this if the number of background apps we
19355         // are managing to keep around is less than half the maximum we desire;
19356         // if we are keeping a good number around, we'll let them use whatever
19357         // memory they want.
19358         final int numCachedAndEmpty = numCached + numEmpty;
19359         int memFactor;
19360         if (numCached <= ProcessList.TRIM_CACHED_APPS
19361                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19362             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19363                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19364             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19365                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19366             } else {
19367                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19368             }
19369         } else {
19370             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19371         }
19372         // We always allow the memory level to go up (better).  We only allow it to go
19373         // down if we are in a state where that is allowed, *and* the total number of processes
19374         // has gone down since last time.
19375         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19376                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19377                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19378         if (memFactor > mLastMemoryLevel) {
19379             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19380                 memFactor = mLastMemoryLevel;
19381                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19382             }
19383         }
19384         mLastMemoryLevel = memFactor;
19385         mLastNumProcesses = mLruProcesses.size();
19386         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19387         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19388         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19389             if (mLowRamStartTime == 0) {
19390                 mLowRamStartTime = now;
19391             }
19392             int step = 0;
19393             int fgTrimLevel;
19394             switch (memFactor) {
19395                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19396                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19397                     break;
19398                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
19399                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19400                     break;
19401                 default:
19402                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19403                     break;
19404             }
19405             int factor = numTrimming/3;
19406             int minFactor = 2;
19407             if (mHomeProcess != null) minFactor++;
19408             if (mPreviousProcess != null) minFactor++;
19409             if (factor < minFactor) factor = minFactor;
19410             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19411             for (int i=N-1; i>=0; i--) {
19412                 ProcessRecord app = mLruProcesses.get(i);
19413                 if (allChanged || app.procStateChanged) {
19414                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
19415                     app.procStateChanged = false;
19416                 }
19417                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19418                         && !app.killedByAm) {
19419                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
19420                         try {
19421                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19422                                     "Trimming memory of " + app.processName + " to " + curLevel);
19423                             app.thread.scheduleTrimMemory(curLevel);
19424                         } catch (RemoteException e) {
19425                         }
19426                         if (false) {
19427                             // For now we won't do this; our memory trimming seems
19428                             // to be good enough at this point that destroying
19429                             // activities causes more harm than good.
19430                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19431                                     && app != mHomeProcess && app != mPreviousProcess) {
19432                                 // Need to do this on its own message because the stack may not
19433                                 // be in a consistent state at this point.
19434                                 // For these apps we will also finish their activities
19435                                 // to help them free memory.
19436                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19437                             }
19438                         }
19439                     }
19440                     app.trimMemoryLevel = curLevel;
19441                     step++;
19442                     if (step >= factor) {
19443                         step = 0;
19444                         switch (curLevel) {
19445                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19446                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19447                                 break;
19448                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19449                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19450                                 break;
19451                         }
19452                     }
19453                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19454                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19455                             && app.thread != null) {
19456                         try {
19457                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19458                                     "Trimming memory of heavy-weight " + app.processName
19459                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19460                             app.thread.scheduleTrimMemory(
19461                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19462                         } catch (RemoteException e) {
19463                         }
19464                     }
19465                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19466                 } else {
19467                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19468                             || app.systemNoUi) && app.pendingUiClean) {
19469                         // If this application is now in the background and it
19470                         // had done UI, then give it the special trim level to
19471                         // have it free UI resources.
19472                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19473                         if (app.trimMemoryLevel < level && app.thread != null) {
19474                             try {
19475                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19476                                         "Trimming memory of bg-ui " + app.processName
19477                                         + " to " + level);
19478                                 app.thread.scheduleTrimMemory(level);
19479                             } catch (RemoteException e) {
19480                             }
19481                         }
19482                         app.pendingUiClean = false;
19483                     }
19484                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19485                         try {
19486                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19487                                     "Trimming memory of fg " + app.processName
19488                                     + " to " + fgTrimLevel);
19489                             app.thread.scheduleTrimMemory(fgTrimLevel);
19490                         } catch (RemoteException e) {
19491                         }
19492                     }
19493                     app.trimMemoryLevel = fgTrimLevel;
19494                 }
19495             }
19496         } else {
19497             if (mLowRamStartTime != 0) {
19498                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19499                 mLowRamStartTime = 0;
19500             }
19501             for (int i=N-1; i>=0; i--) {
19502                 ProcessRecord app = mLruProcesses.get(i);
19503                 if (allChanged || app.procStateChanged) {
19504                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
19505                     app.procStateChanged = false;
19506                 }
19507                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19508                         || app.systemNoUi) && app.pendingUiClean) {
19509                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19510                             && app.thread != null) {
19511                         try {
19512                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19513                                     "Trimming memory of ui hidden " + app.processName
19514                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19515                             app.thread.scheduleTrimMemory(
19516                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19517                         } catch (RemoteException e) {
19518                         }
19519                     }
19520                     app.pendingUiClean = false;
19521                 }
19522                 app.trimMemoryLevel = 0;
19523             }
19524         }
19525
19526         if (mAlwaysFinishActivities) {
19527             // Need to do this on its own message because the stack may not
19528             // be in a consistent state at this point.
19529             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19530         }
19531
19532         if (allChanged) {
19533             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19534         }
19535
19536         // Update from any uid changes.
19537         for (int i=mActiveUids.size()-1; i>=0; i--) {
19538             final UidRecord uidRec = mActiveUids.valueAt(i);
19539             if (uidRec.setProcState != uidRec.curProcState) {
19540                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19541                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19542                         + " to " + uidRec.curProcState);
19543                 uidRec.setProcState = uidRec.curProcState;
19544                 enqueueUidChangeLocked(uidRec, false);
19545             }
19546         }
19547
19548         if (mProcessStats.shouldWriteNowLocked(now)) {
19549             mHandler.post(new Runnable() {
19550                 @Override public void run() {
19551                     synchronized (ActivityManagerService.this) {
19552                         mProcessStats.writeStateAsyncLocked();
19553                     }
19554                 }
19555             });
19556         }
19557
19558         if (DEBUG_OOM_ADJ) {
19559             final long duration = SystemClock.uptimeMillis() - now;
19560             if (false) {
19561                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19562                         new RuntimeException("here").fillInStackTrace());
19563             } else {
19564                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19565             }
19566         }
19567     }
19568
19569     final void trimApplications() {
19570         synchronized (this) {
19571             int i;
19572
19573             // First remove any unused application processes whose package
19574             // has been removed.
19575             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19576                 final ProcessRecord app = mRemovedProcesses.get(i);
19577                 if (app.activities.size() == 0
19578                         && app.curReceiver == null && app.services.size() == 0) {
19579                     Slog.i(
19580                         TAG, "Exiting empty application process "
19581                         + app.processName + " ("
19582                         + (app.thread != null ? app.thread.asBinder() : null)
19583                         + ")\n");
19584                     if (app.pid > 0 && app.pid != MY_PID) {
19585                         app.kill("empty", false);
19586                     } else {
19587                         try {
19588                             app.thread.scheduleExit();
19589                         } catch (Exception e) {
19590                             // Ignore exceptions.
19591                         }
19592                     }
19593                     cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
19594                     mRemovedProcesses.remove(i);
19595
19596                     if (app.persistent) {
19597                         addAppLocked(app.info, false, null /* ABI override */);
19598                     }
19599                 }
19600             }
19601
19602             // Now update the oom adj for all processes.
19603             updateOomAdjLocked();
19604         }
19605     }
19606
19607     /** This method sends the specified signal to each of the persistent apps */
19608     public void signalPersistentProcesses(int sig) throws RemoteException {
19609         if (sig != Process.SIGNAL_USR1) {
19610             throw new SecurityException("Only SIGNAL_USR1 is allowed");
19611         }
19612
19613         synchronized (this) {
19614             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19615                     != PackageManager.PERMISSION_GRANTED) {
19616                 throw new SecurityException("Requires permission "
19617                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19618             }
19619
19620             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19621                 ProcessRecord r = mLruProcesses.get(i);
19622                 if (r.thread != null && r.persistent) {
19623                     Process.sendSignal(r.pid, sig);
19624                 }
19625             }
19626         }
19627     }
19628
19629     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19630         if (proc == null || proc == mProfileProc) {
19631             proc = mProfileProc;
19632             profileType = mProfileType;
19633             clearProfilerLocked();
19634         }
19635         if (proc == null) {
19636             return;
19637         }
19638         try {
19639             proc.thread.profilerControl(false, null, profileType);
19640         } catch (RemoteException e) {
19641             throw new IllegalStateException("Process disappeared");
19642         }
19643     }
19644
19645     private void clearProfilerLocked() {
19646         if (mProfileFd != null) {
19647             try {
19648                 mProfileFd.close();
19649             } catch (IOException e) {
19650             }
19651         }
19652         mProfileApp = null;
19653         mProfileProc = null;
19654         mProfileFile = null;
19655         mProfileType = 0;
19656         mAutoStopProfiler = false;
19657         mSamplingInterval = 0;
19658     }
19659
19660     public boolean profileControl(String process, int userId, boolean start,
19661             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19662
19663         try {
19664             synchronized (this) {
19665                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19666                 // its own permission.
19667                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19668                         != PackageManager.PERMISSION_GRANTED) {
19669                     throw new SecurityException("Requires permission "
19670                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19671                 }
19672
19673                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19674                     throw new IllegalArgumentException("null profile info or fd");
19675                 }
19676
19677                 ProcessRecord proc = null;
19678                 if (process != null) {
19679                     proc = findProcessLocked(process, userId, "profileControl");
19680                 }
19681
19682                 if (start && (proc == null || proc.thread == null)) {
19683                     throw new IllegalArgumentException("Unknown process: " + process);
19684                 }
19685
19686                 if (start) {
19687                     stopProfilerLocked(null, 0);
19688                     setProfileApp(proc.info, proc.processName, profilerInfo);
19689                     mProfileProc = proc;
19690                     mProfileType = profileType;
19691                     ParcelFileDescriptor fd = profilerInfo.profileFd;
19692                     try {
19693                         fd = fd.dup();
19694                     } catch (IOException e) {
19695                         fd = null;
19696                     }
19697                     profilerInfo.profileFd = fd;
19698                     proc.thread.profilerControl(start, profilerInfo, profileType);
19699                     fd = null;
19700                     mProfileFd = null;
19701                 } else {
19702                     stopProfilerLocked(proc, profileType);
19703                     if (profilerInfo != null && profilerInfo.profileFd != null) {
19704                         try {
19705                             profilerInfo.profileFd.close();
19706                         } catch (IOException e) {
19707                         }
19708                     }
19709                 }
19710
19711                 return true;
19712             }
19713         } catch (RemoteException e) {
19714             throw new IllegalStateException("Process disappeared");
19715         } finally {
19716             if (profilerInfo != null && profilerInfo.profileFd != null) {
19717                 try {
19718                     profilerInfo.profileFd.close();
19719                 } catch (IOException e) {
19720                 }
19721             }
19722         }
19723     }
19724
19725     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19726         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19727                 userId, true, ALLOW_FULL_ONLY, callName, null);
19728         ProcessRecord proc = null;
19729         try {
19730             int pid = Integer.parseInt(process);
19731             synchronized (mPidsSelfLocked) {
19732                 proc = mPidsSelfLocked.get(pid);
19733             }
19734         } catch (NumberFormatException e) {
19735         }
19736
19737         if (proc == null) {
19738             ArrayMap<String, SparseArray<ProcessRecord>> all
19739                     = mProcessNames.getMap();
19740             SparseArray<ProcessRecord> procs = all.get(process);
19741             if (procs != null && procs.size() > 0) {
19742                 proc = procs.valueAt(0);
19743                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19744                     for (int i=1; i<procs.size(); i++) {
19745                         ProcessRecord thisProc = procs.valueAt(i);
19746                         if (thisProc.userId == userId) {
19747                             proc = thisProc;
19748                             break;
19749                         }
19750                     }
19751                 }
19752             }
19753         }
19754
19755         return proc;
19756     }
19757
19758     public boolean dumpHeap(String process, int userId, boolean managed,
19759             String path, ParcelFileDescriptor fd) throws RemoteException {
19760
19761         try {
19762             synchronized (this) {
19763                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19764                 // its own permission (same as profileControl).
19765                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19766                         != PackageManager.PERMISSION_GRANTED) {
19767                     throw new SecurityException("Requires permission "
19768                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19769                 }
19770
19771                 if (fd == null) {
19772                     throw new IllegalArgumentException("null fd");
19773                 }
19774
19775                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19776                 if (proc == null || proc.thread == null) {
19777                     throw new IllegalArgumentException("Unknown process: " + process);
19778                 }
19779
19780                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19781                 if (!isDebuggable) {
19782                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19783                         throw new SecurityException("Process not debuggable: " + proc);
19784                     }
19785                 }
19786
19787                 proc.thread.dumpHeap(managed, path, fd);
19788                 fd = null;
19789                 return true;
19790             }
19791         } catch (RemoteException e) {
19792             throw new IllegalStateException("Process disappeared");
19793         } finally {
19794             if (fd != null) {
19795                 try {
19796                     fd.close();
19797                 } catch (IOException e) {
19798                 }
19799             }
19800         }
19801     }
19802
19803     @Override
19804     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19805             String reportPackage) {
19806         if (processName != null) {
19807             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19808                     "setDumpHeapDebugLimit()");
19809         } else {
19810             synchronized (mPidsSelfLocked) {
19811                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19812                 if (proc == null) {
19813                     throw new SecurityException("No process found for calling pid "
19814                             + Binder.getCallingPid());
19815                 }
19816                 if (!Build.IS_DEBUGGABLE
19817                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19818                     throw new SecurityException("Not running a debuggable build");
19819                 }
19820                 processName = proc.processName;
19821                 uid = proc.uid;
19822                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19823                     throw new SecurityException("Package " + reportPackage + " is not running in "
19824                             + proc);
19825                 }
19826             }
19827         }
19828         synchronized (this) {
19829             if (maxMemSize > 0) {
19830                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19831             } else {
19832                 if (uid != 0) {
19833                     mMemWatchProcesses.remove(processName, uid);
19834                 } else {
19835                     mMemWatchProcesses.getMap().remove(processName);
19836                 }
19837             }
19838         }
19839     }
19840
19841     @Override
19842     public void dumpHeapFinished(String path) {
19843         synchronized (this) {
19844             if (Binder.getCallingPid() != mMemWatchDumpPid) {
19845                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19846                         + " does not match last pid " + mMemWatchDumpPid);
19847                 return;
19848             }
19849             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19850                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19851                         + " does not match last path " + mMemWatchDumpFile);
19852                 return;
19853             }
19854             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19855             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19856         }
19857     }
19858
19859     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19860     public void monitor() {
19861         synchronized (this) { }
19862     }
19863
19864     void onCoreSettingsChange(Bundle settings) {
19865         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19866             ProcessRecord processRecord = mLruProcesses.get(i);
19867             try {
19868                 if (processRecord.thread != null) {
19869                     processRecord.thread.setCoreSettings(settings);
19870                 }
19871             } catch (RemoteException re) {
19872                 /* ignore */
19873             }
19874         }
19875     }
19876
19877     // Multi-user methods
19878
19879     /**
19880      * Start user, if its not already running, but don't bring it to foreground.
19881      */
19882     @Override
19883     public boolean startUserInBackground(final int userId) {
19884         return startUser(userId, /* foreground */ false);
19885     }
19886
19887     /**
19888      * Start user, if its not already running, and bring it to foreground.
19889      */
19890     boolean startUserInForeground(final int userId, Dialog dlg) {
19891         boolean result = startUser(userId, /* foreground */ true);
19892         dlg.dismiss();
19893         return result;
19894     }
19895
19896     /**
19897      * Refreshes the list of users related to the current user when either a
19898      * user switch happens or when a new related user is started in the
19899      * background.
19900      */
19901     private void updateCurrentProfileIdsLocked() {
19902         final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19903                 mCurrentUserId, false /* enabledOnly */);
19904         int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19905         for (int i = 0; i < currentProfileIds.length; i++) {
19906             currentProfileIds[i] = profiles.get(i).id;
19907         }
19908         mCurrentProfileIds = currentProfileIds;
19909
19910         synchronized (mUserProfileGroupIdsSelfLocked) {
19911             mUserProfileGroupIdsSelfLocked.clear();
19912             final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19913             for (int i = 0; i < users.size(); i++) {
19914                 UserInfo user = users.get(i);
19915                 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19916                     mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19917                 }
19918             }
19919         }
19920     }
19921
19922     private Set<Integer> getProfileIdsLocked(int userId) {
19923         Set<Integer> userIds = new HashSet<Integer>();
19924         final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19925                 userId, false /* enabledOnly */);
19926         for (UserInfo user : profiles) {
19927             userIds.add(Integer.valueOf(user.id));
19928         }
19929         return userIds;
19930     }
19931
19932     @Override
19933     public boolean switchUser(final int userId) {
19934         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19935         String userName;
19936         synchronized (this) {
19937             UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19938             if (userInfo == null) {
19939                 Slog.w(TAG, "No user info for user #" + userId);
19940                 return false;
19941             }
19942             if (userInfo.isManagedProfile()) {
19943                 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19944                 return false;
19945             }
19946             userName = userInfo.name;
19947             mTargetUserId = userId;
19948         }
19949         mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19950         mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19951         return true;
19952     }
19953
19954     private void showUserSwitchDialog(int userId, String userName) {
19955         // The dialog will show and then initiate the user switch by calling startUserInForeground
19956         Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19957                 true /* above system */);
19958         d.show();
19959     }
19960
19961     private boolean startUser(final int userId, final boolean foreground) {
19962         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19963                 != PackageManager.PERMISSION_GRANTED) {
19964             String msg = "Permission Denial: switchUser() from pid="
19965                     + Binder.getCallingPid()
19966                     + ", uid=" + Binder.getCallingUid()
19967                     + " requires " + INTERACT_ACROSS_USERS_FULL;
19968             Slog.w(TAG, msg);
19969             throw new SecurityException(msg);
19970         }
19971
19972         if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19973
19974         final long ident = Binder.clearCallingIdentity();
19975         try {
19976             synchronized (this) {
19977                 final int oldUserId = mCurrentUserId;
19978                 if (oldUserId == userId) {
19979                     return true;
19980                 }
19981
19982                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19983                         "startUser", false);
19984
19985                 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19986                 if (userInfo == null) {
19987                     Slog.w(TAG, "No user info for user #" + userId);
19988                     return false;
19989                 }
19990                 if (foreground && userInfo.isManagedProfile()) {
19991                     Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19992                     return false;
19993                 }
19994
19995                 if (foreground) {
19996                     mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19997                             R.anim.screen_user_enter);
19998                 }
19999
20000                 boolean needStart = false;
20001
20002                 // If the user we are switching to is not currently started, then
20003                 // we need to start it now.
20004                 if (mStartedUsers.get(userId) == null) {
20005                     mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
20006                     updateStartedUserArrayLocked();
20007                     needStart = true;
20008                 }
20009
20010                 final Integer userIdInt = Integer.valueOf(userId);
20011                 mUserLru.remove(userIdInt);
20012                 mUserLru.add(userIdInt);
20013
20014                 if (foreground) {
20015                     mCurrentUserId = userId;
20016                     mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
20017                     updateCurrentProfileIdsLocked();
20018                     mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
20019                     // Once the internal notion of the active user has switched, we lock the device
20020                     // with the option to show the user switcher on the keyguard.
20021                     mWindowManager.lockNow(null);
20022                 } else {
20023                     final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
20024                     updateCurrentProfileIdsLocked();
20025                     mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
20026                     mUserLru.remove(currentUserIdInt);
20027                     mUserLru.add(currentUserIdInt);
20028                 }
20029
20030                 final UserState uss = mStartedUsers.get(userId);
20031
20032                 // Make sure user is in the started state.  If it is currently
20033                 // stopping, we need to knock that off.
20034                 if (uss.mState == UserState.STATE_STOPPING) {
20035                     // If we are stopping, we haven't sent ACTION_SHUTDOWN,
20036                     // so we can just fairly silently bring the user back from
20037                     // the almost-dead.
20038                     uss.mState = UserState.STATE_RUNNING;
20039                     updateStartedUserArrayLocked();
20040                     needStart = true;
20041                 } else if (uss.mState == UserState.STATE_SHUTDOWN) {
20042                     // This means ACTION_SHUTDOWN has been sent, so we will
20043                     // need to treat this as a new boot of the user.
20044                     uss.mState = UserState.STATE_BOOTING;
20045                     updateStartedUserArrayLocked();
20046                     needStart = true;
20047                 }
20048
20049                 if (uss.mState == UserState.STATE_BOOTING) {
20050                     // Booting up a new user, need to tell system services about it.
20051                     // Note that this is on the same handler as scheduling of broadcasts,
20052                     // which is important because it needs to go first.
20053                     mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
20054                 }
20055
20056                 if (foreground) {
20057                     mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
20058                             oldUserId));
20059                     mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
20060                     mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
20061                     mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
20062                             oldUserId, userId, uss));
20063                     mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
20064                             oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
20065                 }
20066
20067                 if (needStart) {
20068                     // Send USER_STARTED broadcast
20069                     Intent intent = new Intent(Intent.ACTION_USER_STARTED);
20070                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20071                             | Intent.FLAG_RECEIVER_FOREGROUND);
20072                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20073                     broadcastIntentLocked(null, null, intent,
20074                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
20075                             null, false, false, MY_PID, Process.SYSTEM_UID, userId);
20076                 }
20077
20078                 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
20079                     if (userId != UserHandle.USER_OWNER) {
20080                         Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
20081                         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
20082                         broadcastIntentLocked(null, null, intent, null,
20083                                 new IIntentReceiver.Stub() {
20084                                     public void performReceive(Intent intent, int resultCode,
20085                                             String data, Bundle extras, boolean ordered,
20086                                             boolean sticky, int sendingUser) {
20087                                         onUserInitialized(uss, foreground, oldUserId, userId);
20088                                     }
20089                                 }, 0, null, null, null, AppOpsManager.OP_NONE,
20090                                 null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20091                         uss.initializing = true;
20092                     } else {
20093                         getUserManagerLocked().makeInitialized(userInfo.id);
20094                     }
20095                 }
20096
20097                 if (foreground) {
20098                     if (!uss.initializing) {
20099                         moveUserToForeground(uss, oldUserId, userId);
20100                     }
20101                 } else {
20102                     mStackSupervisor.startBackgroundUserLocked(userId, uss);
20103                 }
20104
20105                 if (needStart) {
20106                     Intent intent = new Intent(Intent.ACTION_USER_STARTING);
20107                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20108                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20109                     broadcastIntentLocked(null, null, intent,
20110                             null, new IIntentReceiver.Stub() {
20111                                 @Override
20112                                 public void performReceive(Intent intent, int resultCode,
20113                                         String data, Bundle extras, boolean ordered, boolean sticky,
20114                                         int sendingUser) throws RemoteException {
20115                                 }
20116                             }, 0, null, null,
20117                             new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
20118                             null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20119                 }
20120             }
20121         } finally {
20122             Binder.restoreCallingIdentity(ident);
20123         }
20124
20125         return true;
20126     }
20127
20128     void dispatchForegroundProfileChanged(int userId) {
20129         final int N = mUserSwitchObservers.beginBroadcast();
20130         for (int i = 0; i < N; i++) {
20131             try {
20132                 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
20133             } catch (RemoteException e) {
20134                 // Ignore
20135             }
20136         }
20137         mUserSwitchObservers.finishBroadcast();
20138     }
20139
20140     void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
20141         long ident = Binder.clearCallingIdentity();
20142         try {
20143             Intent intent;
20144             if (oldUserId >= 0) {
20145                 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
20146                 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
20147                 int count = profiles.size();
20148                 for (int i = 0; i < count; i++) {
20149                     int profileUserId = profiles.get(i).id;
20150                     intent = new Intent(Intent.ACTION_USER_BACKGROUND);
20151                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20152                             | Intent.FLAG_RECEIVER_FOREGROUND);
20153                     intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
20154                     broadcastIntentLocked(null, null, intent,
20155                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
20156                             null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
20157                 }
20158             }
20159             if (newUserId >= 0) {
20160                 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
20161                 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
20162                 int count = profiles.size();
20163                 for (int i = 0; i < count; i++) {
20164                     int profileUserId = profiles.get(i).id;
20165                     intent = new Intent(Intent.ACTION_USER_FOREGROUND);
20166                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20167                             | Intent.FLAG_RECEIVER_FOREGROUND);
20168                     intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
20169                     broadcastIntentLocked(null, null, intent,
20170                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
20171                             null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
20172                 }
20173                 intent = new Intent(Intent.ACTION_USER_SWITCHED);
20174                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20175                         | Intent.FLAG_RECEIVER_FOREGROUND);
20176                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
20177                 broadcastIntentLocked(null, null, intent,
20178                         null, null, 0, null, null,
20179                         new String[] {android.Manifest.permission.MANAGE_USERS},
20180                         AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
20181                         UserHandle.USER_ALL);
20182             }
20183         } finally {
20184             Binder.restoreCallingIdentity(ident);
20185         }
20186     }
20187
20188     void dispatchUserSwitch(final UserState uss, final int oldUserId,
20189             final int newUserId) {
20190         final int N = mUserSwitchObservers.beginBroadcast();
20191         if (N > 0) {
20192             final IRemoteCallback callback = new IRemoteCallback.Stub() {
20193                 int mCount = 0;
20194                 @Override
20195                 public void sendResult(Bundle data) throws RemoteException {
20196                     synchronized (ActivityManagerService.this) {
20197                         if (mCurUserSwitchCallback == this) {
20198                             mCount++;
20199                             if (mCount == N) {
20200                                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20201                             }
20202                         }
20203                     }
20204                 }
20205             };
20206             synchronized (this) {
20207                 uss.switching = true;
20208                 mCurUserSwitchCallback = callback;
20209             }
20210             for (int i=0; i<N; i++) {
20211                 try {
20212                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
20213                             newUserId, callback);
20214                 } catch (RemoteException e) {
20215                 }
20216             }
20217         } else {
20218             synchronized (this) {
20219                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20220             }
20221         }
20222         mUserSwitchObservers.finishBroadcast();
20223     }
20224
20225     void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
20226         synchronized (this) {
20227             Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
20228             sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20229         }
20230     }
20231
20232     void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
20233         mCurUserSwitchCallback = null;
20234         mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
20235         mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
20236                 oldUserId, newUserId, uss));
20237     }
20238
20239     void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
20240         synchronized (this) {
20241             if (foreground) {
20242                 moveUserToForeground(uss, oldUserId, newUserId);
20243             }
20244         }
20245
20246         completeSwitchAndInitialize(uss, newUserId, true, false);
20247     }
20248
20249     void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
20250         boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
20251         if (homeInFront) {
20252             startHomeActivityLocked(newUserId, "moveUserToFroreground");
20253         } else {
20254             mStackSupervisor.resumeTopActivitiesLocked();
20255         }
20256         EventLogTags.writeAmSwitchUser(newUserId);
20257         getUserManagerLocked().onUserForeground(newUserId);
20258         sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
20259     }
20260
20261     void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
20262         completeSwitchAndInitialize(uss, newUserId, false, true);
20263     }
20264
20265     void completeSwitchAndInitialize(UserState uss, int newUserId,
20266             boolean clearInitializing, boolean clearSwitching) {
20267         boolean unfrozen = false;
20268         synchronized (this) {
20269             if (clearInitializing) {
20270                 uss.initializing = false;
20271                 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
20272             }
20273             if (clearSwitching) {
20274                 uss.switching = false;
20275             }
20276             if (!uss.switching && !uss.initializing) {
20277                 mWindowManager.stopFreezingScreen();
20278                 unfrozen = true;
20279             }
20280         }
20281         if (unfrozen) {
20282             mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
20283             mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
20284                     newUserId, 0));
20285         }
20286         stopGuestUserIfBackground();
20287     }
20288
20289     /** Called on handler thread */
20290     void dispatchUserSwitchComplete(int userId) {
20291         final int observerCount = mUserSwitchObservers.beginBroadcast();
20292         for (int i = 0; i < observerCount; i++) {
20293             try {
20294                 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
20295             } catch (RemoteException e) {
20296             }
20297         }
20298         mUserSwitchObservers.finishBroadcast();
20299     }
20300
20301     /**
20302      * Stops the guest user if it has gone to the background.
20303      */
20304     private void stopGuestUserIfBackground() {
20305         synchronized (this) {
20306             final int num = mUserLru.size();
20307             for (int i = 0; i < num; i++) {
20308                 Integer oldUserId = mUserLru.get(i);
20309                 UserState oldUss = mStartedUsers.get(oldUserId);
20310                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
20311                         || oldUss.mState == UserState.STATE_STOPPING
20312                         || oldUss.mState == UserState.STATE_SHUTDOWN) {
20313                     continue;
20314                 }
20315                 UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
20316                 if (userInfo.isGuest()) {
20317                     // This is a user to be stopped.
20318                     stopUserLocked(oldUserId, null);
20319                     break;
20320                 }
20321             }
20322         }
20323     }
20324
20325     void scheduleStartProfilesLocked() {
20326         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20327             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20328                     DateUtils.SECOND_IN_MILLIS);
20329         }
20330     }
20331
20332     void startProfilesLocked() {
20333         if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
20334         List<UserInfo> profiles = getUserManagerLocked().getProfiles(
20335                 mCurrentUserId, false /* enabledOnly */);
20336         List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
20337         for (UserInfo user : profiles) {
20338             if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
20339                     && user.id != mCurrentUserId) {
20340                 toStart.add(user);
20341             }
20342         }
20343         final int n = toStart.size();
20344         int i = 0;
20345         for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
20346             startUserInBackground(toStart.get(i).id);
20347         }
20348         if (i < n) {
20349             Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
20350         }
20351     }
20352
20353     void finishUserBoot(UserState uss) {
20354         synchronized (this) {
20355             if (uss.mState == UserState.STATE_BOOTING
20356                     && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
20357                 uss.mState = UserState.STATE_RUNNING;
20358                 final int userId = uss.mHandle.getIdentifier();
20359                 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
20360                 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20361                 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
20362                 broadcastIntentLocked(null, null, intent,
20363                         null, null, 0, null, null,
20364                         new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
20365                         AppOpsManager.OP_NONE, null, true, false, MY_PID, Process.SYSTEM_UID,
20366                         userId);
20367             }
20368         }
20369     }
20370
20371     void finishUserSwitch(UserState uss) {
20372         synchronized (this) {
20373             finishUserBoot(uss);
20374
20375             startProfilesLocked();
20376
20377             int num = mUserLru.size();
20378             int i = 0;
20379             while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
20380                 Integer oldUserId = mUserLru.get(i);
20381                 UserState oldUss = mStartedUsers.get(oldUserId);
20382                 if (oldUss == null) {
20383                     // Shouldn't happen, but be sane if it does.
20384                     mUserLru.remove(i);
20385                     num--;
20386                     continue;
20387                 }
20388                 if (oldUss.mState == UserState.STATE_STOPPING
20389                         || oldUss.mState == UserState.STATE_SHUTDOWN) {
20390                     // This user is already stopping, doesn't count.
20391                     num--;
20392                     i++;
20393                     continue;
20394                 }
20395                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
20396                     // Owner and current can't be stopped, but count as running.
20397                     i++;
20398                     continue;
20399                 }
20400                 // This is a user to be stopped.
20401                 stopUserLocked(oldUserId, null);
20402                 num--;
20403                 i++;
20404             }
20405         }
20406     }
20407
20408     @Override
20409     public int stopUser(final int userId, final IStopUserCallback callback) {
20410         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20411                 != PackageManager.PERMISSION_GRANTED) {
20412             String msg = "Permission Denial: switchUser() from pid="
20413                     + Binder.getCallingPid()
20414                     + ", uid=" + Binder.getCallingUid()
20415                     + " requires " + INTERACT_ACROSS_USERS_FULL;
20416             Slog.w(TAG, msg);
20417             throw new SecurityException(msg);
20418         }
20419         if (userId < 0 || userId == UserHandle.USER_OWNER) {
20420             throw new IllegalArgumentException("Can't stop primary user " + userId);
20421         }
20422         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
20423         synchronized (this) {
20424             return stopUserLocked(userId, callback);
20425         }
20426     }
20427
20428     private int stopUserLocked(final int userId, final IStopUserCallback callback) {
20429         if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
20430         if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
20431             return ActivityManager.USER_OP_IS_CURRENT;
20432         }
20433
20434         final UserState uss = mStartedUsers.get(userId);
20435         if (uss == null) {
20436             // User is not started, nothing to do...  but we do need to
20437             // callback if requested.
20438             if (callback != null) {
20439                 mHandler.post(new Runnable() {
20440                     @Override
20441                     public void run() {
20442                         try {
20443                             callback.userStopped(userId);
20444                         } catch (RemoteException e) {
20445                         }
20446                     }
20447                 });
20448             }
20449             return ActivityManager.USER_OP_SUCCESS;
20450         }
20451
20452         if (callback != null) {
20453             uss.mStopCallbacks.add(callback);
20454         }
20455
20456         if (uss.mState != UserState.STATE_STOPPING
20457                 && uss.mState != UserState.STATE_SHUTDOWN) {
20458             uss.mState = UserState.STATE_STOPPING;
20459             updateStartedUserArrayLocked();
20460
20461             long ident = Binder.clearCallingIdentity();
20462             try {
20463                 // We are going to broadcast ACTION_USER_STOPPING and then
20464                 // once that is done send a final ACTION_SHUTDOWN and then
20465                 // stop the user.
20466                 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
20467                 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20468                 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20469                 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
20470                 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
20471                 // This is the result receiver for the final shutdown broadcast.
20472                 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
20473                     @Override
20474                     public void performReceive(Intent intent, int resultCode, String data,
20475                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20476                         finishUserStop(uss);
20477                     }
20478                 };
20479                 // This is the result receiver for the initial stopping broadcast.
20480                 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
20481                     @Override
20482                     public void performReceive(Intent intent, int resultCode, String data,
20483                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20484                         // On to the next.
20485                         synchronized (ActivityManagerService.this) {
20486                             if (uss.mState != UserState.STATE_STOPPING) {
20487                                 // Whoops, we are being started back up.  Abort, abort!
20488                                 return;
20489                             }
20490                             uss.mState = UserState.STATE_SHUTDOWN;
20491                         }
20492                         mBatteryStatsService.noteEvent(
20493                                 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
20494                                 Integer.toString(userId), userId);
20495                         mSystemServiceManager.stopUser(userId);
20496                         broadcastIntentLocked(null, null, shutdownIntent,
20497                                 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
20498                                 null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20499                     }
20500                 };
20501                 // Kick things off.
20502                 broadcastIntentLocked(null, null, stoppingIntent,
20503                         null, stoppingReceiver, 0, null, null,
20504                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
20505                         null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20506             } finally {
20507                 Binder.restoreCallingIdentity(ident);
20508             }
20509         }
20510
20511         return ActivityManager.USER_OP_SUCCESS;
20512     }
20513
20514     void finishUserStop(UserState uss) {
20515         final int userId = uss.mHandle.getIdentifier();
20516         boolean stopped;
20517         ArrayList<IStopUserCallback> callbacks;
20518         synchronized (this) {
20519             callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
20520             if (mStartedUsers.get(userId) != uss) {
20521                 stopped = false;
20522             } else if (uss.mState != UserState.STATE_SHUTDOWN) {
20523                 stopped = false;
20524             } else {
20525                 stopped = true;
20526                 // User can no longer run.
20527                 mStartedUsers.remove(userId);
20528                 mUserLru.remove(Integer.valueOf(userId));
20529                 updateStartedUserArrayLocked();
20530
20531                 // Clean up all state and processes associated with the user.
20532                 // Kill all the processes for the user.
20533                 forceStopUserLocked(userId, "finish user");
20534             }
20535
20536             // Explicitly remove the old information in mRecentTasks.
20537             mRecentTasks.removeTasksForUserLocked(userId);
20538         }
20539
20540         for (int i=0; i<callbacks.size(); i++) {
20541             try {
20542                 if (stopped) callbacks.get(i).userStopped(userId);
20543                 else callbacks.get(i).userStopAborted(userId);
20544             } catch (RemoteException e) {
20545             }
20546         }
20547
20548         if (stopped) {
20549             mSystemServiceManager.cleanupUser(userId);
20550             synchronized (this) {
20551                 mStackSupervisor.removeUserLocked(userId);
20552             }
20553         }
20554     }
20555
20556     @Override
20557     public UserInfo getCurrentUser() {
20558         if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20559                 != PackageManager.PERMISSION_GRANTED) && (
20560                 checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20561                 != PackageManager.PERMISSION_GRANTED)) {
20562             String msg = "Permission Denial: getCurrentUser() from pid="
20563                     + Binder.getCallingPid()
20564                     + ", uid=" + Binder.getCallingUid()
20565                     + " requires " + INTERACT_ACROSS_USERS;
20566             Slog.w(TAG, msg);
20567             throw new SecurityException(msg);
20568         }
20569         synchronized (this) {
20570             int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20571             return getUserManagerLocked().getUserInfo(userId);
20572         }
20573     }
20574
20575     int getCurrentUserIdLocked() {
20576         return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20577     }
20578
20579     @Override
20580     public boolean isUserRunning(int userId, boolean orStopped) {
20581         if (checkCallingPermission(INTERACT_ACROSS_USERS)
20582                 != PackageManager.PERMISSION_GRANTED) {
20583             String msg = "Permission Denial: isUserRunning() from pid="
20584                     + Binder.getCallingPid()
20585                     + ", uid=" + Binder.getCallingUid()
20586                     + " requires " + INTERACT_ACROSS_USERS;
20587             Slog.w(TAG, msg);
20588             throw new SecurityException(msg);
20589         }
20590         synchronized (this) {
20591             return isUserRunningLocked(userId, orStopped);
20592         }
20593     }
20594
20595     boolean isUserRunningLocked(int userId, boolean orStopped) {
20596         UserState state = mStartedUsers.get(userId);
20597         if (state == null) {
20598             return false;
20599         }
20600         if (orStopped) {
20601             return true;
20602         }
20603         return state.mState != UserState.STATE_STOPPING
20604                 && state.mState != UserState.STATE_SHUTDOWN;
20605     }
20606
20607     @Override
20608     public int[] getRunningUserIds() {
20609         if (checkCallingPermission(INTERACT_ACROSS_USERS)
20610                 != PackageManager.PERMISSION_GRANTED) {
20611             String msg = "Permission Denial: isUserRunning() from pid="
20612                     + Binder.getCallingPid()
20613                     + ", uid=" + Binder.getCallingUid()
20614                     + " requires " + INTERACT_ACROSS_USERS;
20615             Slog.w(TAG, msg);
20616             throw new SecurityException(msg);
20617         }
20618         synchronized (this) {
20619             return mStartedUserArray;
20620         }
20621     }
20622
20623     private void updateStartedUserArrayLocked() {
20624         int num = 0;
20625         for (int i=0; i<mStartedUsers.size();  i++) {
20626             UserState uss = mStartedUsers.valueAt(i);
20627             // This list does not include stopping users.
20628             if (uss.mState != UserState.STATE_STOPPING
20629                     && uss.mState != UserState.STATE_SHUTDOWN) {
20630                 num++;
20631             }
20632         }
20633         mStartedUserArray = new int[num];
20634         num = 0;
20635         for (int i=0; i<mStartedUsers.size();  i++) {
20636             UserState uss = mStartedUsers.valueAt(i);
20637             if (uss.mState != UserState.STATE_STOPPING
20638                     && uss.mState != UserState.STATE_SHUTDOWN) {
20639                 mStartedUserArray[num] = mStartedUsers.keyAt(i);
20640                 num++;
20641             }
20642         }
20643     }
20644
20645     @Override
20646     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20647         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20648                 != PackageManager.PERMISSION_GRANTED) {
20649             String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20650                     + Binder.getCallingPid()
20651                     + ", uid=" + Binder.getCallingUid()
20652                     + " requires " + INTERACT_ACROSS_USERS_FULL;
20653             Slog.w(TAG, msg);
20654             throw new SecurityException(msg);
20655         }
20656
20657         mUserSwitchObservers.register(observer);
20658     }
20659
20660     @Override
20661     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20662         mUserSwitchObservers.unregister(observer);
20663     }
20664
20665     int[] getUsersLocked() {
20666         UserManagerService ums = getUserManagerLocked();
20667         return ums != null ? ums.getUserIds() : new int[] { 0 };
20668     }
20669
20670     UserManagerService getUserManagerLocked() {
20671         if (mUserManager == null) {
20672             IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20673             mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20674         }
20675         return mUserManager;
20676     }
20677
20678     private int applyUserId(int uid, int userId) {
20679         return UserHandle.getUid(userId, uid);
20680     }
20681
20682     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20683         if (info == null) return null;
20684         ApplicationInfo newInfo = new ApplicationInfo(info);
20685         newInfo.uid = applyUserId(info.uid, userId);
20686         newInfo.dataDir = Environment
20687                 .getDataUserPackageDirectory(info.volumeUuid, userId, info.packageName)
20688                 .getAbsolutePath();
20689         return newInfo;
20690     }
20691
20692     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20693         if (aInfo == null
20694                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20695             return aInfo;
20696         }
20697
20698         ActivityInfo info = new ActivityInfo(aInfo);
20699         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20700         return info;
20701     }
20702
20703     private final class LocalService extends ActivityManagerInternal {
20704         @Override
20705         public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
20706                 int targetUserId) {
20707             synchronized (ActivityManagerService.this) {
20708                 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
20709                         targetPkg, intent, null, targetUserId);
20710             }
20711         }
20712
20713         @Override
20714         public String checkContentProviderAccess(String authority, int userId) {
20715             return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
20716         }
20717
20718         @Override
20719         public void onWakefulnessChanged(int wakefulness) {
20720             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20721         }
20722
20723         @Override
20724         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20725                 String processName, String abiOverride, int uid, Runnable crashHandler) {
20726             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20727                     processName, abiOverride, uid, crashHandler);
20728         }
20729
20730         @Override
20731         public SleepToken acquireSleepToken(String tag) {
20732             Preconditions.checkNotNull(tag);
20733
20734             synchronized (ActivityManagerService.this) {
20735                 SleepTokenImpl token = new SleepTokenImpl(tag);
20736                 mSleepTokens.add(token);
20737                 updateSleepIfNeededLocked();
20738                 return token;
20739             }
20740         }
20741
20742         @Override
20743         public ComponentName getHomeActivityForUser(int userId) {
20744             synchronized (ActivityManagerService.this) {
20745                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20746                 return homeActivity == null ? null : homeActivity.realActivity;
20747             }
20748         }
20749     }
20750
20751     private final class SleepTokenImpl extends SleepToken {
20752         private final String mTag;
20753         private final long mAcquireTime;
20754
20755         public SleepTokenImpl(String tag) {
20756             mTag = tag;
20757             mAcquireTime = SystemClock.uptimeMillis();
20758         }
20759
20760         @Override
20761         public void release() {
20762             synchronized (ActivityManagerService.this) {
20763                 if (mSleepTokens.remove(this)) {
20764                     updateSleepIfNeededLocked();
20765                 }
20766             }
20767         }
20768
20769         @Override
20770         public String toString() {
20771             return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20772         }
20773     }
20774
20775     /**
20776      * An implementation of IAppTask, that allows an app to manage its own tasks via
20777      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20778      * only the process that calls getAppTasks() can call the AppTask methods.
20779      */
20780     class AppTaskImpl extends IAppTask.Stub {
20781         private int mTaskId;
20782         private int mCallingUid;
20783
20784         public AppTaskImpl(int taskId, int callingUid) {
20785             mTaskId = taskId;
20786             mCallingUid = callingUid;
20787         }
20788
20789         private void checkCaller() {
20790             if (mCallingUid != Binder.getCallingUid()) {
20791                 throw new SecurityException("Caller " + mCallingUid
20792                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20793             }
20794         }
20795
20796         @Override
20797         public void finishAndRemoveTask() {
20798             checkCaller();
20799
20800             synchronized (ActivityManagerService.this) {
20801                 long origId = Binder.clearCallingIdentity();
20802                 try {
20803                     if (!removeTaskByIdLocked(mTaskId, false)) {
20804                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20805                     }
20806                 } finally {
20807                     Binder.restoreCallingIdentity(origId);
20808                 }
20809             }
20810         }
20811
20812         @Override
20813         public ActivityManager.RecentTaskInfo getTaskInfo() {
20814             checkCaller();
20815
20816             synchronized (ActivityManagerService.this) {
20817                 long origId = Binder.clearCallingIdentity();
20818                 try {
20819                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20820                     if (tr == null) {
20821                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20822                     }
20823                     return createRecentTaskInfoFromTaskRecord(tr);
20824                 } finally {
20825                     Binder.restoreCallingIdentity(origId);
20826                 }
20827             }
20828         }
20829
20830         @Override
20831         public void moveToFront() {
20832             checkCaller();
20833             // Will bring task to front if it already has a root activity.
20834             startActivityFromRecentsInner(mTaskId, null);
20835         }
20836
20837         @Override
20838         public int startActivity(IBinder whoThread, String callingPackage,
20839                 Intent intent, String resolvedType, Bundle options) {
20840             checkCaller();
20841
20842             int callingUser = UserHandle.getCallingUserId();
20843             TaskRecord tr;
20844             IApplicationThread appThread;
20845             synchronized (ActivityManagerService.this) {
20846                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20847                 if (tr == null) {
20848                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20849                 }
20850                 appThread = ApplicationThreadNative.asInterface(whoThread);
20851                 if (appThread == null) {
20852                     throw new IllegalArgumentException("Bad app thread " + appThread);
20853                 }
20854             }
20855             return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20856                     resolvedType, null, null, null, null, 0, 0, null, null,
20857                     null, options, false, callingUser, null, tr);
20858         }
20859
20860         @Override
20861         public void setExcludeFromRecents(boolean exclude) {
20862             checkCaller();
20863
20864             synchronized (ActivityManagerService.this) {
20865                 long origId = Binder.clearCallingIdentity();
20866                 try {
20867                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20868                     if (tr == null) {
20869                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20870                     }
20871                     Intent intent = tr.getBaseIntent();
20872                     if (exclude) {
20873                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20874                     } else {
20875                         intent.setFlags(intent.getFlags()
20876                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20877                     }
20878                 } finally {
20879                     Binder.restoreCallingIdentity(origId);
20880                 }
20881             }
20882         }
20883     }
20884 }