Move shouldUseLauncherIcon to CarNotificationBodyView

This is to address the comments in ag/18875047, that is to move
shouldUseLauncherIcon method to CarNotificationBodyView.
Also moved loadAppLauncherIcon to the same class since the two
method use the same parameter.

Bug: 233552657
Test: Manual
Change-Id: I9db1db46089d0888efff27b80a45d7d5ccddfbc4
diff --git a/src/com/android/car/notification/NotificationUtils.java b/src/com/android/car/notification/NotificationUtils.java
index 9546724..8c3c8b0 100644
--- a/src/com/android/car/notification/NotificationUtils.java
+++ b/src/com/android/car/notification/NotificationUtils.java
@@ -28,8 +28,6 @@
 import android.service.notification.StatusBarNotification;
 import android.util.Log;
 
-import androidx.annotation.VisibleForTesting;
-
 import com.android.internal.graphics.ColorUtils;
 
 public class NotificationUtils {
@@ -41,15 +39,6 @@
     private static final float MAX_LIGHTNESS = 1;
     private static final float LIGHT_COLOR_LUMINANCE_THRESHOLD = 0.5f;
 
-    /**
-     * Key that system apps can add to the Notification extras to override the default
-     * {@link R.bool.config_useLauncherIcon} behavior. If this is set to false, a small and a large
-     * icon should be specified to be shown properly in the relevant default configuration.
-     */
-    @VisibleForTesting
-    static final String EXTRA_USE_LAUNCHER_ICON =
-            "com.android.car.notification.EXTRA_USE_LAUNCHER_ICON";
-
     private NotificationUtils() {
     }
 
@@ -167,22 +156,6 @@
         return Color.luminance(backgroundColor) > LIGHT_COLOR_LUMINANCE_THRESHOLD;
     }
 
-    /**
-     * Returns true if the launcher icon should be used for a given notification.
-     */
-    public static boolean shouldUseLauncherIcon(Context context, StatusBarNotification sbn) {
-        Bundle notificationExtras = sbn.getNotification().extras;
-        if (notificationExtras == null) {
-            return context.getResources().getBoolean(R.bool.config_useLauncherIcon);
-        }
-
-        if (notificationExtras.containsKey(EXTRA_USE_LAUNCHER_ICON)
-                && isSystemApp(context, sbn)) {
-            return notificationExtras.getBoolean(EXTRA_USE_LAUNCHER_ICON);
-        }
-        return context.getResources().getBoolean(R.bool.config_useLauncherIcon);
-    }
-
     private static boolean isSystemPrivilegedOrPlatformKeyInner(Context context,
             AlertEntry alertEntry, boolean checkForPrivilegedApp) {
         PackageInfo packageInfo = getPackageInfo(context, alertEntry.getStatusBarNotification());
diff --git a/src/com/android/car/notification/template/BasicNotificationViewHolder.java b/src/com/android/car/notification/template/BasicNotificationViewHolder.java
index 9343a44..9ab418b 100644
--- a/src/com/android/car/notification/template/BasicNotificationViewHolder.java
+++ b/src/com/android/car/notification/template/BasicNotificationViewHolder.java
@@ -21,7 +21,6 @@
 
 import com.android.car.notification.AlertEntry;
 import com.android.car.notification.NotificationClickHandlerFactory;
-import com.android.car.notification.NotificationUtils;
 import com.android.car.notification.R;
 
 /**
@@ -62,10 +61,8 @@
         Bundle extraData = notification.extras;
         CharSequence title = extraData.getCharSequence(Notification.EXTRA_TITLE);
         CharSequence text = extraData.getCharSequence(Notification.EXTRA_TEXT);
-        boolean useLauncherIcon = NotificationUtils.shouldUseLauncherIcon(getContext(),
-                alertEntry.getStatusBarNotification());
-        mBodyView.bind(title, text, useLauncherIcon,
-                loadAppLauncherIcon(alertEntry.getStatusBarNotification()),
+        mBodyView.bind(title, text,
+                alertEntry.getStatusBarNotification(),
                 notification.getLargeIcon(), /* titleIcon= */ null, /* countText= */ null,
                 notification.showsTime() ? notification.when : null);
     }
