Create CarAppExtender#extend(android.app.Notification.Builder)

This is in addition to the existing
`#extend(androidx.core.app.NotificationCompat.Builder)` method to allow
either compat or android native objects to be extended.

Bug: 360440608
Fixes: 360440608
Test: ./gradlew :car:app:app:test
Relnote: "CarAppExtender can now be used to extend plain Android
notifications instead of only NotificationCompat"

Change-Id: Id3ad735f9de699c6a6d69bdd2349f4920570c4b4
diff --git a/car/app/app/api/1.7.0-beta02.txt b/car/app/app/api/1.7.0-beta02.txt
index e6d983b..425e393 100644
--- a/car/app/app/api/1.7.0-beta02.txt
+++ b/car/app/app/api/1.7.0-beta02.txt
@@ -2316,6 +2316,7 @@
 
   public final class CarAppExtender implements androidx.core.app.NotificationCompat.Extender {
     ctor public CarAppExtender(android.app.Notification);
+    method public android.app.Notification.Builder extend(android.app.Notification.Builder);
     method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Builder);
     method public java.util.List<android.app.Notification.Action!> getActions();
     method public String? getChannelId();
diff --git a/car/app/app/api/current.ignore b/car/app/app/api/current.ignore
index ce589b6..3ef9479 100644
--- a/car/app/app/api/current.ignore
+++ b/car/app/app/api/current.ignore
@@ -1,3 +1,3 @@
 // Baseline format: 1.0
-ChangedValue: androidx.car.app.features.CarFeatures#FEATURE_BACKGROUND_AUDIO_WHILE_DRIVING:
-    Field androidx.car.app.features.CarFeatures.FEATURE_BACKGROUND_AUDIO_WHILE_DRIVING has changed value from background_audio_while_driving to com.android.car.background_audio_while_driving
+AddedMethod: androidx.car.app.notification.CarAppExtender#extend(android.app.Notification.Builder):
+    Added method androidx.car.app.notification.CarAppExtender.extend(android.app.Notification.Builder)
diff --git a/car/app/app/api/current.txt b/car/app/app/api/current.txt
index e6d983b..425e393 100644
--- a/car/app/app/api/current.txt
+++ b/car/app/app/api/current.txt
@@ -2316,6 +2316,7 @@
 
   public final class CarAppExtender implements androidx.core.app.NotificationCompat.Extender {
     ctor public CarAppExtender(android.app.Notification);
+    method public android.app.Notification.Builder extend(android.app.Notification.Builder);
     method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Builder);
     method public java.util.List<android.app.Notification.Action!> getActions();
     method public String? getChannelId();
diff --git a/car/app/app/api/restricted_1.7.0-beta02.txt b/car/app/app/api/restricted_1.7.0-beta02.txt
index e6d983b..425e393 100644
--- a/car/app/app/api/restricted_1.7.0-beta02.txt
+++ b/car/app/app/api/restricted_1.7.0-beta02.txt
@@ -2316,6 +2316,7 @@
 
   public final class CarAppExtender implements androidx.core.app.NotificationCompat.Extender {
     ctor public CarAppExtender(android.app.Notification);
+    method public android.app.Notification.Builder extend(android.app.Notification.Builder);
     method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Builder);
     method public java.util.List<android.app.Notification.Action!> getActions();
     method public String? getChannelId();
diff --git a/car/app/app/api/restricted_current.ignore b/car/app/app/api/restricted_current.ignore
index ce589b6..3ef9479 100644
--- a/car/app/app/api/restricted_current.ignore
+++ b/car/app/app/api/restricted_current.ignore
@@ -1,3 +1,3 @@
 // Baseline format: 1.0
-ChangedValue: androidx.car.app.features.CarFeatures#FEATURE_BACKGROUND_AUDIO_WHILE_DRIVING:
-    Field androidx.car.app.features.CarFeatures.FEATURE_BACKGROUND_AUDIO_WHILE_DRIVING has changed value from background_audio_while_driving to com.android.car.background_audio_while_driving
+AddedMethod: androidx.car.app.notification.CarAppExtender#extend(android.app.Notification.Builder):
+    Added method androidx.car.app.notification.CarAppExtender.extend(android.app.Notification.Builder)
diff --git a/car/app/app/api/restricted_current.txt b/car/app/app/api/restricted_current.txt
index e6d983b..425e393 100644
--- a/car/app/app/api/restricted_current.txt
+++ b/car/app/app/api/restricted_current.txt
@@ -2316,6 +2316,7 @@
 
   public final class CarAppExtender implements androidx.core.app.NotificationCompat.Extender {
     ctor public CarAppExtender(android.app.Notification);
+    method public android.app.Notification.Builder extend(android.app.Notification.Builder);
     method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Builder);
     method public java.util.List<android.app.Notification.Action!> getActions();
     method public String? getChannelId();
