Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac2a1f25 authored by Anton Potapov's avatar Anton Potapov Committed by Android (Google) Code Review
Browse files

Merge "Add slider input events interactor." into main

parents d265dbf2 217c1f4a
Loading
Loading
Loading
Loading
+92 −0
Original line number Original line 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.sliders.domain.interactor

import android.app.ActivityManager
import android.testing.TestableLooper
import android.view.MotionEvent
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.testScope
import com.android.systemui.plugins.fakeVolumeDialogController
import com.android.systemui.testKosmos
import com.android.systemui.volume.Events
import com.android.systemui.volume.dialog.domain.interactor.volumeDialogVisibilityInteractor
import com.android.systemui.volume.dialog.shared.model.VolumeDialogVisibilityModel
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.runner.RunWith

private val volumeDialogTimeout = 3.seconds

@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class VolumeDialogSliderInputEventsInteractorTest : SysuiTestCase() {

    private val kosmos = testKosmos()

    private lateinit var underTest: VolumeDialogSliderInputEventsInteractor

    @Before
    fun setup() {
        underTest = kosmos.volumeDialogSliderInputEventsInteractor
    }

    @Test
    fun inputEvents_resetDialogVisibilityTimeout() =
        with(kosmos) {
            testScope.runTest {
                runCurrent()
                val dialogVisibility by
                    collectLastValue(volumeDialogVisibilityInteractor.dialogVisibility)
                fakeVolumeDialogController.onShowRequested(
                    Events.SHOW_REASON_VOLUME_CHANGED,
                    false,
                    ActivityManager.LOCK_TASK_MODE_LOCKED,
                )
                runCurrent()
                advanceTimeBy(volumeDialogTimeout / 2)
                assertThat(dialogVisibility)
                    .isInstanceOf(VolumeDialogVisibilityModel.Visible::class.java)

                underTest.onTouchEvent(
                    MotionEvent.obtain(
                        /* downTime = */ 0,
                        /* eventTime = */ 0,
                        /* action = */ 0,
                        /* x = */ 0f,
                        /* y = */ 0f,
                        /* metaState = */ 0,
                    )
                )
                advanceTimeBy(volumeDialogTimeout / 2)

                assertThat(dialogVisibility)
                    .isInstanceOf(VolumeDialogVisibilityModel.Visible::class.java)
            }
        }
}
+3 −0
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.volume.dialog.sliders.dagger
package com.android.systemui.volume.dialog.sliders.dagger


import com.android.systemui.volume.dialog.sliders.domain.model.VolumeDialogSliderType
import com.android.systemui.volume.dialog.sliders.domain.model.VolumeDialogSliderType
import com.android.systemui.volume.dialog.sliders.ui.VolumeDialogSliderTouchesViewBinder
import com.android.systemui.volume.dialog.sliders.ui.VolumeDialogSliderViewBinder
import com.android.systemui.volume.dialog.sliders.ui.VolumeDialogSliderViewBinder
import dagger.BindsInstance
import dagger.BindsInstance
import dagger.Subcomponent
import dagger.Subcomponent
@@ -31,6 +32,8 @@ interface VolumeDialogSliderComponent {


    fun sliderViewBinder(): VolumeDialogSliderViewBinder
    fun sliderViewBinder(): VolumeDialogSliderViewBinder


    fun sliderTouchesViewBinder(): VolumeDialogSliderTouchesViewBinder

    @Subcomponent.Factory
    @Subcomponent.Factory
    interface Factory {
    interface Factory {


+37 −0
Original line number Original line 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.sliders.data.repository

import android.annotation.SuppressLint
import android.view.MotionEvent
import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderScope
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.filterNotNull

@VolumeDialogSliderScope
class VolumeDialogSliderTouchEventsRepository @Inject constructor() {

    @SuppressLint("SharedFlowCreation")
    private val mutableSliderTouchEvents: MutableStateFlow<MotionEvent?> = MutableStateFlow(null)
    val sliderTouchEvent: Flow<MotionEvent> = mutableSliderTouchEvents.filterNotNull()

    fun update(event: MotionEvent) {
        mutableSliderTouchEvents.tryEmit(MotionEvent.obtain(event))
    }
}
+61 −0
Original line number Original line 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.sliders.domain.interactor

import android.view.MotionEvent
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialog
import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogCallbacksInteractor
import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogVisibilityInteractor
import com.android.systemui.volume.dialog.domain.model.VolumeDialogEventModel
import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderScope
import com.android.systemui.volume.dialog.sliders.data.repository.VolumeDialogSliderTouchEventsRepository
import com.android.systemui.volume.dialog.sliders.shared.model.SliderInputEvent
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach

@VolumeDialogSliderScope
class VolumeDialogSliderInputEventsInteractor
@Inject
constructor(
    @VolumeDialog coroutineScope: CoroutineScope,
    volumeDialogCallbacksInteractor: VolumeDialogCallbacksInteractor,
    private val visibilityInteractor: VolumeDialogVisibilityInteractor,
    private val repository: VolumeDialogSliderTouchEventsRepository,
) {

    val event: Flow<SliderInputEvent> =
        merge(
            repository.sliderTouchEvent.map { SliderInputEvent.Touch(it) },
            volumeDialogCallbacksInteractor.event
                .filterIsInstance(VolumeDialogEventModel.VolumeChangedFromKey::class)
                .map { SliderInputEvent.Button },
        )

    init {
        event.onEach { visibilityInteractor.resetDismissTimeout() }.launchIn(coroutineScope)
    }

    fun onTouchEvent(newEvent: MotionEvent) {
        repository.update(newEvent)
    }
}
+27 −0
Original line number Original line 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.sliders.shared.model

import android.view.MotionEvent

/** Models input event happened on the Volume Slider */
sealed interface SliderInputEvent {

    data class Touch(val event: MotionEvent) : SliderInputEvent

    data object Button : SliderInputEvent
}
Loading