diff --git a/src/com/android/car/notification/template/CallNotificationViewHolder.java b/src/com/android/car/notification/template/CallNotificationViewHolder.java
index 53365e7..478d8bf 100644
--- a/src/com/android/car/notification/template/CallNotificationViewHolder.java
+++ b/src/com/android/car/notification/template/CallNotificationViewHolder.java
@@ -21,7 +21,6 @@
 
 import com.android.car.notification.AlertEntry;
 import com.android.car.notification.NotificationClickHandlerFactory;
-import com.android.car.notification.NotificationUtils;
 import com.android.car.notification.R;
 
 /**
@@ -62,10 +61,8 @@
         Bundle extraData = notification.extras;
         CharSequence title = extraData.getCharSequence(Notification.EXTRA_TITLE);
         CharSequence text = extraData.getCharSequence(Notification.EXTRA_TEXT);
-        boolean useLauncherIcon = NotificationUtils.shouldUseLauncherIcon(getContext(),
-                alertEntry.getStatusBarNotification());
-        mBodyView.bind(title, text, useLauncherIcon,
-                loadAppLauncherIcon(alertEntry.getStatusBarNotification()),
+        mBodyView.bind(title, text,
+                alertEntry.getStatusBarNotification(),
                 notification.getLargeIcon(), /* titleIcon= */ null, /* countText= */ null,
                 notification.showsTime() ? notification.when : null);
     }
diff --git a/src/com/android/car/notification/template/CarNotificationBaseViewHolder.java b/src/com/android/car/notification/template/CarNotificationBaseViewHolder.java
index f335a6e..77c049b 100644
--- a/src/com/android/car/notification/template/CarNotificationBaseViewHolder.java
+++ b/src/com/android/car/notification/template/CarNotificationBaseViewHolder.java
@@ -21,9 +21,6 @@
 import android.annotation.Nullable;
 import android.app.Notification;
 import android.content.Context;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.Drawable;
-import android.service.notification.StatusBarNotification;
 import android.view.View;
 import android.view.ViewTreeObserver;
 import android.widget.ImageButton;
@@ -167,7 +164,7 @@
         bindBody(mBodyView, isInGroup);
     }
 
-    Context getContext() {
+    protected final Context getContext() {
         return mContext;
     }
 
@@ -407,14 +404,4 @@
     View.OnClickListener getDismissHandler(AlertEntry alertEntry) {
         return mClickHandlerFactory.getDismissHandler(alertEntry);
     }
-
-    @Nullable
-    Drawable loadAppLauncherIcon(StatusBarNotification sbn) {
-        if (!NotificationUtils.shouldUseLauncherIcon(mContext, sbn)) {
-            return null;
-        }
-        Context packageContext = sbn.getPackageContext(mContext);
-        PackageManager pm = packageContext.getPackageManager();
-        return pm.getApplicationIcon(packageContext.getApplicationInfo());
-    }
 }
diff --git a/src/com/android/car/notification/template/CarNotificationBodyView.java b/src/com/android/car/notification/template/CarNotificationBodyView.java
index 29ac116..ef98b5f 100644
--- a/src/com/android/car/notification/template/CarNotificationBodyView.java
+++ b/src/com/android/car/notification/template/CarNotificationBodyView.java
@@ -19,11 +19,14 @@
 import android.annotation.ColorInt;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
+import android.service.notification.StatusBarNotification;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -54,6 +57,15 @@
     private final int mDefaultSecondaryTextColor;
     private final boolean mDefaultUseLauncherIcon;
 
+    /**
+     * Key that system apps can add to the Notification extras to override the default
+     * {@link R.bool.config_useLauncherIcon} behavior. If this is set to false, a small and a large
+     * icon should be specified to be shown properly in the relevant default configuration.
+     */
+    @VisibleForTesting
+    static final String EXTRA_USE_LAUNCHER_ICON =
+            "com.android.car.notification.EXTRA_USE_LAUNCHER_ICON";
+
     private boolean mIsHeadsUp;
     private boolean mShowBigIcon;
     private int mMaxLines;