diff --git a/car/app/app/src/main/java/androidx/car/app/notification/CarAppExtender.java b/car/app/app/src/main/java/androidx/car/app/notification/CarAppExtender.java
index 50ee879..7f67f8c9 100644
--- a/car/app/app/src/main/java/androidx/car/app/notification/CarAppExtender.java
+++ b/car/app/app/src/main/java/androidx/car/app/notification/CarAppExtender.java
@@ -218,8 +218,9 @@
     /**
      * Applies car extensions to a notification that is being built.
      *
-     * <p>This is typically called by
-     * {@link NotificationCompat.Builder#extend(NotificationCompat.Extender)}.
+     * <p>This is automatically called when the style is applied to the builder via {@link
+     * NotificationCompat.Builder#extend(NotificationCompat.Extender)} so this method does not need
+     * to be manually called.
      *
      * @throws NullPointerException if {@code builder} is {@code null}
      */
@@ -227,6 +228,31 @@
     @Override
     public NotificationCompat.Builder extend(@NonNull NotificationCompat.Builder builder) {
         requireNonNull(builder);
+        Bundle carExtensions = createExtrasBundle();
+        builder.getExtras().putBundle(EXTRA_CAR_EXTENDER, carExtensions);
+        return builder;
+    }
+
+    /**
+     * Applies car extensions to a notification that is being built.
+     *
+     * <p>For the most part, developers should be building notifications via {@link
+     * NotificationCompat.Builder} and not {@link Notification.Builder}; however, there may be
+     * reasons to not use the compat version, so this non-compat method is provided for convenience
+     * in those situations.
+     *
+     * @throws NullPointerException if {@code builder} is {@code null}
+     */
+    @NonNull
+    public Notification.Builder extend(@NonNull Notification.Builder builder) {
+        requireNonNull(builder);
+        Bundle carExtensions = createExtrasBundle();
+        builder.getExtras().putBundle(EXTRA_CAR_EXTENDER, carExtensions);
+        return builder;
+    }
+
+    @NonNull
+    private Bundle createExtrasBundle() {
         Bundle carExtensions = new Bundle();
 
         if (mContentTitle != null) {
@@ -272,8 +298,7 @@
             carExtensions.putString(EXTRA_CHANNEL_ID, mChannelId);
         }
 
-        builder.getExtras().putBundle(EXTRA_CAR_EXTENDER, carExtensions);
-        return builder;
+        return carExtensions;
     }
 
     /**
diff --git a/car/app/app/src/test/java/androidx/car/app/notification/CarAppExtenderTest.java b/car/app/app/src/test/java/androidx/car/app/notification/CarAppExtenderTest.java
index 7d59e0c..c810964 100644
--- a/car/app/app/src/test/java/androidx/car/app/notification/CarAppExtenderTest.java
+++ b/car/app/app/src/test/java/androidx/car/app/notification/CarAppExtenderTest.java
@@ -18,6 +18,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import android.app.Notification;
 import android.app.Notification.Action;
 import android.app.PendingIntent;
 import android.content.Context;
@@ -253,4 +254,43 @@
         assertThat(new CarAppExtender(builder.build()).getChannelId())
                 .isEqualTo(channelId);
     }
+
+    @Test
+    @SuppressWarnings("deprecation") // Required for Notification.Builder(Context)
+    public void extend_withNonCompatNotification_hasExtras() {
+        CarAppExtender extender =
+                new CarAppExtender.Builder()
+                        .setContentTitle("Some title")
+                        .setContentText("Some text")
+                        .setSmallIcon(TestUtils.getTestDrawableResId(mContext, "ic_test_1"))
+                        .setLargeIcon(
+                                BitmapFactory.decodeResource(mContext.getResources(),
+                                        TestUtils.getTestDrawableResId(mContext, "ic_test_2")))
+                        .setContentIntent(PendingIntent.getBroadcast(mContext, 0, new Intent(), 0))
+                        .setDeleteIntent(PendingIntent.getBroadcast(mContext, 0, new Intent(), 0))
+                        .addAction(
+                                TestUtils.getTestDrawableResId(mContext, "ic_test_1"),
+                                "Title",
+                                PendingIntent.getBroadcast(mContext, 0, new Intent(), 0))
+                        .setImportance(NotificationManagerCompat.IMPORTANCE_MAX)
+                        .setColor(CarColor.BLUE)
+                        .setChannelId("Some id")
+                        .build();
+
+        Notification.Builder plainAndroidNotificationBuilder = new Notification.Builder(mContext);
+        extender.extend(plainAndroidNotificationBuilder);
+
+        Notification resultNotification = plainAndroidNotificationBuilder.build();
+        CarAppExtender resultExtender = new CarAppExtender(resultNotification);
+
+        assertThat(resultExtender.getContentTitle()).isEqualTo(extender.getContentTitle());
+        assertThat(resultExtender.getContentText()).isEqualTo(extender.getContentText());
+        assertThat(resultExtender.getSmallIcon()).isEqualTo(extender.getSmallIcon());
+        assertThat(resultExtender.getContentIntent()).isNotNull();
+        assertThat(resultExtender.getDeleteIntent()).isNotNull();
+        assertThat(resultExtender.getActions()).hasSize(1);
+        assertThat(resultExtender.getImportance()).isEqualTo(extender.getImportance());
+        assertThat(resultExtender.getColor()).isEqualTo(extender.getColor());
+        assertThat(resultExtender.getChannelId()).isEqualTo(extender.getChannelId());
+    }
 }