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

Commit 3c0370b1 authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Delay releasing validation network request to ensure smooth switch." am: 5422389a

Change-Id: Icaa8ee565e381137c6c152be7e28f63b5d5a3fe0
parents 75b30329 5422389a
Loading
Loading
Loading
Loading
+18 −29
Original line number Diff line number Diff line
@@ -85,8 +85,6 @@ public class CellularNetworkValidator {
    public Handler mHandler = new Handler();
    @VisibleForTesting
    public ConnectivityNetworkCallback mNetworkCallback;
    @VisibleForTesting
    public Runnable mTimeoutCallback;
    private final ValidatedNetworkCache mValidatedNetworkCache = new ValidatedNetworkCache();

    private class ValidatedNetworkCache {
@@ -116,7 +114,7 @@ public class CellularNetworkValidator {
            long mValidationTimeStamp;
        }

        boolean isRecentlyValidated(int subId) {
        synchronized boolean isRecentlyValidated(int subId) {
            long cacheTtl = getValidationCacheTtl(subId);
            String networkIdentity = getValidationNetworkIdentity(subId);
            if (networkIdentity == null || !mValidatedNetworkMap.containsKey(networkIdentity)) {
@@ -128,7 +126,7 @@ public class CellularNetworkValidator {
            return recentlyValidated;
        }

        void storeLastValidationResult(int subId, boolean validated) {
        synchronized void storeLastValidationResult(int subId, boolean validated) {
            String networkIdentity = getValidationNetworkIdentity(subId);
            logd("storeLastValidationResult for subId " + subId
                    + (validated ? " validated." : " not validated."));
@@ -284,23 +282,14 @@ public class CellularNetworkValidator {
        mNetworkCallback = new ConnectivityNetworkCallback(subId);

        mConnectivityManager.requestNetwork(mNetworkRequest, mNetworkCallback, mHandler);
        mHandler.postDelayed(() -> onValidationTimeout(subId), mTimeoutInMs);
    }

        mTimeoutCallback = () -> {
    private synchronized void onValidationTimeout(int subId) {
        logd("timeout on subId " + subId + " validation.");
        // Remember latest validated network.
        mValidatedNetworkCache.storeLastValidationResult(subId, false);
        reportValidationResult(false, subId);
        };

        mHandler.postDelayed(mTimeoutCallback, mTimeoutInMs);
    }

    private void removeTimeoutCallback() {
        // Remove timeout callback.
        if (mTimeoutCallback != null) {
            mHandler.removeCallbacks(mTimeoutCallback);
            mTimeoutCallback = null;
        }
    }

    /**
@@ -309,12 +298,13 @@ public class CellularNetworkValidator {
    public synchronized void stopValidation() {
        if (!isValidating()) {
            logd("No need to stop validation.");
        } else {
            return;
        }
        if (mNetworkCallback != null) {
            mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
            mState = STATE_IDLE;
        }

        removeTimeoutCallback();
        mState = STATE_IDLE;
        mHandler.removeCallbacksAndMessages(null);
        mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
    }

@@ -345,25 +335,24 @@ public class CellularNetworkValidator {
        // If the validation result is not for current subId, do nothing.
        if (mSubId != subId) return;

        removeTimeoutCallback();
        mHandler.removeCallbacksAndMessages(null);

        // Deal with the result only when state is still VALIDATING. This is to avoid
        // receiving multiple callbacks in queue.
        if (mState == STATE_VALIDATING) {
            mValidationCallback.onValidationDone(passed, mSubId);
            if (!mReleaseAfterValidation && passed) {
            mState = STATE_VALIDATED;
            // If validation passed and per request to NOT release after validation, delay cleanup.
            if (!mReleaseAfterValidation && passed) {
                mHandler.postDelayed(()-> stopValidation(), 500);
            } else {
                mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
                mState = STATE_IDLE;
                stopValidation();
            }

            TelephonyMetrics.getInstance().writeNetworkValidate(passed
                    ? TelephonyEvent.NetworkValidationState.NETWORK_VALIDATION_STATE_PASSED
                    : TelephonyEvent.NetworkValidationState.NETWORK_VALIDATION_STATE_FAILED);
        }

        mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
    }

    private synchronized void reportNetworkAvailable(Network network, int subId) {
+0 −1
Original line number Diff line number Diff line
@@ -1282,7 +1282,6 @@ public class PhoneSwitcher extends Handler {
            return;
        }
        confirmSwitch(subId, true);
        mValidator.stopValidation();
    }

    private void onValidationDone(int subId, boolean passed) {
+91 −63
Original line number Diff line number Diff line
@@ -22,10 +22,12 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;

import android.content.Context;
@@ -104,99 +106,46 @@ public class CellularNetworkValidatorTest extends TelephonyTest {
    public void testValidateSuccess() {
        int subId = 1;
        int timeout = 1000;
        NetworkRequest expectedRequest = new NetworkRequest.Builder()
                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                .setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
                        .setSubscriptionId(subId).build())
                .build();

        mValidatorUT.validate(subId, timeout, true, mCallback);

        assertTrue(mValidatorUT.isValidating());
        assertEquals(subId, mValidatorUT.getSubIdInValidation());
        verify(mConnectivityManager).requestNetwork(
                eq(expectedRequest), eq(mValidatorUT.mNetworkCallback), any());
        assertInValidation(subId);

        mValidatorUT.mNetworkCallback.onCapabilitiesChanged(null, new NetworkCapabilities()
                .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED));

        assertValidationResult(subId, true);
    }

    /**
     * Test that a single phone case results in our phone being active and the RIL called
     */
    @Test
    @SmallTest
    public void testValidateTimeout() {
        int subId = 1;
        int timeout = 100;
        NetworkRequest expectedRequest = new NetworkRequest.Builder()
                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                .setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
                        .setSubscriptionId(subId).build())
                .build();

        mValidatorUT.validate(subId, timeout, true, mCallback);
        assertInValidation(subId);

        // Wait for timeout
        moveTimeForward(timeout);
        processAllMessages();

        assertValidationResult(subId, false);
    }

    /**
     * Test that a single phone case results in our phone being active and the RIL called
     */
    @Test
    @SmallTest
    public void testValidateFailure() {
        int subId = 1;
        int timeout = 100;
        NetworkRequest expectedRequest = new NetworkRequest.Builder()
                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                .setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
                        .setSubscriptionId(subId).build())
                .build();

        mValidatorUT.validate(subId, timeout, true, mCallback);

        assertTrue(mValidatorUT.isValidating());
        assertEquals(subId, mValidatorUT.getSubIdInValidation());
        verify(mConnectivityManager).requestNetwork(
                eq(expectedRequest), eq(mValidatorUT.mNetworkCallback), any());

        assertInValidation(subId);
        mValidatorUT.mNetworkCallback.onUnavailable();

        assertValidationResult(subId, false);
    }

    /**
     * Test that a single phone case results in our phone being active and the RIL called
     */
    @Test
    @SmallTest
    public void testNetworkAvailableNotValidated() {
        int subId = 1;
        int timeout = 100;
        NetworkRequest expectedRequest = new NetworkRequest.Builder()
                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                .setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
                        .setSubscriptionId(subId).build())
                .build();

        mValidatorUT.validate(subId, timeout, true, mCallback);

        assertTrue(mValidatorUT.isValidating());
        assertEquals(subId, mValidatorUT.getSubIdInValidation());
        verify(mConnectivityManager).requestNetwork(
                eq(expectedRequest), eq(mValidatorUT.mNetworkCallback), any());
        assertInValidation(subId);

        mValidatorUT.mNetworkCallback.onAvailable(new Network(100));
        assertInValidation(subId);
@@ -212,7 +161,6 @@ public class CellularNetworkValidatorTest extends TelephonyTest {
    @SmallTest
    public void testSkipRecentlyValidatedNetwork() {
        int subId = 1;
        int slotId = 0;
        int timeout = 1000;
        mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
@@ -236,7 +184,6 @@ public class CellularNetworkValidatorTest extends TelephonyTest {
    @SmallTest
    public void testDoNotSkipIfValidationFailed() {
        int subId = 1;
        int slotId = 0;
        int timeout = 1000;
        mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
@@ -257,9 +204,8 @@ public class CellularNetworkValidatorTest extends TelephonyTest {

    @Test
    @SmallTest
    public void testDoNotSkipIfCachExpires() {
    public void testDoNotSkipIfCacheExpires() {
        int subId = 1;
        int slotId = 0;
        int timeout = 1000;
        mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
@@ -286,7 +232,6 @@ public class CellularNetworkValidatorTest extends TelephonyTest {
    @Test
    @SmallTest
    public void testNetworkCachingOfMultipleSub() {
        int slotId = 0;
        int timeout = 1000;
        mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
@@ -413,6 +358,80 @@ public class CellularNetworkValidatorTest extends TelephonyTest {
        verify(mCallback).onNetworkAvailable(network, subId);
    }

    @Test
    @SmallTest
    public void testReleaseRequestAfterValidation_shouldReleaseImmediately() {
        int subId = 1;
        int timeout = 1000;
        mValidatorUT.validate(subId, timeout, true, mCallback);
        mValidatorUT.mNetworkCallback.onCapabilitiesChanged(null, new NetworkCapabilities()
                .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED));
        assertValidationResult(subId, true);
    }

    @Test
    @SmallTest
    public void testDoNotReleaseRequestAfterValidation_shouldReleaseLater() {
        int subId = 1;
        int timeout = 1000;
        mValidatorUT.validate(subId, timeout, false, mCallback);
        mValidatorUT.mNetworkCallback.onCapabilitiesChanged(null, new NetworkCapabilities()
                .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED));
        verify(mCallback).onValidationDone(true, subId);
        assertInValidation(subId);
        moveTimeForward(1000);
        processAllMessages();
        assertValidationResult(subId, true);
    }

    @Test
    @SmallTest
    public void testDoNotReleaseRequestAfterValidation_validationFails_shouldReleaseImmediately() {
        int subId = 1;
        int timeout = 1000;
        mValidatorUT.validate(subId, timeout, false, mCallback);
        mValidatorUT.mNetworkCallback.onLost(new Network(100));
        assertValidationResult(subId, false);
    }

    @Test
    @SmallTest
    public void testDoNotReleaseRequestAfterValidation_timeout_shouldReleaseImmediately() {
        int subId = 1;
        int timeout = 1000;
        mValidatorUT.validate(subId, timeout, false, mCallback);
        assertInValidation(subId);
        moveTimeForward(timeout);
        processAllMessages();
        assertValidationResult(subId, false);
    }

    @Test
    @SmallTest
    public void testDoNotReleaseRequestAfterValidation_BackToBackRequest() {
        int subId1 = 1;
        int timeout = 1000;
        mValidatorUT.validate(subId1, timeout, false, mCallback);
        mValidatorUT.mNetworkCallback.onCapabilitiesChanged(null, new NetworkCapabilities()
                .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED));
        verify(mCallback).onValidationDone(true, subId1);
        assertInValidation(subId1);

        resetStates();
        int subId2 = 2;
        mValidatorUT.validate(subId2, timeout, false, mCallback);
        assertInValidation(subId2);
        mValidatorUT.mNetworkCallback.onCapabilitiesChanged(null, new NetworkCapabilities()
                .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED));
        verify(mCallback).onValidationDone(true, subId2);
        assertInValidation(subId2);
        moveTimeForward(1000);
        processAllMessages();
        assertValidationResult(subId2, true);
        // No callback should be triggered on subId1
        verify(mCallback, never()).onValidationDone(anyBoolean(), eq(subId1));
    }

    private void assertNetworkRecentlyValidated(int subId, boolean shouldBeRecentlyValidated) {
        // Start validation and send network available callback.
        resetStates();
@@ -432,7 +451,7 @@ public class CellularNetworkValidatorTest extends TelephonyTest {
    private void assertValidationResult(int subId, boolean shouldPass) {
        // Verify that validation is over.
        verify(mConnectivityManager).unregisterNetworkCallback(eq(mValidatorUT.mNetworkCallback));
        assertFalse(mValidatorUT.mHandler.hasCallbacks(mValidatorUT.mTimeoutCallback));
        assertFalse(mValidatorUT.mHandler.hasMessagesOrCallbacks());
        assertFalse(mValidatorUT.isValidating());
        assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID,
                mValidatorUT.getSubIdInValidation());
@@ -443,7 +462,16 @@ public class CellularNetworkValidatorTest extends TelephonyTest {

    private void assertInValidation(int subId) {
        assertEquals(subId, mValidatorUT.getSubIdInValidation());
        assertTrue(mValidatorUT.mHandler.hasCallbacks(mValidatorUT.mTimeoutCallback));
        assertTrue(mValidatorUT.mHandler.hasMessagesOrCallbacks());
        assertEquals(subId, mValidatorUT.getSubIdInValidation());
        NetworkRequest expectedRequest = new NetworkRequest.Builder()
                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                .setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
                        .setSubscriptionId(subId).build())
                .build();
        verify(mConnectivityManager).requestNetwork(
                eq(expectedRequest), eq(mValidatorUT.mNetworkCallback), any());
        assertTrue(mValidatorUT.isValidating());
    }

+0 −1
Original line number Diff line number Diff line
@@ -959,7 +959,6 @@ public class PhoneSwitcherTest extends TelephonyTest {
        mPhoneSwitcher.mValidationCallback.onNetworkAvailable(null, 2);
        processAllMessages();
        verify(mMockRadioConfig).setPreferredDataModem(eq(1), any());
        verify(mCellularNetworkValidator).stopValidation();
    }

    @Test