@@ -139,11 +151,13 @@
      * @param countText text signifying the number of messages inside this notification
      * @param when      wall clock time in milliseconds for the notification
      */
-    public void bind(CharSequence title, @Nullable CharSequence content, boolean useLauncherIcon,
-            @Nullable Drawable launcherIcon, @Nullable Icon largeIcon, @Nullable Drawable titleIcon,
+    public void bind(CharSequence title, @Nullable CharSequence content,
+            StatusBarNotification sbn, @Nullable Icon largeIcon, @Nullable Drawable titleIcon,
             @Nullable CharSequence countText, @Nullable Long when) {
         setVisibility(View.VISIBLE);
 
+        boolean useLauncherIcon = setUseLauncherIcon(sbn);
+        Drawable launcherIcon = loadAppLauncherIcon(sbn);
         if (mLargeIconView != null) {
             if (useLauncherIcon && launcherIcon != null) {
                 mLargeIconView.setVisibility(View.VISIBLE);
@@ -221,7 +235,6 @@
         }
     }
 
-
     /**
      * Sets the secondary text color.
      */
@@ -291,6 +304,32 @@
         }
     }
 
+    /**
+     * Returns true if the launcher icon should be used for a given notification.
+     */
+    private boolean setUseLauncherIcon(StatusBarNotification sbn) {
+        Bundle notificationExtras = sbn.getNotification().extras;
+        if (notificationExtras == null) {
+            return getContext().getResources().getBoolean(R.bool.config_useLauncherIcon);
+        }
+
+        if (notificationExtras.containsKey(EXTRA_USE_LAUNCHER_ICON)
+                && NotificationUtils.isSystemApp(getContext(), sbn)) {
+            return notificationExtras.getBoolean(EXTRA_USE_LAUNCHER_ICON);
+        }
+        return getContext().getResources().getBoolean(R.bool.config_useLauncherIcon);
+    }
+
+    @Nullable
+    private Drawable loadAppLauncherIcon(StatusBarNotification sbn) {
+        if (!setUseLauncherIcon(sbn)) {
+            return null;
+        }
+        Context packageContext = sbn.getPackageContext(getContext());
+        PackageManager pm = packageContext.getPackageManager();
+        return pm.getApplicationIcon(packageContext.getApplicationInfo());
+    }
+
     @VisibleForTesting
     TextView getTitleView() {
         return mTitleView;
diff --git a/src/com/android/car/notification/template/EmergencyNotificationViewHolder.java b/src/com/android/car/notification/template/EmergencyNotificationViewHolder.java
index bee10d0..b313b8a 100644
--- a/src/com/android/car/notification/template/EmergencyNotificationViewHolder.java
+++ b/src/com/android/car/notification/template/EmergencyNotificationViewHolder.java
@@ -24,7 +24,6 @@
 
 import com.android.car.notification.AlertEntry;
 import com.android.car.notification.NotificationClickHandlerFactory;
-import com.android.car.notification.NotificationUtils;
 import com.android.car.notification.R;
 
 /**
@@ -73,11 +72,9 @@
         Bundle extraData = notification.extras;
         CharSequence title = extraData.getCharSequence(Notification.EXTRA_TITLE);
         CharSequence text = extraData.getCharSequence(Notification.EXTRA_TEXT);
-        boolean useLauncherIcon = NotificationUtils.shouldUseLauncherIcon(getContext(),
-                alertEntry.getStatusBarNotification());
 
-        mBodyView.bind(title, text, useLauncherIcon,
-                loadAppLauncherIcon(alertEntry.getStatusBarNotification()),
+        mBodyView.bind(title, text,
+                alertEntry.getStatusBarNotification(),
                 notification.getLargeIcon(), /* titleIcon= */ null, /* countText= */ null,
                 notification.showsTime() ? notification.when : null);
     }
