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

Commit 66883bcd authored by Behnam Heydarshahi's avatar Behnam Heydarshahi
Browse files

Delay flashlight reconnect without system clock

Instead we use a mutable state flow and a mutex

Bug: b/412982015
Flag: com.android.systemui.flashlight_strength
Test: atest FlashlightRepositoryTest
Change-Id: I9e5bcdf49073e58ebc52272649aa4eb921765831
parent 95e6035f
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -25,11 +25,11 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.camera.cameraManager
import com.android.systemui.camera.injectCameraCharacteristics
import com.android.systemui.flashlight.shared.model.FlashlightModel
import com.android.systemui.kosmos.advanceTimeBy
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runCurrent
import com.android.systemui.kosmos.runTest
import com.android.systemui.testKosmos
import com.android.systemui.util.time.fakeSystemClock
import com.google.common.truth.Truth.assertThat
import java.util.concurrent.Executor
import kotlin.time.Duration.Companion.seconds
@@ -473,8 +473,7 @@ class FlashlightRepositoryTest : SysuiTestCase() {
            assertThat(state).isEqualTo(FlashlightModel.Unavailable.Temporarily.NotFound)

            injectCameraCharacteristics(true, CameraCharacteristics.LENS_FACING_BACK)
            fakeSystemClock.advanceTime(RECONNECT_COOLDOWN.inWholeMilliseconds + 1000)

            advanceTimeBy(RECONNECT_COOLDOWN.inWholeMilliseconds + 1000)
            assertThat(state).isEqualTo(FlashlightModel.Unavailable.Temporarily.NotFound)

            underTest.setEnabled(true)
@@ -497,7 +496,7 @@ class FlashlightRepositoryTest : SysuiTestCase() {
            assertThat(state).isEqualTo(FlashlightModel.Unavailable.Temporarily.NotFound)

            injectCameraCharacteristics(true, CameraCharacteristics.LENS_FACING_BACK)
            fakeSystemClock.advanceTime(RECONNECT_COOLDOWN.inWholeMilliseconds + 1000)
            advanceTimeBy(RECONNECT_COOLDOWN.inWholeMilliseconds + 1000)

            assertThat(state).isEqualTo(FlashlightModel.Unavailable.Temporarily.NotFound)

@@ -521,7 +520,7 @@ class FlashlightRepositoryTest : SysuiTestCase() {
            assertThat(state).isEqualTo(FlashlightModel.Unavailable.Temporarily.NotFound)

            injectCameraCharacteristics(true, CameraCharacteristics.LENS_FACING_BACK)
            fakeSystemClock.advanceTime(RECONNECT_COOLDOWN.inWholeMilliseconds - 1000)
            advanceTimeBy(RECONNECT_COOLDOWN.inWholeMilliseconds - 1000)

            underTest.setLevel(BASE_TORCH_LEVEL)

+22 −17
Original line number Diff line number Diff line
@@ -33,9 +33,9 @@ import com.android.systemui.shared.settings.data.repository.SecureSettingsReposi
import com.android.systemui.util.asIndenting
import com.android.systemui.util.printSection
import com.android.systemui.util.println
import com.android.systemui.util.time.SystemClock
import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
import java.io.PrintWriter
import java.util.concurrent.atomic.AtomicBoolean
import javax.inject.Inject
import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.CoroutineDispatcher
@@ -43,6 +43,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.asExecutor
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
@@ -80,7 +81,6 @@ constructor(
    private val cameraManager: CameraManager,
    private val dumpManager: DumpManager,
    private val packageManager: PackageManager,
    private val systemClock: SystemClock,
    private val logger: FlashlightLogger,
) : FlashlightRepository, CoreStartable {

@@ -104,8 +104,8 @@ constructor(
    }

    private val flashlightInfo = MutableStateFlow<FlashlightInfo>(FlashlightInfo.NotSupported)
    private var lastConnectionAttempt =
        systemClock.currentTimeMillis() - RECONNECT_COOLDOWN.inWholeMilliseconds

    private var canAttemptReconnect = AtomicBoolean(true)

    override fun start() {
        if (FlashlightStrength.isUnexpectedlyInLegacyMode()) {
@@ -141,31 +141,35 @@ constructor(
            is FlashlightInfo.Supported.LoadedSuccessfully -> true
            is FlashlightInfo.Supported.Initial,
            FlashlightInfo.Supported.ErrorLoading -> {
                val now = systemClock.currentTimeMillis()
                val timeElapsedSinceLastAttempt = now - lastConnectionAttempt
                if (timeElapsedSinceLastAttempt < RECONNECT_COOLDOWN.inWholeMilliseconds) {
                    logger.d(
                        "Need to wait for " +
                            "${(RECONNECT_COOLDOWN.inWholeMilliseconds
                                        - timeElapsedSinceLastAttempt) / 1000} " +
                            "more seconds before trying to connect again."
                    )
                    false
                } else {
                    lastConnectionAttempt = now
                if (canAttemptReconnect.getAndSet(false)) {
                    updateReconnect()
                    var foundCamera: Boolean
                    try {
                        foundCamera = loadFlashlightInfo() != null
                    } catch (exception: Exception) {
                        foundCamera = false
                        logger.w("could not find a camera: ${exception.message}")
                        logger.w("Could not find a camera: ${exception.message}")
                    }
                    if (!foundCamera) {
                        flashlightInfo.emit(FlashlightInfo.Supported.ErrorLoading)
                    }
                    foundCamera
                } else {
                    logger.d(
                        "Need to wait for ${RECONNECT_COOLDOWN.inWholeSeconds}" +
                            " seconds from last attempt before trying to reconnect."
                    )
                    false
                }
            }
        }

    /** Prevent reconnect attempts until [RECONNECT_COOLDOWN] later. */
    private fun updateReconnect() {
        bgScope.launch {
            delay(RECONNECT_COOLDOWN)
            canAttemptReconnect.set(true)
        }
    }

    /**
@@ -341,6 +345,7 @@ constructor(
        }
    }

    /** @throws IllegalArgumentException if level is below 1 and above max */
    override fun setLevel(level: Int) {
        bgScope.launch {
            if (!connectToCameraLoadFlashlightInfo()) {
+0 −2
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.backgroundScope
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.shared.settings.data.repository.secureSettingsRepository
import com.android.systemui.util.time.fakeSystemClock
import org.mockito.kotlin.eq
import org.mockito.kotlin.whenever

@@ -38,7 +37,6 @@ val Kosmos.flashlightRepository: FlashlightRepositoryImpl by
            cameraManager,
            dumpManager,
            packageManager,
            fakeSystemClock,
            flashlightLogger,
        )
    }