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

Commit afdebe14 authored by Sarah Chin's avatar Sarah Chin
Browse files

DC retry ENTERPRISE for duplicate CID if TDs changed

Test: atest DataConnectionTest
Bug: 198473491
Change-Id: I12de99148901111197dd00f7b9d987f667e29e37
parent 620ca2c1
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -1394,7 +1394,9 @@ public class DataConnection extends StateMachine {
                result.mFailCause = DataFailCause.getFailCause(response.getCause());
            }
        } else if (cp.mApnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE
                && mDcController.getActiveDcByCid(response.getId()) != null) {
                && mDcController.getActiveDcByCid(response.getId()) != null
                && mDcController.getTrafficDescriptorsForCid(response.getId())
                        .equals(response.getTrafficDescriptors())) {
            if (DBG) log("DataConnection already exists for cid: " + response.getId());
            result = SetupResult.ERROR_DUPLICATE_CID;
            result.mFailCause = DataFailCause.DUPLICATE_CID;
+49 −7
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.telephony.AccessNetworkConstants;
import android.telephony.DataFailCause;
import android.telephony.data.ApnSetting;
import android.telephony.data.DataCallResponse;
import android.telephony.data.TrafficDescriptor;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.DctConstants;
@@ -86,6 +87,9 @@ public class DcController extends Handler {
    final ArrayList<DataConnection> mDcListAll = new ArrayList<>();
    // @GuardedBy("mDcListAll")
    private final HashMap<Integer, DataConnection> mDcListActiveByCid = new HashMap<>();
    // @GuardedBy("mTrafficDescriptorsByCid")
    private final HashMap<Integer, List<TrafficDescriptor>> mTrafficDescriptorsByCid =
            new HashMap<>();

    /**
     * Aggregated physical link state from all data connections. This reflects the device's RRC
@@ -138,6 +142,9 @@ public class DcController extends Handler {
            mDcListActiveByCid.remove(dc.mCid);
            mDcListAll.remove(dc);
        }
        synchronized (mTrafficDescriptorsByCid) {
            mTrafficDescriptorsByCid.remove(dc.mCid);
        }
    }

    public void addActiveDcByCid(DataConnection dc) {
@@ -147,6 +154,7 @@ public class DcController extends Handler {
        synchronized (mDcListAll) {
            mDcListActiveByCid.put(dc.mCid, dc);
        }
        updateTrafficDescriptorsForCid(dc.mCid, dc.getTrafficDescriptors());
    }

    DataConnection getActiveDcByCid(int cid) {
@@ -162,6 +170,9 @@ public class DcController extends Handler {
                log("removeActiveDcByCid removedDc=null dc=" + dc);
            }
        }
        synchronized (mTrafficDescriptorsByCid) {
            mTrafficDescriptorsByCid.remove(dc.mCid);
        }
    }

    boolean isDefaultDataActive() {
@@ -172,6 +183,18 @@ public class DcController extends Handler {
        }
    }

    List<TrafficDescriptor> getTrafficDescriptorsForCid(int cid) {
        synchronized (mTrafficDescriptorsByCid) {
            return mTrafficDescriptorsByCid.get(cid);
        }
    }

    void updateTrafficDescriptorsForCid(int cid, List<TrafficDescriptor> tds) {
        synchronized (mTrafficDescriptorsByCid) {
            mTrafficDescriptorsByCid.put(cid, tds);
        }
    }

    @Override
    public void handleMessage(Message msg) {
        AsyncResult ar;
@@ -207,19 +230,29 @@ public class DcController extends Handler {
        }

        // Create hashmap of cid to DataCallResponse
        HashMap<Integer, DataCallResponse> dataCallResponseListByCid =
                new HashMap<Integer, DataCallResponse>();
        HashMap<Integer, DataCallResponse> dataCallResponseListByCid = new HashMap<>();
        for (DataCallResponse dcs : dcsList) {
            dataCallResponseListByCid.put(dcs.getId(), dcs);
        }

        // Add a DC that is active but not in the
        // dcsList to the list of DC's to retry
        ArrayList<DataConnection> dcsToRetry = new ArrayList<DataConnection>();
        // Add a DC that is active but not in the dcsList to the list of DC's to retry
        ArrayList<DataConnection> dcsToRetry = new ArrayList<>();
        for (DataConnection dc : dcListActiveByCid.values()) {
            if (dataCallResponseListByCid.get(dc.mCid) == null) {
            DataCallResponse response = dataCallResponseListByCid.get(dc.mCid);
            if (response == null) {
                if (DBG) log("onDataStateChanged: add to retry dc=" + dc);
                dcsToRetry.add(dc);
            } else {
                List<TrafficDescriptor> oldTds = getTrafficDescriptorsForCid(dc.mCid);
                List<TrafficDescriptor> newTds = response.getTrafficDescriptors();
                if (oldTds.equals(newTds)) {
                    if (DBG) {
                        log("onDataStateChanged: add to retry due to TD changed dc=" + dc
                                + ", oldTds=" + oldTds + ", newTds=" + newTds);
                    }
                    updateTrafficDescriptorsForCid(dc.mCid, newTds);
                    dcsToRetry.add(dc);
                }
            }
        }
        if (DBG) log("onDataStateChanged: dcsToRetry=" + dcsToRetry);
@@ -449,9 +482,15 @@ public class DcController extends Handler {

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        synchronized (mDcListAll) {
            return "mDcListAll=" + mDcListAll + " mDcListActiveByCid=" + mDcListActiveByCid;
            sb.append("mDcListAll=").append(mDcListAll)
                    .append(" mDcListActiveByCid=").append(mDcListActiveByCid);
        }
        synchronized (mTrafficDescriptorsByCid) {
            sb.append("mTrafficDescriptorsByCid=").append(mTrafficDescriptorsByCid);
        }
        return sb.toString();
    }

    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -460,5 +499,8 @@ public class DcController extends Handler {
            pw.println(" mDcListAll=" + mDcListAll);
            pw.println(" mDcListActiveByCid=" + mDcListActiveByCid);
        }
        synchronized (mTrafficDescriptorsByCid) {
            pw.println(" mTrafficDescriptorsByCid=" + mTrafficDescriptorsByCid);
        }
    }
}
+30 −4
Original line number Diff line number Diff line
@@ -94,6 +94,7 @@ import java.util.function.Consumer;

public class DataConnectionTest extends TelephonyTest {
    private static final int DEFAULT_DC_CID = 10;
    private static final ArrayList<TrafficDescriptor> DEFAULT_TD_LIST = new ArrayList<>();

    @Mock
    DcTesterFailBringUpAll mDcTesterFailBringUpAll;
@@ -301,7 +302,7 @@ public class DataConnectionTest extends TelephonyTest {
        }
    }

    private void setSuccessfulSetupDataResponse(int cid) {
    private void setSuccessfulSetupDataResponse(int cid, ArrayList<TrafficDescriptor> tds) {
        doAnswer(invocation -> {
            final Message msg = (Message) invocation.getArguments()[10];

@@ -329,7 +330,7 @@ public class DataConnectionTest extends TelephonyTest {
                    .setMtuV6(1500)
                    .setPduSessionId(1)
                    .setQosBearerSessions(new ArrayList<>())
                    .setTrafficDescriptors(new ArrayList<>())
                    .setTrafficDescriptors(tds)
                    .build();
            msg.getData().putParcelable("data_call_response", response);
            msg.arg1 = DataServiceCallback.RESULT_SUCCESS;
@@ -384,7 +385,7 @@ public class DataConnectionTest extends TelephonyTest {

        mDcp.mApnContext = mApnContext;

        setSuccessfulSetupDataResponse(DEFAULT_DC_CID);
        setSuccessfulSetupDataResponse(DEFAULT_DC_CID, DEFAULT_TD_LIST);

        doAnswer(invocation -> {
            final Message msg = (Message) invocation.getArguments()[2];
@@ -520,7 +521,32 @@ public class DataConnectionTest extends TelephonyTest {
        assertTrue(mDc.isInactive());

        // Change the CID
        setSuccessfulSetupDataResponse(DEFAULT_DC_CID + 1);
        setSuccessfulSetupDataResponse(DEFAULT_DC_CID + 1, DEFAULT_TD_LIST);

        // Verify that ENTERPRISE was set up
        connectEvent(true);
        assertTrue(mDc.getNetworkCapabilities().hasCapability(
                NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
    }

    @Test
    public void testConnectEventDuplicateContextIdsDifferentTDs() throws Exception {
        setUpDefaultData(DEFAULT_DC_CID);

        // Try to connect ENTERPRISE with the same CID as default
        replaceInstance(ConnectionParams.class, "mApnContext", mCp, mEnterpriseApnContext);
        doReturn(mApn1).when(mEnterpriseApnContext).getApnSetting();
        doReturn(ApnSetting.TYPE_ENTERPRISE_STRING).when(mEnterpriseApnContext).getApnType();
        doReturn(ApnSetting.TYPE_ENTERPRISE).when(mEnterpriseApnContext).getApnTypeBitmask();

        // Verify that ENTERPRISE wasn't set up
        connectEvent(false);
        assertTrue(mDc.isInactive());

        // Change the TrafficDescriptors
        ArrayList<TrafficDescriptor> tdList = new ArrayList<>();
        tdList.add(new TrafficDescriptor("dnn", DataConnection.getEnterpriseOsAppId()));
        setSuccessfulSetupDataResponse(DEFAULT_DC_CID, tdList);

        // Verify that ENTERPRISE was set up
        connectEvent(true);