1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.systemui.statusbar.notification.collection.coordinator 18 19 import android.app.NotificationChannel.NEWS_ID 20 import android.app.NotificationChannel.PROMOTIONS_ID 21 import android.app.NotificationChannel.RECS_ID 22 import android.app.NotificationChannel.SOCIAL_MEDIA_ID 23 import android.app.NotificationChannel.SYSTEM_RESERVED_IDS 24 import com.android.systemui.statusbar.notification.collection.NotifPipeline 25 import com.android.systemui.statusbar.notification.collection.NotificationEntry 26 import com.android.systemui.statusbar.notification.collection.PipelineEntry 27 import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope 28 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifBundler 29 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner 30 import com.android.systemui.statusbar.notification.collection.render.NodeController 31 import com.android.systemui.statusbar.notification.dagger.NewsHeader 32 import com.android.systemui.statusbar.notification.dagger.PromoHeader 33 import com.android.systemui.statusbar.notification.dagger.RecsHeader 34 import com.android.systemui.statusbar.notification.dagger.SocialHeader 35 import com.android.systemui.statusbar.notification.shared.NotificationBundleUi 36 import com.android.systemui.statusbar.notification.stack.BUCKET_NEWS 37 import com.android.systemui.statusbar.notification.stack.BUCKET_PROMO 38 import com.android.systemui.statusbar.notification.stack.BUCKET_RECS 39 import com.android.systemui.statusbar.notification.stack.BUCKET_SOCIAL 40 import javax.inject.Inject 41 42 /** 43 * Coordinator for sections derived from NotificationAssistantService classification. 44 */ 45 @CoordinatorScope 46 class BundleCoordinator @Inject constructor( 47 @NewsHeader private val newsHeaderController: NodeController, 48 @SocialHeader private val socialHeaderController: NodeController, 49 @RecsHeader private val recsHeaderController: NodeController, 50 @PromoHeader private val promoHeaderController: NodeController, 51 ) : Coordinator { 52 53 val newsSectioner = 54 object : NotifSectioner("News", BUCKET_NEWS) { isInSectionnull55 override fun isInSection(entry: PipelineEntry): Boolean { 56 return entry.representativeEntry?.channel?.id == NEWS_ID 57 } 58 getHeaderNodeControllernull59 override fun getHeaderNodeController(): NodeController? { 60 return newsHeaderController 61 } 62 } 63 64 val socialSectioner = 65 object : NotifSectioner("Social", BUCKET_SOCIAL) { isInSectionnull66 override fun isInSection(entry: PipelineEntry): Boolean { 67 return entry.representativeEntry?.channel?.id == SOCIAL_MEDIA_ID 68 } 69 getHeaderNodeControllernull70 override fun getHeaderNodeController(): NodeController? { 71 return socialHeaderController 72 } 73 } 74 75 val recsSectioner = 76 object : NotifSectioner("Recommendations", BUCKET_RECS) { isInSectionnull77 override fun isInSection(entry: PipelineEntry): Boolean { 78 return entry.representativeEntry?.channel?.id == RECS_ID 79 } 80 getHeaderNodeControllernull81 override fun getHeaderNodeController(): NodeController? { 82 return recsHeaderController 83 } 84 } 85 86 val promoSectioner = 87 object : NotifSectioner("Promotions", BUCKET_PROMO) { isInSectionnull88 override fun isInSection(entry: PipelineEntry): Boolean { 89 return entry.representativeEntry?.channel?.id == PROMOTIONS_ID 90 } 91 getHeaderNodeControllernull92 override fun getHeaderNodeController(): NodeController? { 93 return promoHeaderController 94 } 95 } 96 97 val bundler = 98 object : NotifBundler("NotifBundler") { 99 100 // Use list instead of set to keep fixed order 101 override val bundleIds: List<String> = 102 if (debugBundleUi) SYSTEM_RESERVED_IDS + "notify" 103 else SYSTEM_RESERVED_IDS 104 getBundleIdOrNullnull105 override fun getBundleIdOrNull(entry: NotificationEntry?): String? { 106 if (debugBundleUi && entry?.key?.contains("notify") == true) { 107 return "notify" 108 } 109 return entry?.representativeEntry?.channel?.id?.takeIf { it in this.bundleIds } 110 } 111 } 112 attachnull113 override fun attach(pipeline: NotifPipeline) { 114 if (NotificationBundleUi.isEnabled) { 115 pipeline.setNotifBundler(bundler) 116 } 117 } 118 119 companion object { 120 @kotlin.jvm.JvmField 121 var debugBundleUi: Boolean = true 122 } 123 } 124