diff --git a/src/com/android/car/notification/template/InboxNotificationViewHolder.java b/src/com/android/car/notification/template/InboxNotificationViewHolder.java
index 247860e..85f1a22 100644
--- a/src/com/android/car/notification/template/InboxNotificationViewHolder.java
+++ b/src/com/android/car/notification/template/InboxNotificationViewHolder.java
@@ -21,7 +21,6 @@
 
 import com.android.car.notification.AlertEntry;
 import com.android.car.notification.NotificationClickHandlerFactory;
-import com.android.car.notification.NotificationUtils;
 import com.android.car.notification.R;
 
 /**
@@ -63,11 +62,9 @@
         Bundle extraData = notification.extras;
         CharSequence title = extraData.getCharSequence(Notification.EXTRA_TITLE_BIG);
         CharSequence text = extraData.getCharSequence(Notification.EXTRA_SUMMARY_TEXT);
-        boolean useLauncherIcon = NotificationUtils.shouldUseLauncherIcon(getContext(),
-                alertEntry.getStatusBarNotification());
 
-        mBodyView.bind(title, text, useLauncherIcon,
-                loadAppLauncherIcon(alertEntry.getStatusBarNotification()),
+        mBodyView.bind(title, text,
+                alertEntry.getStatusBarNotification(),
                 notification.getLargeIcon(), /* titleIcon= */ null, /* countText= */ null,
                 notification.showsTime() ? notification.when : null);
     }
diff --git a/src/com/android/car/notification/template/MessageNotificationViewHolder.java b/src/com/android/car/notification/template/MessageNotificationViewHolder.java
index 54efd59..f854e10 100644
--- a/src/com/android/car/notification/template/MessageNotificationViewHolder.java
+++ b/src/com/android/car/notification/template/MessageNotificationViewHolder.java
@@ -34,7 +34,6 @@
 
 import com.android.car.notification.AlertEntry;
 import com.android.car.notification.NotificationClickHandlerFactory;
-import com.android.car.notification.NotificationUtils;
 import com.android.car.notification.PreprocessingManager;
 import com.android.car.notification.R;
 
@@ -226,11 +225,8 @@
                             sbn, conversationTitle, avatar, groupIcon, when);
             mBodyView.setCountOnClickListener(listener);
         }
-        boolean useLauncherIcon = NotificationUtils.shouldUseLauncherIcon(getContext(), sbn);
-
-        mBodyView.bind(conversationTitle, messageText, useLauncherIcon,
-                loadAppLauncherIcon(sbn), avatar, groupIcon,
-                unshownCountText, when);
+        mBodyView.bind(conversationTitle, messageText,
+                sbn, avatar, groupIcon, unshownCountText, when);
     }
 
     private CharSequence getMessageText(Notification.MessagingStyle.Message message,
@@ -400,10 +396,7 @@
                         R.plurals.message_unshown_count, finalUnshownCount, finalUnshownCount);
             }
 
-            Drawable launcherIcon = loadAppLauncherIcon(sbn);
-            boolean useLauncherIcon = NotificationUtils.shouldUseLauncherIcon(getContext(),
-                    sbn);
-            mBodyView.bind(title, finalMessage, useLauncherIcon, launcherIcon, avatar, groupIcon,
+            mBodyView.bind(title, finalMessage, sbn, avatar, groupIcon,
                     unshownCountText, when);
             mBodyView.setContentMaxLines(mMaxLineCount);
             mBodyView.setCountOnClickListener(null);
diff --git a/src/com/android/car/notification/template/NavigationNotificationViewHolder.java b/src/com/android/car/notification/template/NavigationNotificationViewHolder.java
index 605b72e..74d7fea 100644
--- a/src/com/android/car/notification/template/NavigationNotificationViewHolder.java
+++ b/src/com/android/car/notification/template/NavigationNotificationViewHolder.java
@@ -21,7 +21,6 @@
 
 import com.android.car.notification.AlertEntry;
 import com.android.car.notification.NotificationClickHandlerFactory;
-import com.android.car.notification.NotificationUtils;
 import com.android.car.notification.R;
 
 /**
@@ -62,11 +61,8 @@
         Bundle extraData = notification.extras;
         CharSequence title = extraData.getCharSequence(Notification.EXTRA_TITLE);
         CharSequence text = extraData.getCharSequence(Notification.EXTRA_TEXT);
-        boolean useLauncherIcon = NotificationUtils.shouldUseLauncherIcon(getContext(),
-                alertEntry.getStatusBarNotification());
 
-        mBodyView.bind(title, text, useLauncherIcon,
-                loadAppLauncherIcon(alertEntry.getStatusBarNotification()),
+        mBodyView.bind(title, text, alertEntry.getStatusBarNotification(),
                 notification.getLargeIcon(), /* titleIcon= */ null, /* countText= */ null,
                 notification.showsTime() ? notification.when : null);
     }
