Loading packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImpl.kt +54 −19 Original line number Diff line number Diff line Loading @@ -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: " + Loading @@ -359,6 +365,7 @@ constructor( var registered = false try { logBuffer.i { "registerForProvisionStateChanged" } sm.registerForProvisionStateChanged( bgDispatcher.asExecutor(), callback, Loading @@ -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 Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImplTest.kt +143 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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) Loading Loading @@ -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 Loading Loading @@ -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> = Loading @@ -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 = Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImpl.kt +54 −19 Original line number Diff line number Diff line Loading @@ -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: " + Loading @@ -359,6 +365,7 @@ constructor( var registered = false try { logBuffer.i { "registerForProvisionStateChanged" } sm.registerForProvisionStateChanged( bgDispatcher.asExecutor(), callback, Loading @@ -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 Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImplTest.kt +143 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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) Loading Loading @@ -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 Loading Loading @@ -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> = Loading @@ -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 = Loading