Merge "Notif redesign: Show small icon for headless system apps" into main
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowModule.java
index 43ade5c..4feb78a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowModule.java
@@ -18,6 +18,7 @@
 
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.statusbar.notification.row.icon.AppIconProviderModule;
+import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProviderModule;
 import com.android.systemui.statusbar.notification.row.shared.NotificationRowContentBinderRefactor;
 
 import dagger.Binds;
@@ -29,7 +30,7 @@
 /**
  * Dagger Module containing notification row and view inflation implementations.
  */
-@Module(includes = {AppIconProviderModule.class})
+@Module(includes = {AppIconProviderModule.class, NotificationIconStyleProviderModule.class})
 public abstract class NotificationRowModule {
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationIconStyleProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationIconStyleProvider.kt
new file mode 100644
index 0000000..165c1a7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationIconStyleProvider.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.row.icon
+
+import android.annotation.WorkerThread
+import android.app.Flags
+import android.content.Context
+import android.content.pm.ApplicationInfo
+import android.service.notification.StatusBarNotification
+import android.util.Log
+import com.android.systemui.dagger.SysUISingleton
+import dagger.Module
+import dagger.Provides
+import javax.inject.Inject
+import javax.inject.Provider
+
+/**
+ * A provider used to cache and fetch information about which icon should be displayed by
+ * notifications.
+ */
+interface NotificationIconStyleProvider {
+    @WorkerThread
+    fun shouldShowAppIcon(notification: StatusBarNotification, context: Context): Boolean
+}
+
+@SysUISingleton
+class NotificationIconStyleProviderImpl @Inject constructor() : NotificationIconStyleProvider {
+    override fun shouldShowAppIcon(notification: StatusBarNotification, context: Context): Boolean {
+        val packageContext = notification.getPackageContext(context)
+        return !belongsToHeadlessSystemApp(packageContext)
+    }
+
+    @WorkerThread
+    private fun belongsToHeadlessSystemApp(context: Context): Boolean {
+        val info = context.applicationInfo
+        if (info != null) {
+            if ((info.flags and ApplicationInfo.FLAG_SYSTEM) == 0) {
+                // It's not a system app at all.
+                return false
+            } else {
+                // If there's no launch intent, it's probably a headless app.
+                val pm = context.packageManager
+                return (pm.getLaunchIntentForPackage(info.packageName) == null)
+            }
+        } else {
+            // If for some reason we don't have the app info, we don't know; best assume it's
+            // not a system app.
+            return false
+        }
+    }
+}
+
+class NoOpIconStyleProvider : NotificationIconStyleProvider {
+    companion object {
+        const val TAG = "NoOpIconStyleProvider"
+    }
+
+    override fun shouldShowAppIcon(notification: StatusBarNotification, context: Context): Boolean {
+        Log.wtf(TAG, "NoOpIconStyleProvider should not be used anywhere.")
+        return true
+    }
+}
+
+@Module
+class NotificationIconStyleProviderModule {
+    @Provides
+    @SysUISingleton
+    fun provideImpl(
+        realImpl: Provider<NotificationIconStyleProviderImpl>
+    ): NotificationIconStyleProvider =
+        if (Flags.notificationsRedesignAppIcons()) {
+            realImpl.get()
+        } else {
+            NoOpIconStyleProvider()
+        }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationRowIconViewInflaterFactory.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationRowIconViewInflaterFactory.kt
index 2522e58..79defd2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationRowIconViewInflaterFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationRowIconViewInflaterFactory.kt
@@ -32,7 +32,10 @@
  */
 class NotificationRowIconViewInflaterFactory
 @Inject
-constructor(private val appIconProvider: AppIconProvider) : NotifRemoteViewsFactory {
+constructor(
+    private val appIconProvider: AppIconProvider,
+    private val iconStyleProvider: NotificationIconStyleProvider,
+) : NotifRemoteViewsFactory {
     override fun instantiate(
         row: ExpandableNotificationRow,
         @NotificationRowContentBinder.InflationFlag layoutType: Int,
@@ -48,8 +51,7 @@
                     view.setIconProvider(
                         object : NotificationRowIconView.NotificationIconProvider {
                             override fun shouldShowAppIcon(): Boolean {
-                                // TODO(b/371174789): implement me
-                                return true
+                                return iconStyleProvider.shouldShowAppIcon(row.entry.sbn, context)
                             }
 
                             override fun getAppIcon(): Drawable {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt
index a7a6195..7f4c670 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt
@@ -70,6 +70,7 @@
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag
 import com.android.systemui.statusbar.notification.row.icon.AppIconProviderImpl
+import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProviderImpl
 import com.android.systemui.statusbar.notification.row.icon.NotificationRowIconViewInflaterFactory
 import com.android.systemui.statusbar.notification.row.shared.NotificationRowContentBinderRefactor
 import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerLogger
@@ -287,7 +288,10 @@
             BigPictureLayoutInflaterFactory(),
             NotificationOptimizedLinearLayoutFactory(),
             { Mockito.mock(NotificationViewFlipperFactory::class.java) },
-            NotificationRowIconViewInflaterFactory(AppIconProviderImpl(context)),
+            NotificationRowIconViewInflaterFactory(
+                AppIconProviderImpl(context),
+                NotificationIconStyleProviderImpl(),
+            ),
         )
     }
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/icon/NotificationIconStyleProviderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/icon/NotificationIconStyleProviderKosmos.kt
new file mode 100644
index 0000000..611c90a
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/icon/NotificationIconStyleProviderKosmos.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.row.icon
+
+import com.android.systemui.kosmos.Kosmos
+
+val Kosmos.notificationIconStyleProvider by Kosmos.Fixture { NotificationIconStyleProviderImpl() }