Loading packages/SystemUI/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogVisibilityInteractor.kt +2 −2 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.update private val maxDialogShowTime: Duration = 3.seconds private val MAX_DIALOG_SHOW_TIME: Duration = 3.seconds /** * Handles Volume Dialog visibility state. It might change from several sources: Loading @@ -65,7 +65,7 @@ constructor( init { merge( mutableDismissDialogEvents.mapLatest { delay(maxDialogShowTime) delay(MAX_DIALOG_SHOW_TIME) VolumeDialogEventModel.DismissRequested(Events.DISMISS_REASON_TIMEOUT) }, callbacksInteractor.event, Loading packages/SystemUI/src/com/android/systemui/volume/dialog/settings/domain/VolumeDialogSettingsButtonInteractor.kt 0 → 100644 +58 −0 Original line number Diff line number Diff line /* * 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.volume.dialog.settings.domain import android.app.ActivityManager import com.android.app.tracing.coroutines.flow.map import com.android.systemui.statusbar.policy.DeviceProvisionedController import com.android.systemui.volume.Events import com.android.systemui.volume.dialog.dagger.scope.VolumeDialog import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogVisibilityInteractor import com.android.systemui.volume.dialog.domain.model.VolumeDialogVisibilityModel import com.android.systemui.volume.panel.domain.interactor.VolumePanelGlobalStateInteractor import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.stateIn @VolumeDialogScope class VolumeDialogSettingsButtonInteractor @Inject constructor( @VolumeDialog private val coroutineScope: CoroutineScope, private val deviceProvisionedController: DeviceProvisionedController, private val volumePanelGlobalStateInteractor: VolumePanelGlobalStateInteractor, private val visibilityInteractor: VolumeDialogVisibilityInteractor, ) { val isVisible: StateFlow<Boolean> = visibilityInteractor.dialogVisibility .filterIsInstance(VolumeDialogVisibilityModel.Visible::class) .map { model -> deviceProvisionedController.isCurrentUserSetup() && model.lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE } .stateIn(coroutineScope, SharingStarted.Eagerly, false) fun onButtonClicked() { volumePanelGlobalStateInteractor.setVisible(true) visibilityInteractor.dismissDialog(Events.DISMISS_REASON_SETTINGS_CLICKED) } } packages/SystemUI/src/com/android/systemui/volume/dialog/settings/ui/binder/VolumeDialogSettingsButtonViewBinder.kt 0 → 100644 +54 −0 Original line number Diff line number Diff line /* * 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.volume.dialog.settings.ui.binder import android.view.View import com.android.systemui.lifecycle.WindowLifecycleState import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.lifecycle.setSnapshotBinding import com.android.systemui.lifecycle.viewModel import com.android.systemui.res.R import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope import com.android.systemui.volume.dialog.settings.ui.viewmodel.VolumeDialogSettingsButtonViewModel import javax.inject.Inject import kotlinx.coroutines.awaitCancellation @VolumeDialogScope class VolumeDialogSettingsButtonViewBinder @Inject constructor(private val viewModelFactory: VolumeDialogSettingsButtonViewModel.Factory) { fun bind(view: View) { with(view) { val button = requireViewById<View>(R.id.settings) repeatWhenAttached { viewModel( traceName = "VolumeDialogViewBinder", minWindowLifecycleState = WindowLifecycleState.ATTACHED, factory = { viewModelFactory.create() }, ) { viewModel -> setSnapshotBinding { visibility = if (viewModel.isVisible) View.VISIBLE else View.GONE button.setOnClickListener { viewModel.onButtonClicked() } } awaitCancellation() } } } } } packages/SystemUI/src/com/android/systemui/volume/dialog/settings/ui/viewmodel/VolumeDialogSettingsButtonViewModel.kt 0 → 100644 +49 −0 Original line number Diff line number Diff line /* * 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.volume.dialog.settings.ui.viewmodel import androidx.compose.runtime.getValue import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.Hydrator import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope import com.android.systemui.volume.dialog.settings.domain.VolumeDialogSettingsButtonInteractor import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject class VolumeDialogSettingsButtonViewModel @AssistedInject constructor(private val interactor: VolumeDialogSettingsButtonInteractor) : ExclusiveActivatable() { private val hydrator = Hydrator("VolumeDialog_settings_button") val isVisible by hydrator.hydratedStateOf("isVisible", interactor.isVisible) override suspend fun onActivated(): Nothing { hydrator.activate() } fun onButtonClicked() { interactor.onButtonClicked() } @VolumeDialogScope @AssistedFactory interface Factory { fun create(): VolumeDialogSettingsButtonViewModel } } packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogBinder.kt +4 −8 Original line number Diff line number Diff line Loading @@ -20,21 +20,18 @@ import android.app.Dialog import android.graphics.Color import android.graphics.PixelFormat import android.graphics.drawable.ColorDrawable import android.view.View import android.view.ViewGroup import android.view.Window import android.view.WindowManager import androidx.lifecycle.lifecycleScope import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.res.R import com.android.systemui.volume.dialog.dagger.scope.VolumeDialog import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope import com.android.systemui.volume.dialog.settings.ui.binder.VolumeDialogSettingsButtonViewBinder import com.android.systemui.volume.dialog.ui.viewmodel.VolumeDialogGravityViewModel import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @VolumeDialogScope class VolumeDialogBinder Loading @@ -42,6 +39,7 @@ class VolumeDialogBinder constructor( @VolumeDialog private val coroutineScope: CoroutineScope, private val volumeDialogViewBinder: VolumeDialogViewBinder, private val settingsButtonViewBinder: VolumeDialogSettingsButtonViewBinder, private val gravityViewModel: VolumeDialogGravityViewModel, ) { Loading @@ -50,10 +48,8 @@ constructor( setupWindow(window!!) dialog.setContentView(R.layout.volume_dialog) val volumeDialogView: View = dialog.requireViewById(R.id.volume_dialog_container) volumeDialogView.repeatWhenAttached { lifecycleScope.launch { volumeDialogViewBinder.bind(volumeDialogView) } } settingsButtonViewBinder.bind(dialog.requireViewById(R.id.settings_container)) volumeDialogViewBinder.bind(dialog.requireViewById(R.id.volume_dialog_container)) } } Loading Loading
packages/SystemUI/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogVisibilityInteractor.kt +2 −2 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.update private val maxDialogShowTime: Duration = 3.seconds private val MAX_DIALOG_SHOW_TIME: Duration = 3.seconds /** * Handles Volume Dialog visibility state. It might change from several sources: Loading @@ -65,7 +65,7 @@ constructor( init { merge( mutableDismissDialogEvents.mapLatest { delay(maxDialogShowTime) delay(MAX_DIALOG_SHOW_TIME) VolumeDialogEventModel.DismissRequested(Events.DISMISS_REASON_TIMEOUT) }, callbacksInteractor.event, Loading
packages/SystemUI/src/com/android/systemui/volume/dialog/settings/domain/VolumeDialogSettingsButtonInteractor.kt 0 → 100644 +58 −0 Original line number Diff line number Diff line /* * 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.volume.dialog.settings.domain import android.app.ActivityManager import com.android.app.tracing.coroutines.flow.map import com.android.systemui.statusbar.policy.DeviceProvisionedController import com.android.systemui.volume.Events import com.android.systemui.volume.dialog.dagger.scope.VolumeDialog import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogVisibilityInteractor import com.android.systemui.volume.dialog.domain.model.VolumeDialogVisibilityModel import com.android.systemui.volume.panel.domain.interactor.VolumePanelGlobalStateInteractor import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.stateIn @VolumeDialogScope class VolumeDialogSettingsButtonInteractor @Inject constructor( @VolumeDialog private val coroutineScope: CoroutineScope, private val deviceProvisionedController: DeviceProvisionedController, private val volumePanelGlobalStateInteractor: VolumePanelGlobalStateInteractor, private val visibilityInteractor: VolumeDialogVisibilityInteractor, ) { val isVisible: StateFlow<Boolean> = visibilityInteractor.dialogVisibility .filterIsInstance(VolumeDialogVisibilityModel.Visible::class) .map { model -> deviceProvisionedController.isCurrentUserSetup() && model.lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE } .stateIn(coroutineScope, SharingStarted.Eagerly, false) fun onButtonClicked() { volumePanelGlobalStateInteractor.setVisible(true) visibilityInteractor.dismissDialog(Events.DISMISS_REASON_SETTINGS_CLICKED) } }
packages/SystemUI/src/com/android/systemui/volume/dialog/settings/ui/binder/VolumeDialogSettingsButtonViewBinder.kt 0 → 100644 +54 −0 Original line number Diff line number Diff line /* * 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.volume.dialog.settings.ui.binder import android.view.View import com.android.systemui.lifecycle.WindowLifecycleState import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.lifecycle.setSnapshotBinding import com.android.systemui.lifecycle.viewModel import com.android.systemui.res.R import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope import com.android.systemui.volume.dialog.settings.ui.viewmodel.VolumeDialogSettingsButtonViewModel import javax.inject.Inject import kotlinx.coroutines.awaitCancellation @VolumeDialogScope class VolumeDialogSettingsButtonViewBinder @Inject constructor(private val viewModelFactory: VolumeDialogSettingsButtonViewModel.Factory) { fun bind(view: View) { with(view) { val button = requireViewById<View>(R.id.settings) repeatWhenAttached { viewModel( traceName = "VolumeDialogViewBinder", minWindowLifecycleState = WindowLifecycleState.ATTACHED, factory = { viewModelFactory.create() }, ) { viewModel -> setSnapshotBinding { visibility = if (viewModel.isVisible) View.VISIBLE else View.GONE button.setOnClickListener { viewModel.onButtonClicked() } } awaitCancellation() } } } } }
packages/SystemUI/src/com/android/systemui/volume/dialog/settings/ui/viewmodel/VolumeDialogSettingsButtonViewModel.kt 0 → 100644 +49 −0 Original line number Diff line number Diff line /* * 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.volume.dialog.settings.ui.viewmodel import androidx.compose.runtime.getValue import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.Hydrator import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope import com.android.systemui.volume.dialog.settings.domain.VolumeDialogSettingsButtonInteractor import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject class VolumeDialogSettingsButtonViewModel @AssistedInject constructor(private val interactor: VolumeDialogSettingsButtonInteractor) : ExclusiveActivatable() { private val hydrator = Hydrator("VolumeDialog_settings_button") val isVisible by hydrator.hydratedStateOf("isVisible", interactor.isVisible) override suspend fun onActivated(): Nothing { hydrator.activate() } fun onButtonClicked() { interactor.onButtonClicked() } @VolumeDialogScope @AssistedFactory interface Factory { fun create(): VolumeDialogSettingsButtonViewModel } }
packages/SystemUI/src/com/android/systemui/volume/dialog/ui/binder/VolumeDialogBinder.kt +4 −8 Original line number Diff line number Diff line Loading @@ -20,21 +20,18 @@ import android.app.Dialog import android.graphics.Color import android.graphics.PixelFormat import android.graphics.drawable.ColorDrawable import android.view.View import android.view.ViewGroup import android.view.Window import android.view.WindowManager import androidx.lifecycle.lifecycleScope import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.res.R import com.android.systemui.volume.dialog.dagger.scope.VolumeDialog import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope import com.android.systemui.volume.dialog.settings.ui.binder.VolumeDialogSettingsButtonViewBinder import com.android.systemui.volume.dialog.ui.viewmodel.VolumeDialogGravityViewModel import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @VolumeDialogScope class VolumeDialogBinder Loading @@ -42,6 +39,7 @@ class VolumeDialogBinder constructor( @VolumeDialog private val coroutineScope: CoroutineScope, private val volumeDialogViewBinder: VolumeDialogViewBinder, private val settingsButtonViewBinder: VolumeDialogSettingsButtonViewBinder, private val gravityViewModel: VolumeDialogGravityViewModel, ) { Loading @@ -50,10 +48,8 @@ constructor( setupWindow(window!!) dialog.setContentView(R.layout.volume_dialog) val volumeDialogView: View = dialog.requireViewById(R.id.volume_dialog_container) volumeDialogView.repeatWhenAttached { lifecycleScope.launch { volumeDialogViewBinder.bind(volumeDialogView) } } settingsButtonViewBinder.bind(dialog.requireViewById(R.id.settings_container)) volumeDialogViewBinder.bind(dialog.requireViewById(R.id.volume_dialog_container)) } } Loading