diff --git a/src/com/android/car/notification/template/ProgressNotificationViewHolder.java b/src/com/android/car/notification/template/ProgressNotificationViewHolder.java
index d29fe65..499ba89 100644
--- a/src/com/android/car/notification/template/ProgressNotificationViewHolder.java
+++ b/src/com/android/car/notification/template/ProgressNotificationViewHolder.java
@@ -73,11 +73,9 @@
         Bundle extraData = notification.extras;
         CharSequence title = extraData.getCharSequence(Notification.EXTRA_TITLE);
         CharSequence text = extraData.getCharSequence(Notification.EXTRA_TEXT);
-        boolean useLauncherIcon = NotificationUtils.shouldUseLauncherIcon(getContext(),
-                alertEntry.getStatusBarNotification());
 
-        mBodyView.bind(title, text, useLauncherIcon,
-                loadAppLauncherIcon(alertEntry.getStatusBarNotification()),
+        mBodyView.bind(title, text,
+                alertEntry.getStatusBarNotification(),
                 notification.getLargeIcon(), /* titleIcon= */ null, /* countText= */ null,
                 notification.showsTime() ? notification.when : null);
 
diff --git a/tests/unit/src/com/android/car/notification/NotificationUtilsTest.java b/tests/unit/src/com/android/car/notification/NotificationUtilsTest.java
index ac12172..24fd62d 100644
--- a/tests/unit/src/com/android/car/notification/NotificationUtilsTest.java
+++ b/tests/unit/src/com/android/car/notification/NotificationUtilsTest.java
@@ -187,50 +187,6 @@
                 .isFalse();
     }
 
