diff options
7 files changed, 105 insertions, 51 deletions
diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt index 3c325940c325..13ee1960da72 100644 --- a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt +++ b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt @@ -17,7 +17,6 @@ package com.android.systemui.compose -import android.app.Dialog import android.content.Context import android.view.View import android.view.WindowInsets @@ -33,7 +32,6 @@ import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel import com.android.systemui.scene.shared.model.Scene import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel -import com.android.systemui.statusbar.phone.SystemUIDialogFactory import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.StateFlow @@ -90,10 +88,10 @@ object ComposeFacade : BaseComposeFacade { throwComposeUnavailableError() } - override fun createStickyKeysDialog( - dialogFactory: SystemUIDialogFactory, + override fun createStickyKeysIndicatorContent( + context: Context, viewModel: StickyKeysIndicatorViewModel - ): Dialog { + ): View { throwComposeUnavailableError() } diff --git a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt index afb860e62261..f05c7f3f1616 100644 --- a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt +++ b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt @@ -16,7 +16,6 @@ package com.android.systemui.compose -import android.app.Dialog import android.content.Context import android.graphics.Point import android.view.View @@ -39,7 +38,7 @@ import com.android.systemui.communal.ui.compose.CommunalContainer import com.android.systemui.communal.ui.compose.CommunalHub import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel import com.android.systemui.communal.widgets.WidgetConfigurator -import com.android.systemui.keyboard.stickykeys.ui.view.StickyKeysIndicator +import com.android.systemui.keyboard.stickykeys.ui.view.createStickyKeyIndicatorView import com.android.systemui.keyboard.stickykeys.ui.viewmodel.StickyKeysIndicatorViewModel import com.android.systemui.people.ui.compose.PeopleScreen import com.android.systemui.people.ui.viewmodel.PeopleViewModel @@ -50,8 +49,6 @@ import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.ui.composable.ComposableScene import com.android.systemui.scene.ui.composable.SceneContainer import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel -import com.android.systemui.statusbar.phone.SystemUIDialogFactory -import com.android.systemui.statusbar.phone.create import com.android.systemui.volume.panel.ui.composable.VolumePanelRoot import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel import kotlinx.coroutines.CoroutineScope @@ -140,11 +137,11 @@ object ComposeFacade : BaseComposeFacade { } } - override fun createStickyKeysDialog( - dialogFactory: SystemUIDialogFactory, + override fun createStickyKeysIndicatorContent( + context: Context, viewModel: StickyKeysIndicatorViewModel - ): Dialog { - return dialogFactory.create { StickyKeysIndicator(viewModel) } + ): View { + return createStickyKeyIndicatorView(context, viewModel) } override fun createCommunalView( diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyboard/stickykeys/ui/view/StickyKeysIndicator.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyboard/stickykeys/ui/view/StickyKeysIndicator.kt index 68e57b5d51b8..4f3d4879813f 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyboard/stickykeys/ui/view/StickyKeysIndicator.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyboard/stickykeys/ui/view/StickyKeysIndicator.kt @@ -16,23 +16,42 @@ package com.android.systemui.keyboard.stickykeys.ui.view +import android.content.Context +import android.view.View import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding +import androidx.compose.material3.LocalContentColor import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.key import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp +import com.android.compose.theme.PlatformTheme import com.android.systemui.keyboard.stickykeys.shared.model.Locked import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey import com.android.systemui.keyboard.stickykeys.ui.viewmodel.StickyKeysIndicatorViewModel +fun createStickyKeyIndicatorView(context: Context, viewModel: StickyKeysIndicatorViewModel): View { + return ComposeView(context).apply { + setContent { + PlatformTheme { + val defaultContentColor = MaterialTheme.colorScheme.onSurfaceVariant + CompositionLocalProvider(LocalContentColor provides defaultContentColor) { + StickyKeysIndicator(viewModel) + } + } + } + } +} + @Composable fun StickyKeysIndicator(viewModel: StickyKeysIndicatorViewModel) { val stickyKeys by viewModel.indicatorContent.collectAsState(emptyMap()) diff --git a/packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt b/packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt index 947cb024f7fe..8df7e8b430f0 100644 --- a/packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt +++ b/packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt @@ -17,7 +17,6 @@ package com.android.systemui.compose -import android.app.Dialog import android.content.Context import android.view.View import android.view.WindowInsets @@ -33,7 +32,6 @@ import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel import com.android.systemui.scene.shared.model.Scene import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel -import com.android.systemui.statusbar.phone.SystemUIDialogFactory import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.StateFlow @@ -96,11 +94,11 @@ interface BaseComposeFacade { sceneByKey: Map<SceneKey, Scene>, ): View - /** Creates sticky key dialog presenting provided [viewModel] */ - fun createStickyKeysDialog( - dialogFactory: SystemUIDialogFactory, + /** Creates sticky key indicator content presenting provided [viewModel] */ + fun createStickyKeysIndicatorContent( + context: Context, viewModel: StickyKeysIndicatorViewModel - ): Dialog + ): View /** Create a [View] to represent [viewModel] on screen. */ fun createCommunalView( diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeyDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeyDialogFactory.kt new file mode 100644 index 000000000000..3ed58a7fe5ae --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeyDialogFactory.kt @@ -0,0 +1,67 @@ +/* + * 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.keyboard.stickykeys.ui + +import android.app.Dialog +import android.content.Context +import android.view.Gravity +import android.view.Window +import android.view.WindowManager +import android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND +import android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE +import android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE +import android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL +import androidx.activity.ComponentDialog +import com.android.systemui.compose.ComposeFacade +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.keyboard.stickykeys.ui.viewmodel.StickyKeysIndicatorViewModel +import com.android.systemui.res.R +import javax.inject.Inject + +@SysUISingleton +class StickyKeyDialogFactory +@Inject +constructor( + @Application val context: Context, +) { + + fun create(viewModel: StickyKeysIndicatorViewModel): Dialog { + return createStickyKeyIndicator(viewModel) + } + + private fun createStickyKeyIndicator(viewModel: StickyKeysIndicatorViewModel): Dialog { + return ComponentDialog(context, R.style.Theme_SystemUI_Dialog).apply { + // because we're requesting window feature it must be called before setting content + window?.setStickyKeyWindowAttributes() + setContentView(ComposeFacade.createStickyKeysIndicatorContent(context, viewModel)) + } + } + + private fun Window.setStickyKeyWindowAttributes() { + requestFeature(Window.FEATURE_NO_TITLE) + setType(TYPE_STATUS_BAR_SUB_PANEL) + addFlags(FLAG_NOT_FOCUSABLE or FLAG_NOT_TOUCHABLE) + clearFlags(FLAG_DIM_BEHIND) + setGravity(Gravity.TOP or Gravity.END) + attributes = + WindowManager.LayoutParams().apply { + copyFrom(attributes) + title = "StickyKeysIndicator" + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeysIndicatorCoordinator.kt b/packages/SystemUI/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeysIndicatorCoordinator.kt index c3a618d29c76..842fd04bfcc5 100644 --- a/packages/SystemUI/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeysIndicatorCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeysIndicatorCoordinator.kt @@ -18,16 +18,11 @@ package com.android.systemui.keyboard.stickykeys.ui import android.app.Dialog import android.util.Log -import android.view.Gravity -import android.view.ViewGroup.LayoutParams.WRAP_CONTENT -import android.view.Window -import android.view.WindowManager import com.android.systemui.compose.ComposeFacade import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyboard.stickykeys.StickyKeysLogger import com.android.systemui.keyboard.stickykeys.ui.viewmodel.StickyKeysIndicatorViewModel -import com.android.systemui.statusbar.phone.SystemUIDialogFactory import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import javax.inject.Inject @@ -37,7 +32,7 @@ class StickyKeysIndicatorCoordinator @Inject constructor( @Application private val applicationScope: CoroutineScope, - private val dialogFactory: SystemUIDialogFactory, + private val stickyKeyDialogFactory: StickyKeyDialogFactory, private val viewModel: StickyKeysIndicatorViewModel, private val stickyKeysLogger: StickyKeysLogger, ) { @@ -57,25 +52,10 @@ constructor( dialog?.dismiss() dialog = null } else if (dialog == null) { - dialog = ComposeFacade.createStickyKeysDialog(dialogFactory, viewModel).apply { - window?.setAttributes() - show() - } + dialog = stickyKeyDialogFactory.create(viewModel) + dialog?.show() } } } } - - private fun Window.setAttributes() { - setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL) - addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED) - addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) - clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) - setGravity(Gravity.TOP or Gravity.END) - attributes = WindowManager.LayoutParams().apply { - copyFrom(attributes) - width = WRAP_CONTENT - title = "StickyKeysIndicator" - } - } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeysIndicatorCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeysIndicatorCoordinatorTest.kt index df73cc8f0212..a992956f5121 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeysIndicatorCoordinatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeysIndicatorCoordinatorTest.kt @@ -16,6 +16,7 @@ package com.android.systemui.keyboard.stickykeys.ui +import android.app.Dialog import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.compose.ComposeFacade @@ -26,8 +27,6 @@ import com.android.systemui.keyboard.stickykeys.shared.model.Locked import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey.SHIFT import com.android.systemui.keyboard.stickykeys.ui.viewmodel.StickyKeysIndicatorViewModel import com.android.systemui.kosmos.Kosmos -import com.android.systemui.statusbar.phone.ComponentSystemUIDialog -import com.android.systemui.statusbar.phone.SystemUIDialogFactory import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever @@ -40,8 +39,6 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.JUnit4 -import org.mockito.Mockito.anyBoolean -import org.mockito.Mockito.anyInt import org.mockito.Mockito.verify import org.mockito.Mockito.verifyZeroInteractions @@ -53,15 +50,13 @@ class StickyKeysIndicatorCoordinatorTest : SysuiTestCase() { private lateinit var coordinator: StickyKeysIndicatorCoordinator private val testScope = TestScope(StandardTestDispatcher()) private val stickyKeysRepository = FakeStickyKeysRepository() - private val dialog = mock<ComponentSystemUIDialog>() + private val dialog = mock<Dialog>() @Before fun setup() { Assume.assumeTrue(ComposeFacade.isComposeAvailable()) - val dialogFactory = mock<SystemUIDialogFactory> { - whenever(applicationContext).thenReturn(context) - whenever(create(any(), anyInt(), anyBoolean())).thenReturn(dialog) - } + val dialogFactory = mock<StickyKeyDialogFactory>() + whenever(dialogFactory.create(any())).thenReturn(dialog) val keyboardRepository = Kosmos().keyboardRepository val viewModel = StickyKeysIndicatorViewModel( stickyKeysRepository, |