Create all notification channels on boot

Previously, channels would only be created when the first notification
was sent to that user.

Bug: 265277413
Test: Manually, checking both personal and work profile
Change-Id: I7fe5e2e0c86bad3a9501a71bd869b2909a4eab1d
diff --git a/service/java/com/android/safetycenter/SafetyCenterNotificationChannels.java b/service/java/com/android/safetycenter/SafetyCenterNotificationChannels.java
index 024b2cd..59a9cc9 100644
--- a/service/java/com/android/safetycenter/SafetyCenterNotificationChannels.java
+++ b/service/java/com/android/safetycenter/SafetyCenterNotificationChannels.java
@@ -22,15 +22,20 @@
 import android.app.NotificationChannel;
 import android.app.NotificationChannelGroup;
 import android.app.NotificationManager;
+import android.content.Context;
 import android.os.Binder;
+import android.os.UserHandle;
 import android.safetycenter.SafetySourceData;
 import android.safetycenter.SafetySourceIssue;
 import android.util.Log;
 
 import androidx.annotation.RequiresApi;
 
+import com.android.permission.util.UserUtils;
 import com.android.safetycenter.resources.SafetyCenterResourcesContext;
 
+import java.util.List;
+
 /** Class responsible for creating and updating Safety Center's notification channels. */
 @RequiresApi(TIRAMISU)
 final class SafetyCenterNotificationChannels {
@@ -48,6 +53,14 @@
         mResourcesContext = safetyCenterResourceContext;
     }
 
+    /** Returns a {@link NotificationManager} which will send notifications to the given user. */
+    @Nullable
+    static NotificationManager getNotificationManagerForUser(
+            Context baseContext, UserHandle userHandle) {
+        Context contextAsUser = baseContext.createContextAsUser(userHandle, 0);
+        return contextAsUser.getSystemService(NotificationManager.class);
+    }
+
     /**
      * Returns the ID of the appropriate {@link NotificationChannel} for a notification about the
      * given {@code issue} after ensuring that channel has been created.
@@ -63,6 +76,23 @@
         return getChannelIdForIssue(issue);
     }
 
+    /**
+     * Creates all Safety Center {@link NotificationChannel}s instances and their group, for all
+     * current users, dropping any calling identity so those channels can be unblockable. Throws a
+     * {@link RuntimeException} if any channel is malformed and could not be created.
+     */
+    void createAllChannelsForAllUsers(Context context) {
+        List<UserHandle> users = UserUtils.getUserHandles(context);
+        for (int i = 0; i < users.size(); i++) {
+            try {
+                createAllChannelsWithoutCallingIdentity(
+                        getNotificationManagerForUser(context, users.get(i)));
+            } catch (RuntimeException e) {
+                Log.w(TAG, "Unable to create notification channels", e);
+            }
+        }
+    }
+
     @Nullable
     private String getChannelIdForIssue(SafetySourceIssue issue) {
         switch (issue.getSeverityLevel()) {
diff --git a/service/java/com/android/safetycenter/SafetyCenterNotificationSender.java b/service/java/com/android/safetycenter/SafetyCenterNotificationSender.java
index debc108..24eb304 100644
--- a/service/java/com/android/safetycenter/SafetyCenterNotificationSender.java
+++ b/service/java/com/android/safetycenter/SafetyCenterNotificationSender.java
@@ -311,9 +311,9 @@
 
     /** Returns a {@link NotificationManager} which will send notifications to the given user. */
     @Nullable
-    private NotificationManager getNotificationManagerForUser(@UserIdInt int recipientUserId) {
-        Context contextAsUser = mContext.createContextAsUser(UserHandle.of(recipientUserId), 0);
-        return contextAsUser.getSystemService(NotificationManager.class);
+    private NotificationManager getNotificationManagerForUser(@UserIdInt int userId) {
+        return SafetyCenterNotificationChannels.getNotificationManagerForUser(
+                mContext, UserHandle.of(userId));
     }
 
     /**
diff --git a/service/java/com/android/safetycenter/SafetyCenterService.java b/service/java/com/android/safetycenter/SafetyCenterService.java
index 414383e..d2d62d3 100644
--- a/service/java/com/android/safetycenter/SafetyCenterService.java
+++ b/service/java/com/android/safetycenter/SafetyCenterService.java
@@ -110,6 +110,8 @@
 
     private final SafetyCenterResourcesContext mSafetyCenterResourcesContext;
 
+    private final SafetyCenterNotificationChannels mNotificationChannels;
+
     @GuardedBy("mApiLock")
     private final SafetyCenterConfigReader mSafetyCenterConfigReader;
 
@@ -156,13 +158,12 @@
                         new PendingIntentFactory(context, mSafetyCenterResourcesContext),
                         mSafetyCenterDataManager);
         mSafetyCenterListeners = new SafetyCenterListeners(mSafetyCenterDataFactory);
+        mNotificationChannels = new SafetyCenterNotificationChannels(mSafetyCenterResourcesContext);
         mNotificationSender =
                 new SafetyCenterNotificationSender(
                         context,
                         new SafetyCenterNotificationFactory(
-                                context,
-                                new SafetyCenterNotificationChannels(mSafetyCenterResourcesContext),
-                                mSafetyCenterResourcesContext),
+                                context, mNotificationChannels, mSafetyCenterResourcesContext),
                         mSafetyCenterDataManager);
         mSafetyCenterBroadcastDispatcher =
                 new SafetyCenterBroadcastDispatcher(
@@ -216,6 +217,7 @@
         if (phase == SystemService.PHASE_BOOT_COMPLETED && canUseSafetyCenter()) {
             registerSafetyCenterEnabledListener();
             registerSafetyCenterPullAtomCallback();
+            mNotificationChannels.createAllChannelsForAllUsers(getContext());
         }
     }