-
-    @Test
-    public void onShouldUseLauncherIcon_noExtras_returnsDefault()
-            throws PackageManager.NameNotFoundException {
-        setApplicationInfo(/* signedWithPlatformKey= */ false, /* isSystemApp= */
-                true, /* isPrivilegedApp= */ false);
-        Notification notification = new Notification();
-        notification.extras = new Bundle();
-        when(mStatusBarNotification.getNotification()).thenReturn(notification);
-
-        assertThat(NotificationUtils.shouldUseLauncherIcon(mContext, mStatusBarNotification))
-                .isTrue();
-    }
-
-    @Test
-    public void onShouldUseLauncherIcon_notSystemApp_returnsDefault()
-            throws PackageManager.NameNotFoundException {
-        setApplicationInfo(/* signedWithPlatformKey= */ false, /* isSystemApp= */
-                false, /* isPrivilegedApp= */ false);
-        Notification notification = new Notification();
-        notification.extras = new Bundle();
-        notification.extras.putBoolean(
-                NotificationUtils.EXTRA_USE_LAUNCHER_ICON, false);
-        when(mStatusBarNotification.getNotification()).thenReturn(notification);
-
-        assertThat(NotificationUtils.shouldUseLauncherIcon(mContext, mStatusBarNotification))
-                .isTrue();
-    }
-
-    @Test
-    public void onShouldUseLauncherIcon_systemApp_returnsExtra()
-            throws PackageManager.NameNotFoundException {
-        setApplicationInfo(/* signedWithPlatformKey= */ false, /* isSystemApp= */
-                true, /* isPrivilegedApp= */ false);
-        Notification notification = new Notification();
-        notification.extras = new Bundle();
-        notification.extras.putBoolean(
-                NotificationUtils.EXTRA_USE_LAUNCHER_ICON, false);
-        when(mStatusBarNotification.getNotification()).thenReturn(notification);
-
-        assertThat(NotificationUtils.shouldUseLauncherIcon(mContext, mStatusBarNotification))
-                .isFalse();
-    }
-
     @Test
     public void onGetNotificationViewType_notificationIsARecognizedType_returnsCorrectType() {
         Map<String, CarNotificationTypeItem> typeMap = new HashMap<>();
diff --git a/tests/unit/src/com/android/car/notification/template/CarNotificationBodyViewTest.java b/tests/unit/src/com/android/car/notification/template/CarNotificationBodyViewTest.java
index 9001e60..f6c5406 100644
--- a/tests/unit/src/com/android/car/notification/template/CarNotificationBodyViewTest.java
+++ b/tests/unit/src/com/android/car/notification/template/CarNotificationBodyViewTest.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.ShapeDrawable;
+import android.service.notification.StatusBarNotification;
 
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -28,6 +29,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
 import java.util.Calendar;
@@ -43,6 +45,8 @@
 
     private CarNotificationBodyView mCarNotificationBodyView;
     private Context mContext;
+    @Mock
+    private StatusBarNotification mMockStatusBarNotification;
 
     @Before
     public void setup() {
@@ -54,8 +58,8 @@
 
     @Test
     public void onBind_launcherIconUsed_titleTextSet() {
-        mCarNotificationBodyView.bind(TEST_TITLE, TEST_BODY, /* useLauncherIcon= */ true,
-                TEST_DRAWABLE, /* largeIcon= */ null, /* titleIcon= */ null,
+        mCarNotificationBodyView.bind(TEST_TITLE, TEST_BODY, mMockStatusBarNotification,
+            /* largeIcon= */ null, /* titleIcon= */ null,
                 TEST_COUNT, TEST_WHEN);
 
         assertThat(mCarNotificationBodyView.getTitleView().getText()).isEqualTo(TEST_TITLE);
@@ -63,8 +67,8 @@
 
     @Test
     public void onBind_launcherIconUsed_contentTextSet() {
-        mCarNotificationBodyView.bind(TEST_TITLE, TEST_BODY, /* useLauncherIcon= */ true,
-                TEST_DRAWABLE, /* largeIcon= */ null, /* titleIcon= */ null,
+        mCarNotificationBodyView.bind(TEST_TITLE, TEST_BODY, mMockStatusBarNotification,
+            /* largeIcon= */ null, /* titleIcon= */ null,
                 TEST_COUNT, TEST_WHEN);
 
         assertThat(mCarNotificationBodyView.getContentView().getText()).isEqualTo(TEST_BODY);
@@ -72,8 +76,8 @@
 
     @Test
     public void onBind_launcherIconUsed_countTextSet() {
-        mCarNotificationBodyView.bind(TEST_TITLE, TEST_BODY, /* useLauncherIcon= */ true,
-                TEST_DRAWABLE, /* largeIcon= */ null, /* titleIcon= */ null,
+        mCarNotificationBodyView.bind(TEST_TITLE, TEST_BODY, mMockStatusBarNotification,
+            /* largeIcon= */ null, /* titleIcon= */ null,
                 TEST_COUNT, TEST_WHEN);
 
         assertThat(mCarNotificationBodyView.getCountView().getText()).isEqualTo(TEST_COUNT);
@@ -81,8 +85,8 @@
 
     @Test
     public void onBind_launcherIconUsed_timeSet() {
-        mCarNotificationBodyView.bind(TEST_TITLE, TEST_BODY, /* useLauncherIcon= */ true,
-                TEST_DRAWABLE, /* largeIcon= */ null, /* titleIcon= */ null,
+        mCarNotificationBodyView.bind(TEST_TITLE, TEST_BODY, mMockStatusBarNotification,
+            /* largeIcon= */ null, /* titleIcon= */ null,
                 TEST_COUNT, TEST_WHEN);
 
         assertThat(mCarNotificationBodyView.getTimeView().getText()).isEqualTo(EXPECTED_WHEN);