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

Commit bdfd3764 authored by Jack Yu's avatar Jack Yu
Browse files

Fixed out of boundary exception in data retry

Network request can be removed before retry happens. We
need to check if the request is still present.

Bug: 226642219
Test: atest FrameworksTelephonyTests
Merged-In: I8ba7dc03e80bddb351ddf264a18c096ee3d50792
Change-Id: I8ba7dc03e80bddb351ddf264a18c096ee3d50792
parent 261ce0bb
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
@@ -1738,7 +1738,7 @@ public class DataNetworkController extends Handler {
     * {@link #evaluateDataNetwork(DataNetwork, DataEvaluationReason)}.
     * @return The tear down reason.
     */
    private @TearDownReason int getTearDownReason(@NonNull DataEvaluation dataEvaluation) {
    private static @TearDownReason int getTearDownReason(@NonNull DataEvaluation dataEvaluation) {
        if (dataEvaluation.containsDisallowedReasons()) {
            switch (dataEvaluation.getDataDisallowedReasons().get(0)) {
                case DATA_DISABLED:
@@ -2185,6 +2185,14 @@ public class DataNetworkController extends Handler {
            mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
                    () -> callback.onAnyDataNetworkExistingChanged(mAnyDataNetworkExisting)));
        }

        requestList.removeIf(request -> !mAllNetworkRequestList.contains(request));
        if (requestList.isEmpty()) {
            log("onDataNetworkSetupFailed: All requests have been released. "
                    + "Will not evaluate retry.");
            return;
        }

        // Data retry manager will determine if retry is needed. If needed, retry will be scheduled.
        mDataRetryManager.evaluateDataSetupRetry(dataNetwork.getDataProfile(),
                dataNetwork.getTransport(), requestList, cause, retryDelayMillis);
@@ -2219,8 +2227,17 @@ public class DataNetworkController extends Handler {
     * @param dataSetupRetryEntry The data setup retry entry scheduled by {@link DataRetryManager}.
     */
    private void onDataNetworkSetupRetry(@NonNull DataSetupRetryEntry dataSetupRetryEntry) {
        // The request might be already removed before retry happens. Remove them from the list
        // if that's the case.
        dataSetupRetryEntry.networkRequestList.removeIf(
                request -> !mAllNetworkRequestList.contains(request));
        if (dataSetupRetryEntry.networkRequestList.isEmpty()) {
            loge("onDataNetworkSetupRetry: Request list is empty. Abort retry.");
            return;
        }
        TelephonyNetworkRequest telephonyNetworkRequest =
                dataSetupRetryEntry.networkRequestList.get(0);

        int networkCapability = telephonyNetworkRequest.getApnTypeNetworkCapability();
        int preferredTransport = mAccessNetworksManager.getPreferredTransportByNetworkCapability(
                networkCapability);
+18 −0
Original line number Diff line number Diff line
@@ -2076,4 +2076,22 @@ public class DataNetworkControllerTest extends TelephonyTest {
        pdcs = pdcsCaptor.getValue();
        assertThat(pdcs.getState()).isEqualTo(TelephonyManager.DATA_DISCONNECTED);
    }

    @Test
    public void testNetworkRequestRemovedBeforeRetry() {
        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.CONGESTION,
                DataCallResponse.RETRY_DURATION_UNDEFINED);
        TelephonyNetworkRequest networkRequest = createNetworkRequest(
                NetworkCapabilities.NET_CAPABILITY_INTERNET);
        mDataNetworkControllerUT.addNetworkRequest(networkRequest);
        logd("Removing network request.");
        mDataNetworkControllerUT.removeNetworkRequest(networkRequest);
        processAllMessages();

        // There should be only one invocation, which is the original setup data request. There
        // shouldn't be more than 1 (i.e. should not retry).
        verify(mMockedWwanDataServiceManager, times(1)).setupDataCall(anyInt(),
                any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(),
                any(), any(), anyBoolean(), any(Message.class));
    }
}