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

Commit b9da53cb authored by David Lin's avatar David Lin Committed by Android (Google) Code Review
Browse files

Merge "[Sat] Replace device provisioned check with satellite provisioned" into 24D1-dev

parents 1d5c95f2 32cc62c4
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.pipeline.satellite.data

import com.android.systemui.statusbar.pipeline.satellite.shared.model.SatelliteConnectionState
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow

/**
 * Device-based satellite refers to the capability of a device to connect directly to a satellite
@@ -25,6 +26,9 @@ import kotlinx.coroutines.flow.Flow
 * given mobile data subscription.
 */
interface DeviceBasedSatelliteRepository {
    /** The current status of satellite provisioning. If not false, we don't want to show an icon */
    val isSatelliteProvisioned: StateFlow<Boolean>

    /** See [SatelliteConnectionState] for available states */
    val connectionState: Flow<SatelliteConnectionState>

+38 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.telephony.satellite.NtnSignalStrengthCallback
import android.telephony.satellite.SatelliteManager
import android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS
import android.telephony.satellite.SatelliteModemStateCallback
import android.telephony.satellite.SatelliteProvisionStateCallback
import android.telephony.satellite.SatelliteSupportedStateCallback
import androidx.annotation.VisibleForTesting
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
@@ -337,6 +338,43 @@ constructor(
            }
        }

    override val isSatelliteProvisioned: StateFlow<Boolean> =
        satelliteSupport
            .whenSupported(
                supported = ::satelliteProvisioned,
                orElse = flowOf(false),
                retrySignal = telephonyProcessCrashedEvent,
            )
            .stateIn(scope, SharingStarted.WhileSubscribed(), false)

    private fun satelliteProvisioned(sm: SupportedSatelliteManager): Flow<Boolean> =
        conflatedCallbackFlow {
            val callback = SatelliteProvisionStateCallback { provisioned ->
                logBuffer.i {
                    "onSatelliteProvisionStateChanged: " +
                        if (provisioned) "provisioned" else "not provisioned"
                }
                trySend(provisioned)
            }

            var registered = false
            try {
                sm.registerForProvisionStateChanged(
                    bgDispatcher.asExecutor(),
                    callback,
                )
                registered = true
            } catch (e: Exception) {
                logBuffer.e("error registering for provisioning state callback", e)
            }

            awaitClose {
                if (registered) {
                    sm.unregisterForProvisionStateChanged(callback)
                }
            }
        }

    /**
     * Signal that we should start polling [checkIsSatelliteAllowed]. We only need to poll if there
     * are active listeners to [isSatelliteAllowedForCurrentLocation]
+1 −3
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ import com.android.systemui.statusbar.pipeline.satellite.data.DeviceBasedSatelli
import com.android.systemui.statusbar.pipeline.satellite.shared.model.SatelliteConnectionState
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
import com.android.systemui.statusbar.policy.domain.interactor.DeviceProvisioningInteractor
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -45,7 +44,6 @@ class DeviceBasedSatelliteInteractor
constructor(
    val repo: DeviceBasedSatelliteRepository,
    iconsInteractor: MobileIconsInteractor,
    deviceProvisioningInteractor: DeviceProvisioningInteractor,
    wifiInteractor: WifiInteractor,
    @Application scope: CoroutineScope,
    @DeviceBasedSatelliteInputLog private val logBuffer: LogBuffer,
@@ -78,7 +76,7 @@ constructor(
            }
            .stateIn(scope, SharingStarted.WhileSubscribed(), 0)

    val isDeviceProvisioned: Flow<Boolean> = deviceProvisioningInteractor.isDeviceProvisioned
    val isSatelliteProvisioned = repo.isSatelliteProvisioned

    val isWifiActive: Flow<Boolean> =
        wifiInteractor.wifiNetwork.map { it is WifiNetworkModel.Active }
+3 −3
Original line number Diff line number Diff line
@@ -79,11 +79,11 @@ constructor(
            } else {
                combine(
                    interactor.isSatelliteAllowed,
                    interactor.isDeviceProvisioned,
                    interactor.isSatelliteProvisioned,
                    interactor.isWifiActive,
                    airplaneModeRepository.isAirplaneMode
                ) { isSatelliteAllowed, isDeviceProvisioned, isWifiActive, isAirplaneMode ->
                    isSatelliteAllowed && isDeviceProvisioned && !isWifiActive && !isAirplaneMode
                ) { isSatelliteAllowed, isSatelliteProvisioned, isWifiActive, isAirplaneMode ->
                    isSatelliteAllowed && isSatelliteProvisioned && !isWifiActive && !isAirplaneMode
                }
            }
        }
+93 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_UNAVAI
import android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN
import android.telephony.satellite.SatelliteManager.SatelliteException
import android.telephony.satellite.SatelliteModemStateCallback
import android.telephony.satellite.SatelliteProvisionStateCallback
import android.telephony.satellite.SatelliteSupportedStateCallback
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -325,6 +326,98 @@ class DeviceBasedSatelliteRepositoryImplTest : SysuiTestCase() {
            assertThat(latest).isFalse()
        }

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

            assertThat(underTest.isSatelliteProvisioned.value).isFalse()
        }

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

            // THEN default provisioned state is false
            assertThat(underTest.isSatelliteProvisioned.value).isFalse()
        }

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

            val provisioned by collectLastValue(underTest.isSatelliteProvisioned)
            runCurrent()

            val callback =
                withArgCaptor<SatelliteProvisionStateCallback> {
                    verify(satelliteManager).registerForProvisionStateChanged(any(), capture())
                }

            // WHEN provisioning state changes
            callback.onSatelliteProvisionStateChanged(true)

            // THEN the value is reflected in the repo
            assertThat(provisioned).isTrue()
        }

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

            val provisioned by collectLastValue(underTest.isSatelliteProvisioned)

            runCurrent()

            val callback =
                withArgCaptor<SatelliteProvisionStateCallback> {
                    verify(satelliteManager).registerForProvisionStateChanged(any(), capture())
                }
            val telephonyCallback =
                MobileTelephonyHelpers.getTelephonyCallbackForType<
                    TelephonyCallback.RadioPowerStateListener
                >(
                    telephonyManager
                )

            // GIVEN satellite is currently provisioned
            callback.onSatelliteProvisionStateChanged(true)

            assertThat(provisioned).isTrue()

            // WHEN a crash event happens (detected by radio state change)
            telephonyCallback.onRadioPowerStateChanged(TelephonyManager.RADIO_POWER_ON)
            runCurrent()
            telephonyCallback.onRadioPowerStateChanged(TelephonyManager.RADIO_POWER_OFF)
            runCurrent()

            // THEN listeners are re-registered
            verify(satelliteManager, times(2)).registerForProvisionStateChanged(any(), any())
        }

    @Test
    fun satelliteNotSupported_listenersAreNotRegistered() =
        testScope.runTest {
Loading