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

Commit 842a9827 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "[Sat] Change the satellite provisioned check to eager; query when start" into main

parents b5ab0f35 bcf8c31e
Loading
Loading
Loading
Loading
+54 −19
Original line number Diff line number Diff line
@@ -345,10 +345,16 @@ constructor(
                orElse = flowOf(false),
                retrySignal = telephonyProcessCrashedEvent,
            )
            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
            .stateIn(scope, SharingStarted.Eagerly, false)

    private fun satelliteProvisioned(sm: SupportedSatelliteManager): Flow<Boolean> =
        conflatedCallbackFlow {
                // TODO(b/347992038): SatelliteManager should be sending the current provisioned
                // status when we register a callback. Until then, we have to manually query here.

                // First, check to see what the current status is, and send the result to the output
                trySend(queryIsSatelliteProvisioned(sm))

                val callback = SatelliteProvisionStateCallback { provisioned ->
                    logBuffer.i {
                        "onSatelliteProvisionStateChanged: " +
@@ -359,6 +365,7 @@ constructor(

                var registered = false
                try {
                    logBuffer.i { "registerForProvisionStateChanged" }
                    sm.registerForProvisionStateChanged(
                        bgDispatcher.asExecutor(),
                        callback,
@@ -374,6 +381,34 @@ constructor(
                    }
                }
            }
            .flowOn(bgDispatcher)

    /** Check the current satellite provisioning status. */
    private suspend fun queryIsSatelliteProvisioned(sm: SupportedSatelliteManager): Boolean =
        withContext(bgDispatcher) {
            suspendCancellableCoroutine { continuation ->
                val receiver =
                    object : OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> {
                        override fun onResult(result: Boolean) {
                            logBuffer.i { "requestIsProvisioned.onResult: $result" }
                            continuation.resume(result)
                        }

                        override fun onError(exception: SatelliteManager.SatelliteException) {
                            logBuffer.e("requestIsProvisioned.onError:", exception)
                            continuation.resume(false)
                        }
                    }

                logBuffer.i { "Query for current satellite provisioned state." }
                try {
                    sm.requestIsProvisioned(bgDispatcher.asExecutor(), receiver)
                } catch (e: Exception) {
                    logBuffer.e("Exception while calling SatelliteManager.requestIsProvisioned:", e)
                    continuation.resume(false)
                }
            }
        }

    /**
     * Signal that we should start polling [checkIsSatelliteAllowed]. We only need to poll if there
+143 −1
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_NOT_CO
import android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_OFF
import android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE
import android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN
import android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_ERROR
import android.telephony.satellite.SatelliteManager.SatelliteException
import android.telephony.satellite.SatelliteModemStateCallback
import android.telephony.satellite.SatelliteProvisionStateCallback
@@ -62,6 +63,7 @@ import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.atLeastOnce
import org.mockito.Mockito.doAnswer
import org.mockito.Mockito.never
import org.mockito.Mockito.times
@@ -354,13 +356,142 @@ class DeviceBasedSatelliteRepositoryImplTest : SysuiTestCase() {
        }

    @Test
    fun satelliteProvisioned_supported_tracksCallback() =
    fun satelliteProvisioned_returnsException_defaultsToFalse() =
        testScope.runTest {
            // GIVEN satellite is supported on device
            doAnswer {
                val callback: OutcomeReceiver<Boolean, SatelliteException> =
                    it.getArgument(1) as OutcomeReceiver<Boolean, SatelliteException>
                callback.onResult(true)
            }
                .whenever(satelliteManager)
                .requestIsSupported(any(), any())

            // GIVEN satellite returns an error when asked if provisioned
            doAnswer {
                val receiver = it.arguments[1] as OutcomeReceiver<Boolean, SatelliteException>
                receiver.onError(SatelliteException(SATELLITE_RESULT_ERROR))
                null
            }
                .whenever(satelliteManager)
                .requestIsProvisioned(
                    any(),
                    any<OutcomeReceiver<Boolean, SatelliteException>>()
                )

            // GIVEN we've been up long enough to start querying
            systemClock.setUptimeMillis(Process.getStartUptimeMillis() + MIN_UPTIME)

            underTest =
                DeviceBasedSatelliteRepositoryImpl(
                    Optional.of(satelliteManager),
                    telephonyManager,
                    dispatcher,
                    testScope.backgroundScope,
                    logBuffer = FakeLogBuffer.Factory.create(),
                    verboseLogBuffer = FakeLogBuffer.Factory.create(),
                    systemClock,
                )

            // WHEN we try to check for provisioned status
            val provisioned by collectLastValue(underTest.isSatelliteProvisioned)

            // THEN well, first we don't throw...
            // AND THEN we assume that it's not provisioned
            assertThat(provisioned).isFalse()
        }

    @Test
    fun satelliteProvisioned_throwsWhenQuerying_defaultsToFalse() =
        testScope.runTest {
            // GIVEN satellite is supported on device
            doAnswer {
                val callback: OutcomeReceiver<Boolean, SatelliteException> =
                    it.getArgument(1) as OutcomeReceiver<Boolean, SatelliteException>
                callback.onResult(true)
            }
                .whenever(satelliteManager)
                .requestIsSupported(any(), any())

            // GIVEN satellite throws when asked if provisioned
            whenever(satelliteManager.requestIsProvisioned(any(), any()))
                .thenThrow(SecurityException())

            // GIVEN we've been up long enough to start querying
            systemClock.setUptimeMillis(Process.getStartUptimeMillis() + MIN_UPTIME)

            underTest =
                DeviceBasedSatelliteRepositoryImpl(
                    Optional.of(satelliteManager),
                    telephonyManager,
                    dispatcher,
                    testScope.backgroundScope,
                    logBuffer = FakeLogBuffer.Factory.create(),
                    verboseLogBuffer = FakeLogBuffer.Factory.create(),
                    systemClock,
                )

            // WHEN we try to check for provisioned status
            val provisioned by collectLastValue(underTest.isSatelliteProvisioned)

            // THEN well, first we don't throw...
            // AND THEN we assume that it's not provisioned
            assertThat(provisioned).isFalse()
        }

    @Test
    fun satelliteProvisioned_supported_provisioned_queriesInitialStateBeforeCallbacks() =
        testScope.runTest {
            // GIVEN satellite is supported, and provisioned
            setUpRepo(
                uptime = MIN_UPTIME,
                satMan = satelliteManager,
                satelliteSupported = true,
                initialSatelliteIsProvisioned = true,
            )

            val provisioned by collectLastValue(underTest.isSatelliteProvisioned)

            runCurrent()

            // THEN the current state is requested
            verify(satelliteManager, atLeastOnce()).requestIsProvisioned(any(), any())

            // AND the state is correct
            assertThat(provisioned).isTrue()
        }

    @Test
    fun satelliteProvisioned_supported_notProvisioned_queriesInitialStateBeforeCallbacks() =
        testScope.runTest {
            // GIVEN satellite is supported, and provisioned
            setUpRepo(
                uptime = MIN_UPTIME,
                satMan = satelliteManager,
                satelliteSupported = true,
                initialSatelliteIsProvisioned = false,
            )

            val provisioned by collectLastValue(underTest.isSatelliteProvisioned)

            runCurrent()

            // THEN the current state is requested
            verify(satelliteManager, atLeastOnce()).requestIsProvisioned(any(), any())

            // AND the state is correct
            assertThat(provisioned).isFalse()
        }

    @Test
    fun satelliteProvisioned_supported_notInitiallyProvisioned_tracksCallback() =
        testScope.runTest {
            // GIVEN satellite is not supported
            setUpRepo(
                uptime = MIN_UPTIME,
                satMan = satelliteManager,
                satelliteSupported = true,
                initialSatelliteIsProvisioned = false,
            )

            val provisioned by collectLastValue(underTest.isSatelliteProvisioned)
@@ -416,6 +547,8 @@ class DeviceBasedSatelliteRepositoryImplTest : SysuiTestCase() {

            // THEN listeners are re-registered
            verify(satelliteManager, times(2)).registerForProvisionStateChanged(any(), any())
            // AND the state is queried again
            verify(satelliteManager, times(2)).requestIsProvisioned(any(), any())
        }

    @Test
@@ -632,6 +765,7 @@ class DeviceBasedSatelliteRepositoryImplTest : SysuiTestCase() {
        uptime: Long = MIN_UPTIME,
        satMan: SatelliteManager? = satelliteManager,
        satelliteSupported: Boolean = true,
        initialSatelliteIsProvisioned: Boolean = true,
    ) {
        doAnswer {
                val callback: OutcomeReceiver<Boolean, SatelliteException> =
@@ -641,6 +775,14 @@ class DeviceBasedSatelliteRepositoryImplTest : SysuiTestCase() {
            .whenever(satelliteManager)
            .requestIsSupported(any(), any())

        doAnswer {
            val callback: OutcomeReceiver<Boolean, SatelliteException> =
                it.getArgument(1) as OutcomeReceiver<Boolean, SatelliteException>
            callback.onResult(initialSatelliteIsProvisioned)
        }
            .whenever(satelliteManager)
            .requestIsProvisioned(any(), any())

        systemClock.setUptimeMillis(Process.getStartUptimeMillis() + uptime)

        underTest =