diff --git a/src/com/android/settings/network/SatelliteRepository.kt b/src/com/android/settings/network/SatelliteRepository.kt index 03da9b0f01b..565fbf349d4 100644 --- a/src/com/android/settings/network/SatelliteRepository.kt +++ b/src/com/android/settings/network/SatelliteRepository.kt @@ -33,6 +33,7 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.flowOf import java.util.concurrent.Executor +import kotlinx.coroutines.flow.flowOn /** * A repository class for interacting with the SatelliteManager API. @@ -112,13 +113,13 @@ class SatelliteRepository( } /** - * Provides a Flow that emits the enabled state of the satellite modem. Updates are triggered + * Provides a Flow that emits the session state of the satellite modem. Updates are triggered * when the modem state changes. * * @param defaultDispatcher The CoroutineDispatcher to use (Defaults to `Dispatchers.Default`). - * @return A Flow emitting `true` when the modem is enabled and `false` otherwise. + * @return A Flow emitting `true` when the session is started and `false` otherwise. */ - fun getIsModemEnabledFlow( + fun getIsSessionStartedFlow( defaultDispatcher: CoroutineDispatcher = Dispatchers.Default, ): Flow { val satelliteManager: SatelliteManager? = @@ -130,42 +131,27 @@ class SatelliteRepository( return callbackFlow { val callback = SatelliteModemStateCallback { state -> - val isEnabled = convertSatelliteModemStateToEnabledState(state) - Log.i(TAG, "Satellite modem state changed: state=$state, isEnabled=$isEnabled") - trySend(isEnabled) + val isSessionStarted = isSatelliteSessionStarted(state) + Log.i(TAG, "Satellite modem state changed: state=$state" + + ", isSessionStarted=$isSessionStarted") + trySend(isSessionStarted) } - val result = satelliteManager.registerForModemStateChanged( + val registerResult = satelliteManager.registerForModemStateChanged( defaultDispatcher.asExecutor(), callback ) - Log.i(TAG, "Call registerForModemStateChanged: result=$result") + + if (registerResult != SatelliteManager.SATELLITE_RESULT_SUCCESS) { + // If the registration failed (e.g., device doesn't support satellite), + // SatelliteManager will not emit the current state by callback. + // We send `false` value by ourself to make sure the flow has initial value. + Log.w(TAG, "Failed to register for satellite modem state change: $registerResult") + trySend(false) + } awaitClose { satelliteManager.unregisterForModemStateChanged(callback) } - } - } - - /** - * Converts a [SatelliteManager.SatelliteModemState] to a boolean representing whether the modem - * is enabled. - * - * @param state The SatelliteModemState provided by the SatelliteManager. - * @return `true` if the modem is enabled, `false` otherwise. - */ - @VisibleForTesting - fun convertSatelliteModemStateToEnabledState( - @SatelliteManager.SatelliteModemState state: Int, - ): Boolean { - // Mapping table based on logic from b/315928920#comment24 - return when (state) { - SatelliteManager.SATELLITE_MODEM_STATE_IDLE, - SatelliteManager.SATELLITE_MODEM_STATE_LISTENING, - SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING, - SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_RETRYING, - SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED, - SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED -> true - else -> false - } + }.flowOn(Dispatchers.Default) } /** diff --git a/src/com/android/settings/network/telephony/MobileNetworkSwitchController.kt b/src/com/android/settings/network/telephony/MobileNetworkSwitchController.kt index 41cef508493..447909e5aaf 100644 --- a/src/com/android/settings/network/telephony/MobileNetworkSwitchController.kt +++ b/src/com/android/settings/network/telephony/MobileNetworkSwitchController.kt @@ -59,7 +59,7 @@ class MobileNetworkSwitchController @JvmOverloads constructor( val changeable by remember { combine( context.callStateFlow(subId).map { it == TelephonyManager.CALL_STATE_IDLE }, - satelliteRepository.getIsModemEnabledFlow() + satelliteRepository.getIsSessionStartedFlow() ) { isCallStateIdle, isSatelliteModemEnabled -> isCallStateIdle && !isSatelliteModemEnabled } diff --git a/tests/robotests/src/com/android/settings/network/SatelliteRepositoryTest.kt b/tests/robotests/src/com/android/settings/network/SatelliteRepositoryTest.kt index 3c947ab4e28..62fd10a951c 100644 --- a/tests/robotests/src/com/android/settings/network/SatelliteRepositoryTest.kt +++ b/tests/robotests/src/com/android/settings/network/SatelliteRepositoryTest.kt @@ -120,7 +120,7 @@ class SatelliteRepositoryTest { @Test fun requestIsSessionStarted_registerFailed() = runBlocking { `when`(mockSatelliteManager.registerForModemStateChanged(any(), any()) - ).thenAnswer { invocation -> + ).thenAnswer { SatelliteManager.SATELLITE_RESULT_ERROR } @@ -187,7 +187,7 @@ class SatelliteRepositoryTest { } @Test - fun getIsModemEnabledFlow_isSatelliteEnabledState() = runBlocking { + fun getIsSessionStartedFlow_isSatelliteEnabledState() = runBlocking { `when`( mockSatelliteManager.registerForModemStateChanged( any(), @@ -199,13 +199,13 @@ class SatelliteRepositoryTest { SatelliteManager.SATELLITE_RESULT_SUCCESS } - val flow = repository.getIsModemEnabledFlow() + val flow = repository.getIsSessionStartedFlow() assertThat(flow.first()).isTrue() } @Test - fun getIsModemEnabledFlow_isSatelliteDisabledState() = runBlocking { + fun getIsSessionStartedFlow_isSatelliteDisabledState() = runBlocking { `when`( mockSatelliteManager.registerForModemStateChanged( any(), @@ -217,16 +217,28 @@ class SatelliteRepositoryTest { SatelliteManager.SATELLITE_RESULT_SUCCESS } - val flow = repository.getIsModemEnabledFlow() + val flow = repository.getIsSessionStartedFlow() assertThat(flow.first()).isFalse() } @Test - fun getIsModemEnabledFlow_nullSatelliteManager() = runBlocking { + fun getIsSessionStartedFlow_nullSatelliteManager() = runBlocking { `when`(spyContext.getSystemService(SatelliteManager::class.java)).thenReturn(null) - val flow = repository.getIsModemEnabledFlow() + val flow = repository.getIsSessionStartedFlow() + assertThat(flow.first()).isFalse() + } + + @Test + fun getIsSessionStartedFlow_registerFailed() = runBlocking { + `when`(mockSatelliteManager.registerForModemStateChanged(any(), any()) + ).thenAnswer { + SatelliteManager.SATELLITE_RESULT_ERROR + } + + val flow = repository.getIsSessionStartedFlow() + assertThat(flow.first()).isFalse() } } \ No newline at end of file