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

Commit 24849861 authored by Malcolm Chen's avatar Malcolm Chen Committed by Xiangyu/Malcolm Chen
Browse files

In CellularNetworkValidator, handle back to back request.

If back to back requests are sent to CellularNetworkValidator,
it will stop the previous validation silently and restart validation
on the latest subscription. To make it work, a per subscription
NetworkCallback will be created for each validation so that when
old validation result comes in, we can compare the validated subId
agains the latest and avoid race condition.

Bug: 122255288
Test: unittest
Change-Id: Ie128e0ab03c4ca3eed55be1a88bda35283abab06
Merged-In: Ie128e0ab03c4ca3eed55be1a88bda35283abab06
parent 62eb37c4
Loading
Loading
Loading
Loading
+53 −39
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ import android.util.Log;
 * validation process. It listens request on a specific subId, sends a network request
 * to Connectivity and listens to its callback or timeout.
 */
public class CellularNetworkValidator extends ConnectivityManager.NetworkCallback  {
public class CellularNetworkValidator {
    private static final String LOG_TAG = "NetworkValidator";

    // States of validator. Only one validation can happen at once.
@@ -56,6 +56,7 @@ public class CellularNetworkValidator extends ConnectivityManager.NetworkCallbac
    private Context mContext;
    private ConnectivityManager mConnectivityManager;
    private Handler mHandler = new Handler();
    private ConnectivityNetworkCallback mNetworkCallback;

    /**
     * Callback to pass in when starting validation.
@@ -109,12 +110,6 @@ public class CellularNetworkValidator extends ConnectivityManager.NetworkCallbac
        // If it's already validating the same subscription, do nothing.
        if (subId == mSubId) return;

        if (isValidating()) {
            logd("Failed to start validation. Already validating sub " + mSubId);
            callback.onValidationResult(false, subId);
            return;
        }

        Phone phone = PhoneFactory.getPhone(SubscriptionManager.getPhoneId(subId));
        if (phone == null) {
            logd("Failed to start validation. Inactive subId " + subId);
@@ -122,6 +117,10 @@ public class CellularNetworkValidator extends ConnectivityManager.NetworkCallbac
            return;
        }

        if (isValidating()) {
            stopValidation();
        }

        mState = STATE_VALIDATING;
        mSubId = subId;
        mTimeoutInMs = timeoutInMs;
@@ -132,7 +131,10 @@ public class CellularNetworkValidator extends ConnectivityManager.NetworkCallbac
        logd("Start validating subId " + mSubId + " mTimeoutInMs " + mTimeoutInMs
                + " mReleaseAfterValidation " + mReleaseAfterValidation);

        mConnectivityManager.requestNetwork(mNetworkRequest, this, mHandler, mTimeoutInMs);
        mNetworkCallback = new ConnectivityNetworkCallback(subId);

        mConnectivityManager.requestNetwork(
                mNetworkRequest, mNetworkCallback, mHandler, mTimeoutInMs);
    }

    /**
@@ -142,7 +144,7 @@ public class CellularNetworkValidator extends ConnectivityManager.NetworkCallbac
        if (!isValidating()) {
            logd("No need to stop validation.");
        } else {
            mConnectivityManager.unregisterNetworkCallback(this);
            mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
            mState = STATE_IDLE;
        }
        mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -170,7 +172,10 @@ public class CellularNetworkValidator extends ConnectivityManager.NetworkCallbac
                .build();
    }

    private synchronized void reportValidationResult(boolean passed) {
    private synchronized void reportValidationResult(boolean passed, int subId) {
        // If the validation result is not for current subId, do nothing.
        if (mSubId != subId) return;

        // Deal with the result only when state is still VALIDATING. This is to avoid
        // receiving multiple callbacks in queue.
        if (mState == STATE_VALIDATING) {
@@ -178,12 +183,20 @@ public class CellularNetworkValidator extends ConnectivityManager.NetworkCallbac
            if (!mReleaseAfterValidation && passed) {
                mState = STATE_VALIDATED;
            } else {
                mConnectivityManager.unregisterNetworkCallback(this);
                mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
                mState = STATE_IDLE;
            }
        }

        mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
    }

    class ConnectivityNetworkCallback extends ConnectivityManager.NetworkCallback {
        private final int mSubId;

        ConnectivityNetworkCallback(int subId) {
            mSubId = subId;
        }
        /**
         * ConnectivityManager.NetworkCallback implementation
         */
@@ -195,19 +208,19 @@ public class CellularNetworkValidator extends ConnectivityManager.NetworkCallbac
        @Override
        public void onLosing(Network network, int maxMsToLive) {
            logd("network onLosing " + network + " maxMsToLive " + maxMsToLive);
        reportValidationResult(false);
            reportValidationResult(false, ConnectivityNetworkCallback.this.mSubId);
        }

        @Override
        public void onLost(Network network) {
            logd("network onLost " + network);
        reportValidationResult(false);
            reportValidationResult(false, ConnectivityNetworkCallback.this.mSubId);
        }

        @Override
        public void onUnavailable() {
            logd("onUnavailable");
        reportValidationResult(false);
            reportValidationResult(false, ConnectivityNetworkCallback.this.mSubId);
        }

        @Override
@@ -215,7 +228,8 @@ public class CellularNetworkValidator extends ConnectivityManager.NetworkCallbac
                NetworkCapabilities networkCapabilities) {
            if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
                logd("onValidated");
            reportValidationResult(true);
                reportValidationResult(true, ConnectivityNetworkCallback.this.mSubId);
            }
        }
    }