Send boot_completed for users started in the background

Bug: 14587584

Change-Id: I7abfad0a7102376e1665b528f3fd110a4b6ed164
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index cbb8377..b7ec283 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -16523,7 +16523,7 @@
                 }
 
                 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
-                    if (userId != 0) {
+                    if (userId != UserHandle.USER_OWNER) {
                         Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
                         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
                         broadcastIntentLocked(null, null, intent, null,
@@ -16552,6 +16552,8 @@
                     EventLogTags.writeAmSwitchUser(userId);
                     getUserManagerLocked().userForeground(userId);
                     sendUserSwitchBroadcastsLocked(oldUserId, userId);
+                } else {
+                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
                 }
 
                 if (needStart) {
@@ -16727,7 +16729,7 @@
         }
     }
 
-    void finishUserSwitch(UserStartedState uss) {
+    void finishUserBoot(UserStartedState uss) {
         synchronized (this) {
             if (uss.mState == UserStartedState.STATE_BOOTING
                     && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
@@ -16741,6 +16743,12 @@
                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
                         true, false, MY_PID, Process.SYSTEM_UID, userId);
             }
+        }
+    }
+
+    void finishUserSwitch(UserStartedState uss) {
+        synchronized (this) {
+            finishUserBoot(uss);
 
             startProfilesLocked();
 
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 2e979d2..899efbb 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -193,6 +193,9 @@
     /** Used on user changes */
     final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>();
 
+    /** Used to queue up any background users being started */
+    final ArrayList<UserStartedState> mStartingBackgroundUsers = new ArrayList<UserStartedState>();
+
     /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
      * is being brought in front of us. */
     boolean mUserLeaving = false;
@@ -1988,9 +1991,20 @@
 
         if (booting) {
             mService.finishBooting();
-        } else if (startingUsers != null) {
-            for (int i = 0; i < startingUsers.size(); i++) {
-                mService.finishUserSwitch(startingUsers.get(i));
+        } else {
+            // Complete user switch
+            if (startingUsers != null) {
+                for (int i = 0; i < startingUsers.size(); i++) {
+                    mService.finishUserSwitch(startingUsers.get(i));
+                }
+            }
+            // Complete starting up of background users
+            if (mStartingBackgroundUsers.size() > 0) {
+                startingUsers = new ArrayList<UserStartedState>(mStartingBackgroundUsers);
+                mStartingBackgroundUsers.clear();
+                for (int i = 0; i < startingUsers.size(); i++) {
+                    mService.finishUserBoot(startingUsers.get(i));
+                }
             }
         }
 
@@ -2496,6 +2510,15 @@
         return homeInFront;
     }
 
+    /**
+     * Add background users to send boot completed events to.
+     * @param userId The user being started in the background
+     * @param uss The state object for the user.
+     */
+    public void startBackgroundUserLocked(int userId, UserStartedState uss) {
+        mStartingBackgroundUsers.add(uss);
+    }
+
     final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
         int N = mStoppingActivities.size();
         if (N <= 0) return null;