1 /* 2 * Copyright (C) 2023 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.dagger 18 19 import com.android.systemui.CoreStartable 20 import com.android.systemui.NoOpCoreStartable 21 import com.android.systemui.dagger.SysUISingleton 22 import com.android.systemui.dagger.qualifiers.UiBackground 23 import com.android.systemui.plugins.statusbar.StatusBarStateController 24 import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor 25 import com.android.systemui.statusbar.NotificationListener 26 import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore 27 import com.android.systemui.statusbar.notification.collection.NotifPipeline 28 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider 29 import com.android.systemui.statusbar.notification.logging.NotificationLogger 30 import com.android.systemui.statusbar.notification.logging.NotificationLogger.ExpansionStateLogger 31 import com.android.systemui.statusbar.notification.logging.NotificationPanelLogger 32 import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor 33 import com.android.systemui.statusbar.notification.stack.ui.view.NotificationRowStatsLogger 34 import com.android.systemui.statusbar.notification.stack.ui.view.NotificationStatsLogger 35 import com.android.systemui.statusbar.notification.stack.ui.view.NotificationStatsLoggerImpl 36 import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationLoggerViewModel 37 import com.android.systemui.util.kotlin.JavaAdapter 38 import com.android.systemui.util.kotlin.getOrNull 39 import dagger.Binds 40 import dagger.Module 41 import dagger.Provides 42 import dagger.multibindings.ClassKey 43 import dagger.multibindings.IntoMap 44 import java.util.Optional 45 import java.util.concurrent.Executor 46 import javax.inject.Provider 47 48 @Module 49 interface NotificationStatsLoggerModule { 50 51 /** Binds an implementation to the [NotificationStatsLogger]. */ bindsStatsLoggerImplnull52 @Binds fun bindsStatsLoggerImpl(impl: NotificationStatsLoggerImpl): NotificationStatsLogger 53 54 companion object { 55 56 /** Provides a [NotificationStatsLogger] if the refactor flag is on. */ 57 @Provides 58 fun provideStatsLogger( 59 provider: Provider<NotificationStatsLogger> 60 ): Optional<NotificationStatsLogger> { 61 return if (NotificationsLiveDataStoreRefactor.isEnabled) { 62 Optional.of(provider.get()) 63 } else { 64 Optional.empty() 65 } 66 } 67 68 /** Provides a [NotificationLoggerViewModel] if the refactor flag is on. */ 69 @Provides 70 fun provideViewModel( 71 provider: Provider<NotificationLoggerViewModel> 72 ): Optional<NotificationLoggerViewModel> { 73 return if (NotificationsLiveDataStoreRefactor.isEnabled) { 74 Optional.of(provider.get()) 75 } else { 76 Optional.empty() 77 } 78 } 79 80 /** Provides the legacy [NotificationLogger] if the refactor flag is off. */ 81 @Provides 82 @SysUISingleton 83 fun provideLegacyLoggerOptional( 84 notificationListener: NotificationListener?, 85 @UiBackground uiBgExecutor: Executor?, 86 notifLiveDataStore: NotifLiveDataStore?, 87 visibilityProvider: NotificationVisibilityProvider?, 88 notifPipeline: NotifPipeline?, 89 statusBarStateController: StatusBarStateController?, 90 windowRootViewVisibilityInteractor: WindowRootViewVisibilityInteractor?, 91 javaAdapter: JavaAdapter?, 92 expansionStateLogger: ExpansionStateLogger?, 93 notificationPanelLogger: NotificationPanelLogger? 94 ): Optional<NotificationLogger> { 95 return if (NotificationsLiveDataStoreRefactor.isEnabled) { 96 Optional.empty() 97 } else { 98 Optional.of( 99 NotificationLogger( 100 notificationListener, 101 uiBgExecutor, 102 notifLiveDataStore, 103 visibilityProvider, 104 notifPipeline, 105 statusBarStateController, 106 windowRootViewVisibilityInteractor, 107 javaAdapter, 108 expansionStateLogger, 109 notificationPanelLogger 110 ) 111 ) 112 } 113 } 114 115 /** 116 * Provides a the legacy [NotificationLogger] or the new [NotificationStatsLogger] to the 117 * notification row. 118 * 119 * TODO(b/308623704) remove the [NotificationRowStatsLogger] interface, and provide a 120 * [NotificationStatsLogger] to the row directly. 121 */ 122 @Provides 123 fun provideRowStatsLogger( 124 newProvider: Provider<NotificationStatsLogger>, 125 legacyLoggerOptional: Optional<NotificationLogger>, 126 ): NotificationRowStatsLogger { 127 return legacyLoggerOptional.getOrNull() ?: newProvider.get() 128 } 129 130 /** 131 * Binds the legacy [NotificationLogger] as a [CoreStartable] if the feature flag is off, or 132 * binds a no-op [CoreStartable] otherwise. 133 * 134 * The old [NotificationLogger] is a [CoreStartable], because it's managing its own data 135 * updates, but the new [NotificationStatsLogger] is not. Currently Dagger doesn't support 136 * optionally binding entries with @[IntoMap], therefore we provide a no-op [CoreStartable] 137 * here if the feature flag is on, but this can be removed once the flag is released. 138 */ 139 @Provides 140 @IntoMap 141 @ClassKey(NotificationLogger::class) 142 fun provideCoreStartable( 143 legacyLoggerOptional: Optional<NotificationLogger> 144 ): CoreStartable { 145 return legacyLoggerOptional.getOrNull() ?: NoOpCoreStartable() 146 } 147 } 148 } 149