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.data.repository 18 19 import android.content.Context 20 import android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR 21 import com.android.systemui.CoreStartable 22 import com.android.systemui.dagger.SysUISingleton 23 import com.android.systemui.dagger.qualifiers.Background 24 import com.android.systemui.display.data.repository.DisplayRepository 25 import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository 26 import com.android.systemui.display.data.repository.PerDisplayStore 27 import com.android.systemui.display.data.repository.SingleDisplayStore 28 import com.android.systemui.plugins.DarkIconDispatcher 29 import com.android.systemui.statusbar.core.StatusBarConnectedDisplays 30 import com.android.systemui.statusbar.phone.DarkIconDispatcherImpl 31 import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher 32 import dagger.Binds 33 import dagger.Lazy 34 import dagger.Module 35 import dagger.Provides 36 import dagger.multibindings.ClassKey 37 import dagger.multibindings.IntoMap 38 import javax.inject.Inject 39 import kotlinx.coroutines.CoroutineScope 40 41 /** Provides per display instances of [DarkIconDispatcher]. */ 42 interface DarkIconDispatcherStore : PerDisplayStore<DarkIconDispatcher> 43 44 /** Provides per display instances of [SysuiDarkIconDispatcher]. */ 45 interface SysuiDarkIconDispatcherStore : PerDisplayStore<SysuiDarkIconDispatcher> 46 47 /** 48 * Multi display implementation that should be used when the [StatusBarConnectedDisplays] flag is 49 * enabled. 50 */ 51 @SysUISingleton 52 class MultiDisplayDarkIconDispatcherStore 53 @Inject 54 constructor( 55 @Background backgroundApplicationScope: CoroutineScope, 56 displayRepository: DisplayRepository, 57 private val factory: DarkIconDispatcherImpl.Factory, 58 private val displayWindowPropertiesRepository: DisplayWindowPropertiesRepository, 59 ) : 60 SysuiDarkIconDispatcherStore, 61 StatusBarPerDisplayStoreImpl<SysuiDarkIconDispatcher>( 62 backgroundApplicationScope, 63 displayRepository, 64 ) { 65 66 init { 67 StatusBarConnectedDisplays.unsafeAssertInNewMode() 68 } 69 createInstanceForDisplaynull70 override fun createInstanceForDisplay(displayId: Int): SysuiDarkIconDispatcher? { 71 val properties = 72 displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR) ?: return null 73 return factory.create(displayId, properties.context) 74 } 75 onDisplayRemovalActionnull76 override suspend fun onDisplayRemovalAction(instance: SysuiDarkIconDispatcher) { 77 instance.stop() 78 } 79 80 override val instanceClass = SysuiDarkIconDispatcher::class.java 81 } 82 83 /** 84 * Single display implementation that should be used when the [StatusBarConnectedDisplays] flag is 85 * disabled. 86 */ 87 @SysUISingleton 88 class SingleDisplayDarkIconDispatcherStore 89 @Inject 90 constructor(factory: DarkIconDispatcherImpl.Factory, context: Context) : 91 SysuiDarkIconDispatcherStore, 92 PerDisplayStore<SysuiDarkIconDispatcher> by SingleDisplayStore( 93 defaultInstance = factory.create(context.displayId, context) <lambda>null94 ) { 95 96 init { 97 StatusBarConnectedDisplays.assertInLegacyMode() 98 } 99 } 100 101 /** Extra implementation that simply implements the [DarkIconDispatcherStore] interface. */ 102 @SysUISingleton 103 class DarkIconDispatcherStoreImpl 104 @Inject 105 constructor(private val store: SysuiDarkIconDispatcherStore) : DarkIconDispatcherStore { 106 override val defaultDisplay: DarkIconDispatcher 107 get() = store.defaultDisplay 108 forDisplaynull109 override fun forDisplay(displayId: Int): DarkIconDispatcher? = store.forDisplay(displayId) 110 } 111 112 @Module 113 interface DarkIconDispatcherStoreModule { 114 115 @Binds fun store(impl: DarkIconDispatcherStoreImpl): DarkIconDispatcherStore 116 117 companion object { 118 @Provides 119 @SysUISingleton 120 fun sysUiStore( 121 singleDisplayLazy: Lazy<SingleDisplayDarkIconDispatcherStore>, 122 multiDisplayLazy: Lazy<MultiDisplayDarkIconDispatcherStore>, 123 ): SysuiDarkIconDispatcherStore { 124 return if (StatusBarConnectedDisplays.isEnabled) { 125 multiDisplayLazy.get() 126 } else { 127 singleDisplayLazy.get() 128 } 129 } 130 131 @Provides 132 @SysUISingleton 133 @IntoMap 134 @ClassKey(DarkIconDispatcherStore::class) 135 fun storeAsCoreStartable( 136 multiDisplayLazy: Lazy<MultiDisplayDarkIconDispatcherStore> 137 ): CoreStartable { 138 return if (StatusBarConnectedDisplays.isEnabled) { 139 multiDisplayLazy.get() 140 } else { 141 CoreStartable.NOP 142 } 143 } 144 } 145 } 146