Loading src/java/com/android/internal/telephony/satellite/SatelliteController.java +98 −1 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ import android.os.IBinder; import android.os.ICancellationSignal; import android.os.Looper; import android.os.Message; import android.os.OutcomeReceiver; import android.os.PersistableBundle; import android.os.Registrant; import android.os.RegistrantList; Loading Loading @@ -235,6 +236,7 @@ public class SatelliteController extends Handler { private static final int EVENT_PROVISION_SATELLITE_TOKEN_UPDATED = 45; private static final int EVENT_NOTIFY_NTN_ELIGIBILITY_HYSTERESIS_TIMED_OUT = 46; private static final int EVENT_WIFI_CONNECTIVITY_STATE_CHANGED = 47; private static final int EVENT_SATELLITE_ACCESS_RESTRICTION_CHECKING_RESULT = 48; @NonNull private static SatelliteController sInstance; @NonNull private final Context mContext; Loading Loading @@ -409,6 +411,10 @@ public class SatelliteController extends Handler { */ @GuardedBy("mSatellitePhoneLock") private Boolean mLastNotifiedNtnEligibility = null; @GuardedBy("mSatellitePhoneLock") private boolean mNtnEligibilityHysteresisTimedOut = false; @GuardedBy("mSatellitePhoneLock") private boolean mCheckingAccessRestrictionInProgress = false; @GuardedBy("mSatelliteConnectedLock") @NonNull private final Map<Integer, CarrierRoamingSatelliteSessionStats> Loading Loading @@ -1536,11 +1542,12 @@ public class SatelliteController extends Handler { case EVENT_NOTIFY_NTN_ELIGIBILITY_HYSTERESIS_TIMED_OUT: { synchronized (mSatellitePhoneLock) { mNtnEligibilityHysteresisTimedOut = true; boolean eligible = isCarrierRoamingNtnEligible(mSatellitePhone); plogd("EVENT_NOTIFY_NTN_ELIGIBILITY_HYSTERESIS_TIMED_OUT:" + " isCarrierRoamingNtnEligible=" + eligible); if (eligible) { updateLastNotifiedNtnEligibilityAndNotify(true); requestIsSatelliteAllowedForCurrentLocation(); } } break; Loading Loading @@ -1603,6 +1610,10 @@ public class SatelliteController extends Handler { } break; } case EVENT_SATELLITE_ACCESS_RESTRICTION_CHECKING_RESULT: { handleSatelliteAccessRestrictionCheckingResult((boolean) msg.obj); break; } default: Log.w(TAG, "SatelliteControllerHandler: unexpected message code: " + Loading Loading @@ -4724,6 +4735,7 @@ public class SatelliteController extends Handler { startNtnEligibilityHysteresisTimer(); } } else { mNtnEligibilityHysteresisTimedOut = false; stopNtnEligibilityHysteresisTimer(); updateLastNotifiedNtnEligibilityAndNotify(false); } Loading Loading @@ -4758,6 +4770,7 @@ public class SatelliteController extends Handler { int subId = mSatellitePhone.getSubId(); long timeout = getCarrierSupportedSatelliteNotificationHysteresisTimeMillis(subId); mNtnEligibilityHysteresisTimedOut = false; plogd("startNtnEligibilityHysteresisTimer: sendMessageDelayed subId=" + subId + ", phoneId=" + mSatellitePhone.getPhoneId() + ", timeout=" + timeout); sendMessageDelayed(obtainMessage(EVENT_NOTIFY_NTN_ELIGIBILITY_HYSTERESIS_TIMED_OUT), Loading Loading @@ -5559,6 +5572,26 @@ public class SatelliteController extends Handler { result.send(SATELLITE_RESULT_SUCCESS, bundle); } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) protected boolean isSubscriptionProvisioned(int subId) { plogd("isSubscriptionProvisioned: subId=" + subId); if (!mFeatureFlags.carrierRoamingNbIotNtn()) { plogd("isSubscriptionProvisioned: carrierRoamingNbIotNtn flag is disabled"); return false; } String subscriberId = getSubscriberId( mSubscriptionManagerService.getSubscriptionInfo(subId)); if (subscriberId.isEmpty()) { plogd("isSubscriptionProvisioned: subId=" + subId + " subscriberId is empty."); return false; } synchronized (mSatelliteTokenProvisionedLock) { return mProvisionedSubscriberId.getOrDefault(subscriberId, false); } } /** * Deliver the list of provisioned satellite subscriber ids. * Loading Loading @@ -5632,6 +5665,12 @@ public class SatelliteController extends Handler { return false; } if (!isSubscriptionProvisioned(subId)) { plogd("isCarrierRoamingNtnEligible[phoneId=" + phone.getPhoneId() + "]: subscription is not provisioned to use satellite."); return false; } if (!isSatelliteServiceSupportedByCarrier(subId, NetworkRegistrationInfo.SERVICE_TYPE_SMS)) { plogd("isCarrierRoamingNtnEligible[phoneId=" + phone.getPhoneId() Loading Loading @@ -5673,4 +5712,62 @@ public class SatelliteController extends Handler { } return false; } private void requestIsSatelliteAllowedForCurrentLocation() { plogd("requestIsSatelliteAllowedForCurrentLocation()"); synchronized (mSatellitePhoneLock) { if (mCheckingAccessRestrictionInProgress) { plogd("requestIsSatelliteCommunicationAllowedForCurrentLocation was already sent"); return; } mCheckingAccessRestrictionInProgress = true; } OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> callback = new OutcomeReceiver<>() { @Override public void onResult(Boolean result) { plogd("requestIsSatelliteAllowedForCurrentLocation: result=" + result); sendMessage(obtainMessage( EVENT_SATELLITE_ACCESS_RESTRICTION_CHECKING_RESULT, result)); } @Override public void onError(SatelliteManager.SatelliteException ex) { plogd("requestIsSatelliteAllowedForCurrentLocation: onError, ex=" + ex); sendMessage(obtainMessage( EVENT_SATELLITE_ACCESS_RESTRICTION_CHECKING_RESULT, false)); } }; requestIsSatelliteCommunicationAllowedForCurrentLocation(callback); } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) protected void requestIsSatelliteCommunicationAllowedForCurrentLocation( @NonNull OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> callback) { SatelliteManager satelliteManager = mContext.getSystemService(SatelliteManager.class); if (satelliteManager == null) { ploge("requestIsSatelliteCommunicationAllowedForCurrentLocation: " + "SatelliteManager is null"); return; } satelliteManager.requestIsCommunicationAllowedForCurrentLocation( this::post, callback); } private void handleSatelliteAccessRestrictionCheckingResult(boolean satelliteAllowed) { synchronized (mSatellitePhoneLock) { mCheckingAccessRestrictionInProgress = false; boolean eligible = isCarrierRoamingNtnEligible(mSatellitePhone); plogd("handleSatelliteAccessRestrictionCheckingResult:" + " satelliteAllowed=" + satelliteAllowed + ", isCarrierRoamingNtnEligible=" + eligible + ", mNtnEligibilityHysteresisTimedOut=" + mNtnEligibilityHysteresisTimedOut); if (satelliteAllowed && eligible && mNtnEligibilityHysteresisTimedOut) { updateLastNotifiedNtnEligibilityAndNotify(true); mNtnEligibilityHysteresisTimedOut = false; } } } } tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java +49 −0 Original line number Diff line number Diff line Loading @@ -102,6 +102,7 @@ import android.os.Handler; import android.os.ICancellationSignal; import android.os.Looper; import android.os.Message; import android.os.OutcomeReceiver; import android.os.PersistableBundle; import android.os.RemoteException; import android.os.ResultReceiver; Loading Loading @@ -3849,6 +3850,7 @@ public class SatelliteControllerTest extends TelephonyTest { /*slotIndex*/ 0, /*subId*/ SUB_ID, /*carrierId*/ 0, /*specificCarrierId*/ 0) ); } mSatelliteControllerUT.setSatellitePhone(1); processAllMessages(); assertTrue(mSatelliteControllerUT.isCarrierRoamingNtnEligible(mPhone)); Loading Loading @@ -3881,6 +3883,7 @@ public class SatelliteControllerTest extends TelephonyTest { ); } mSatelliteControllerUT.setSatellitePhone(1); mSatelliteControllerUT.isSatelliteAllowedCallback = null; processAllMessages(); mSatelliteControllerUT.elapsedRealtime = 0; assertTrue(mSatelliteControllerUT.isCarrierRoamingNtnEligible(mPhone)); Loading @@ -3892,6 +3895,10 @@ public class SatelliteControllerTest extends TelephonyTest { mSatelliteControllerUT.elapsedRealtime = 2 * 60 * 1000; moveTimeForward(2 * 60 * 1000); processAllMessages(); assertNotNull(mSatelliteControllerUT.isSatelliteAllowedCallback); mSatelliteControllerUT.isSatelliteAllowedCallback.onResult(true); processAllMessages(); assertTrue(mSatelliteControllerUT.isCarrierRoamingNtnEligible(mPhone)); verify(mPhone, times(1)).notifyCarrierRoamingNtnEligibleStateChanged(eq(true)); verify(mPhone2, times(0)).notifyCarrierRoamingNtnEligibleStateChanged(anyBoolean()); Loading @@ -3903,6 +3910,29 @@ public class SatelliteControllerTest extends TelephonyTest { assertFalse(mSatelliteControllerUT.isCarrierRoamingNtnEligible(mPhone)); verify(mPhone, times(1)).notifyCarrierRoamingNtnEligibleStateChanged(eq(false)); verify(mPhone2, times(0)).notifyCarrierRoamingNtnEligibleStateChanged(anyBoolean()); // isSatelliteAllowedCallback.onError() returns error when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE); sendServiceStateChangedEvent(); processAllMessages(); mSatelliteControllerUT.elapsedRealtime = 0; assertTrue(mSatelliteControllerUT.isCarrierRoamingNtnEligible(mPhone)); verify(mPhone, times(0)).notifyCarrierRoamingNtnEligibleStateChanged(eq(true)); verify(mPhone2, times(0)).notifyCarrierRoamingNtnEligibleStateChanged(anyBoolean()); clearInvocations(mPhone); // 2 minutes later and hysteresis timeout is 1 minute mSatelliteControllerUT.elapsedRealtime = 2 * 60 * 1000; moveTimeForward(2 * 60 * 1000); processAllMessages(); assertNotNull(mSatelliteControllerUT.isSatelliteAllowedCallback); mSatelliteControllerUT.isSatelliteAllowedCallback.onError(new SatelliteException( SATELLITE_RESULT_ERROR)); processAllMessages(); assertTrue(mSatelliteControllerUT.isCarrierRoamingNtnEligible(mPhone)); verify(mPhone, times(0)).notifyCarrierRoamingNtnEligibleStateChanged(eq(true)); verify(mPhone2, times(0)).notifyCarrierRoamingNtnEligibleStateChanged(anyBoolean()); } @Test Loading Loading @@ -4677,6 +4707,7 @@ public class SatelliteControllerTest extends TelephonyTest { public long elapsedRealtime = 0; public int satelliteModeSettingValue = SATELLITE_MODE_ENABLED_FALSE; public boolean setSettingsKeyToAllowDeviceRotationCalled = false; public OutcomeReceiver<Boolean, SatelliteException> isSatelliteAllowedCallback = null; TestSatelliteController( Context context, Looper looper, @NonNull FeatureFlags featureFlags) { Loading Loading @@ -4729,5 +4760,23 @@ public class SatelliteControllerTest extends TelephonyTest { mSatellitePhone = mPhone; } } @Override protected void requestIsSatelliteCommunicationAllowedForCurrentLocation( @NonNull OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> callback) { logd("requestIsSatelliteCommunicationAllowedForCurrentLocation: callback=" + callback); isSatelliteAllowedCallback = callback; } @Override protected boolean isSubscriptionProvisioned(int subId) { synchronized (mSatellitePhoneLock) { if (mSatellitePhone.getSubId() == subId) { return true; } } return false; } } } Loading
src/java/com/android/internal/telephony/satellite/SatelliteController.java +98 −1 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ import android.os.IBinder; import android.os.ICancellationSignal; import android.os.Looper; import android.os.Message; import android.os.OutcomeReceiver; import android.os.PersistableBundle; import android.os.Registrant; import android.os.RegistrantList; Loading Loading @@ -235,6 +236,7 @@ public class SatelliteController extends Handler { private static final int EVENT_PROVISION_SATELLITE_TOKEN_UPDATED = 45; private static final int EVENT_NOTIFY_NTN_ELIGIBILITY_HYSTERESIS_TIMED_OUT = 46; private static final int EVENT_WIFI_CONNECTIVITY_STATE_CHANGED = 47; private static final int EVENT_SATELLITE_ACCESS_RESTRICTION_CHECKING_RESULT = 48; @NonNull private static SatelliteController sInstance; @NonNull private final Context mContext; Loading Loading @@ -409,6 +411,10 @@ public class SatelliteController extends Handler { */ @GuardedBy("mSatellitePhoneLock") private Boolean mLastNotifiedNtnEligibility = null; @GuardedBy("mSatellitePhoneLock") private boolean mNtnEligibilityHysteresisTimedOut = false; @GuardedBy("mSatellitePhoneLock") private boolean mCheckingAccessRestrictionInProgress = false; @GuardedBy("mSatelliteConnectedLock") @NonNull private final Map<Integer, CarrierRoamingSatelliteSessionStats> Loading Loading @@ -1536,11 +1542,12 @@ public class SatelliteController extends Handler { case EVENT_NOTIFY_NTN_ELIGIBILITY_HYSTERESIS_TIMED_OUT: { synchronized (mSatellitePhoneLock) { mNtnEligibilityHysteresisTimedOut = true; boolean eligible = isCarrierRoamingNtnEligible(mSatellitePhone); plogd("EVENT_NOTIFY_NTN_ELIGIBILITY_HYSTERESIS_TIMED_OUT:" + " isCarrierRoamingNtnEligible=" + eligible); if (eligible) { updateLastNotifiedNtnEligibilityAndNotify(true); requestIsSatelliteAllowedForCurrentLocation(); } } break; Loading Loading @@ -1603,6 +1610,10 @@ public class SatelliteController extends Handler { } break; } case EVENT_SATELLITE_ACCESS_RESTRICTION_CHECKING_RESULT: { handleSatelliteAccessRestrictionCheckingResult((boolean) msg.obj); break; } default: Log.w(TAG, "SatelliteControllerHandler: unexpected message code: " + Loading Loading @@ -4724,6 +4735,7 @@ public class SatelliteController extends Handler { startNtnEligibilityHysteresisTimer(); } } else { mNtnEligibilityHysteresisTimedOut = false; stopNtnEligibilityHysteresisTimer(); updateLastNotifiedNtnEligibilityAndNotify(false); } Loading Loading @@ -4758,6 +4770,7 @@ public class SatelliteController extends Handler { int subId = mSatellitePhone.getSubId(); long timeout = getCarrierSupportedSatelliteNotificationHysteresisTimeMillis(subId); mNtnEligibilityHysteresisTimedOut = false; plogd("startNtnEligibilityHysteresisTimer: sendMessageDelayed subId=" + subId + ", phoneId=" + mSatellitePhone.getPhoneId() + ", timeout=" + timeout); sendMessageDelayed(obtainMessage(EVENT_NOTIFY_NTN_ELIGIBILITY_HYSTERESIS_TIMED_OUT), Loading Loading @@ -5559,6 +5572,26 @@ public class SatelliteController extends Handler { result.send(SATELLITE_RESULT_SUCCESS, bundle); } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) protected boolean isSubscriptionProvisioned(int subId) { plogd("isSubscriptionProvisioned: subId=" + subId); if (!mFeatureFlags.carrierRoamingNbIotNtn()) { plogd("isSubscriptionProvisioned: carrierRoamingNbIotNtn flag is disabled"); return false; } String subscriberId = getSubscriberId( mSubscriptionManagerService.getSubscriptionInfo(subId)); if (subscriberId.isEmpty()) { plogd("isSubscriptionProvisioned: subId=" + subId + " subscriberId is empty."); return false; } synchronized (mSatelliteTokenProvisionedLock) { return mProvisionedSubscriberId.getOrDefault(subscriberId, false); } } /** * Deliver the list of provisioned satellite subscriber ids. * Loading Loading @@ -5632,6 +5665,12 @@ public class SatelliteController extends Handler { return false; } if (!isSubscriptionProvisioned(subId)) { plogd("isCarrierRoamingNtnEligible[phoneId=" + phone.getPhoneId() + "]: subscription is not provisioned to use satellite."); return false; } if (!isSatelliteServiceSupportedByCarrier(subId, NetworkRegistrationInfo.SERVICE_TYPE_SMS)) { plogd("isCarrierRoamingNtnEligible[phoneId=" + phone.getPhoneId() Loading Loading @@ -5673,4 +5712,62 @@ public class SatelliteController extends Handler { } return false; } private void requestIsSatelliteAllowedForCurrentLocation() { plogd("requestIsSatelliteAllowedForCurrentLocation()"); synchronized (mSatellitePhoneLock) { if (mCheckingAccessRestrictionInProgress) { plogd("requestIsSatelliteCommunicationAllowedForCurrentLocation was already sent"); return; } mCheckingAccessRestrictionInProgress = true; } OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> callback = new OutcomeReceiver<>() { @Override public void onResult(Boolean result) { plogd("requestIsSatelliteAllowedForCurrentLocation: result=" + result); sendMessage(obtainMessage( EVENT_SATELLITE_ACCESS_RESTRICTION_CHECKING_RESULT, result)); } @Override public void onError(SatelliteManager.SatelliteException ex) { plogd("requestIsSatelliteAllowedForCurrentLocation: onError, ex=" + ex); sendMessage(obtainMessage( EVENT_SATELLITE_ACCESS_RESTRICTION_CHECKING_RESULT, false)); } }; requestIsSatelliteCommunicationAllowedForCurrentLocation(callback); } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) protected void requestIsSatelliteCommunicationAllowedForCurrentLocation( @NonNull OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> callback) { SatelliteManager satelliteManager = mContext.getSystemService(SatelliteManager.class); if (satelliteManager == null) { ploge("requestIsSatelliteCommunicationAllowedForCurrentLocation: " + "SatelliteManager is null"); return; } satelliteManager.requestIsCommunicationAllowedForCurrentLocation( this::post, callback); } private void handleSatelliteAccessRestrictionCheckingResult(boolean satelliteAllowed) { synchronized (mSatellitePhoneLock) { mCheckingAccessRestrictionInProgress = false; boolean eligible = isCarrierRoamingNtnEligible(mSatellitePhone); plogd("handleSatelliteAccessRestrictionCheckingResult:" + " satelliteAllowed=" + satelliteAllowed + ", isCarrierRoamingNtnEligible=" + eligible + ", mNtnEligibilityHysteresisTimedOut=" + mNtnEligibilityHysteresisTimedOut); if (satelliteAllowed && eligible && mNtnEligibilityHysteresisTimedOut) { updateLastNotifiedNtnEligibilityAndNotify(true); mNtnEligibilityHysteresisTimedOut = false; } } } }
tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java +49 −0 Original line number Diff line number Diff line Loading @@ -102,6 +102,7 @@ import android.os.Handler; import android.os.ICancellationSignal; import android.os.Looper; import android.os.Message; import android.os.OutcomeReceiver; import android.os.PersistableBundle; import android.os.RemoteException; import android.os.ResultReceiver; Loading Loading @@ -3849,6 +3850,7 @@ public class SatelliteControllerTest extends TelephonyTest { /*slotIndex*/ 0, /*subId*/ SUB_ID, /*carrierId*/ 0, /*specificCarrierId*/ 0) ); } mSatelliteControllerUT.setSatellitePhone(1); processAllMessages(); assertTrue(mSatelliteControllerUT.isCarrierRoamingNtnEligible(mPhone)); Loading Loading @@ -3881,6 +3883,7 @@ public class SatelliteControllerTest extends TelephonyTest { ); } mSatelliteControllerUT.setSatellitePhone(1); mSatelliteControllerUT.isSatelliteAllowedCallback = null; processAllMessages(); mSatelliteControllerUT.elapsedRealtime = 0; assertTrue(mSatelliteControllerUT.isCarrierRoamingNtnEligible(mPhone)); Loading @@ -3892,6 +3895,10 @@ public class SatelliteControllerTest extends TelephonyTest { mSatelliteControllerUT.elapsedRealtime = 2 * 60 * 1000; moveTimeForward(2 * 60 * 1000); processAllMessages(); assertNotNull(mSatelliteControllerUT.isSatelliteAllowedCallback); mSatelliteControllerUT.isSatelliteAllowedCallback.onResult(true); processAllMessages(); assertTrue(mSatelliteControllerUT.isCarrierRoamingNtnEligible(mPhone)); verify(mPhone, times(1)).notifyCarrierRoamingNtnEligibleStateChanged(eq(true)); verify(mPhone2, times(0)).notifyCarrierRoamingNtnEligibleStateChanged(anyBoolean()); Loading @@ -3903,6 +3910,29 @@ public class SatelliteControllerTest extends TelephonyTest { assertFalse(mSatelliteControllerUT.isCarrierRoamingNtnEligible(mPhone)); verify(mPhone, times(1)).notifyCarrierRoamingNtnEligibleStateChanged(eq(false)); verify(mPhone2, times(0)).notifyCarrierRoamingNtnEligibleStateChanged(anyBoolean()); // isSatelliteAllowedCallback.onError() returns error when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE); sendServiceStateChangedEvent(); processAllMessages(); mSatelliteControllerUT.elapsedRealtime = 0; assertTrue(mSatelliteControllerUT.isCarrierRoamingNtnEligible(mPhone)); verify(mPhone, times(0)).notifyCarrierRoamingNtnEligibleStateChanged(eq(true)); verify(mPhone2, times(0)).notifyCarrierRoamingNtnEligibleStateChanged(anyBoolean()); clearInvocations(mPhone); // 2 minutes later and hysteresis timeout is 1 minute mSatelliteControllerUT.elapsedRealtime = 2 * 60 * 1000; moveTimeForward(2 * 60 * 1000); processAllMessages(); assertNotNull(mSatelliteControllerUT.isSatelliteAllowedCallback); mSatelliteControllerUT.isSatelliteAllowedCallback.onError(new SatelliteException( SATELLITE_RESULT_ERROR)); processAllMessages(); assertTrue(mSatelliteControllerUT.isCarrierRoamingNtnEligible(mPhone)); verify(mPhone, times(0)).notifyCarrierRoamingNtnEligibleStateChanged(eq(true)); verify(mPhone2, times(0)).notifyCarrierRoamingNtnEligibleStateChanged(anyBoolean()); } @Test Loading Loading @@ -4677,6 +4707,7 @@ public class SatelliteControllerTest extends TelephonyTest { public long elapsedRealtime = 0; public int satelliteModeSettingValue = SATELLITE_MODE_ENABLED_FALSE; public boolean setSettingsKeyToAllowDeviceRotationCalled = false; public OutcomeReceiver<Boolean, SatelliteException> isSatelliteAllowedCallback = null; TestSatelliteController( Context context, Looper looper, @NonNull FeatureFlags featureFlags) { Loading Loading @@ -4729,5 +4760,23 @@ public class SatelliteControllerTest extends TelephonyTest { mSatellitePhone = mPhone; } } @Override protected void requestIsSatelliteCommunicationAllowedForCurrentLocation( @NonNull OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> callback) { logd("requestIsSatelliteCommunicationAllowedForCurrentLocation: callback=" + callback); isSatelliteAllowedCallback = callback; } @Override protected boolean isSubscriptionProvisioned(int subId) { synchronized (mSatellitePhoneLock) { if (mSatellitePhone.getSubId() == subId) { return true; } } return false; } } }