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

Commit 9f428151 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fixed a race condition for early arrived PCO data" into tm-qpr-dev

parents 5be5ea1c fe247e37
Loading
Loading
Loading
Loading
+55 −35
Original line number Diff line number Diff line
@@ -647,10 +647,10 @@ public class DataNetwork extends StateMachine {
    private @NonNull DataAllowedReason mDataAllowedReason;

    /**
     * PCO (Protocol Configuration Options) data received from the network. Key is the PCO id, value
     * is the PCO content.
     * PCO (Protocol Configuration Options) data received from the network. The first key is the
     * cid of the PCO data, the second key is the PCO id, the value is the PCO data.
     */
    private final @NonNull Map<Integer, PcoData> mPcoData = new ArrayMap<>();
    private final @NonNull Map<Integer, Map<Integer, PcoData>> mPcoData = new ArrayMap<>();

    /** The QOS bearer sessions. */
    private final @NonNull List<QosBearerSession> mQosBearerSessions = new ArrayList<>();
@@ -1012,6 +1012,8 @@ public class DataNetwork extends StateMachine {
                    sendMessage(EVENT_DATA_CONFIG_UPDATED);
                }
            };
            mRil.registerForPcoData(getHandler(), EVENT_PCO_DATA_RECEIVED, null);

            mDataConfigManager.registerCallback(mDataConfigManagerCallback);
            mPhone.getDisplayInfoController().registerForTelephonyDisplayInfoChanged(
                    getHandler(), EVENT_DISPLAY_INFO_CHANGED, null);
@@ -1064,6 +1066,7 @@ public class DataNetwork extends StateMachine {
            mPhone.getServiceStateTracker().unregisterForServiceStateChanged(getHandler());
            mPhone.getDisplayInfoController().unregisterForTelephonyDisplayInfoChanged(
                    getHandler());
            mRil.unregisterForPcoData(getHandler());
            mDataConfigManager.unregisterCallback(mDataConfigManagerCallback);
        }

@@ -1111,12 +1114,16 @@ public class DataNetwork extends StateMachine {
                    updateNetworkCapabilities();
                    break;
                }
                case EVENT_PCO_DATA_RECEIVED: {
                    AsyncResult ar = (AsyncResult) msg.obj;
                    onPcoDataReceived((PcoData) ar.result);
                    break;
                }
                case EVENT_NOTIFY_HANDOVER_CANCELLED_RESPONSE:
                    log("Notified handover cancelled.");
                    break;
                case EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED:
                case EVENT_TEAR_DOWN_NETWORK:
                case EVENT_PCO_DATA_RECEIVED:
                case EVENT_STUCK_IN_TRANSIENT_STATE:
                case EVENT_DISPLAY_INFO_CHANGED:
                case EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET:
@@ -1208,7 +1215,6 @@ public class DataNetwork extends StateMachine {
                    break;
                case EVENT_NOTIFY_HANDOVER_STARTED:
                case EVENT_TEAR_DOWN_NETWORK:
                case EVENT_PCO_DATA_RECEIVED:
                case EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET:
                    // Defer the request until connected or disconnected.
                    log("Defer message " + eventToString(msg.what));
@@ -1275,6 +1281,13 @@ public class DataNetwork extends StateMachine {
                }
            }

            // If we've ever received PCO data before connected, now it's the time to
            // process it.
            mPcoData.getOrDefault(mCid.get(mTransport), Collections.emptyMap())
                    .forEach((pcoId, pcoData) -> {
                        onPcoDataChanged(pcoData);
                    });

            notifyPreciseDataConnectionState();
            updateSuspendState();
        }
@@ -1338,10 +1351,6 @@ public class DataNetwork extends StateMachine {
                case EVENT_SUBSCRIPTION_PLAN_OVERRIDE:
                    updateMeteredAndCongested();
                    break;
                case EVENT_PCO_DATA_RECEIVED:
                    ar = (AsyncResult) msg.obj;
                    onPcoDataReceived((PcoData) ar.result);
                    break;
                case EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE:
                    int resultCode = msg.arg1;
                    onDeactivateResponse(resultCode);
@@ -1415,10 +1424,6 @@ public class DataNetwork extends StateMachine {
                    onHandoverResponse(resultCode, dataCallResponse,
                            (DataHandoverRetryEntry) msg.obj);
                    break;
                case EVENT_PCO_DATA_RECEIVED:
                    AsyncResult ar = (AsyncResult) msg.obj;
                    onPcoDataReceived((PcoData) ar.result);
                    break;
                case EVENT_STUCK_IN_TRANSIENT_STATE:
                    // enable detection only for valid timeout range
                    reportAnomaly("Data service did not respond the handover request within "
@@ -1608,7 +1613,6 @@ public class DataNetwork extends StateMachine {
    private void registerForWwanEvents() {
        registerForBandwidthUpdate();
        mKeepaliveTracker.registerForKeepaliveStatus();
        mRil.registerForPcoData(this.getHandler(), EVENT_PCO_DATA_RECEIVED, null);
        mRil.registerForNotAvailable(this.getHandler(), EVENT_RADIO_NOT_AVAILABLE, null);
    }

@@ -1618,7 +1622,6 @@ public class DataNetwork extends StateMachine {
    private void unregisterForWwanEvents() {
        unregisterForBandwidthUpdate();
        mKeepaliveTracker.unregisterForKeepaliveStatus();
        mRil.unregisterForPcoData(this.getHandler());
        mRil.unregisterForNotAvailable(this.getHandler());
    }

@@ -3200,8 +3203,6 @@ public class DataNetwork extends StateMachine {
            mDataProfile = mHandoverDataProfile;
            updateDataNetwork(response);
            if (mTransport != AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
                // Handover from WWAN to WLAN
                mPcoData.clear();
                unregisterForWwanEvents();
            } else {
                // Handover from WLAN to WWAN
@@ -3250,13 +3251,10 @@ public class DataNetwork extends StateMachine {
    /**
     * Called when receiving PCO (Protocol Configuration Options) data from the cellular network.
     *
     * @param pcoData PCO data.
     * @param pcoData The PCO data.
     */
    private void onPcoDataReceived(@NonNull PcoData pcoData) {
        if (pcoData.cid != getId()) return;
        PcoData oldData = mPcoData.put(pcoData.pcoId, pcoData);
        if (!Objects.equals(oldData, pcoData)) {
            log("onPcoDataReceived: " + pcoData);
    private void onPcoDataChanged(@NonNull PcoData pcoData) {
        log("onPcoDataChanged: " + pcoData);
        mDataNetworkCallback.invokeFromExecutor(
                () -> mDataNetworkCallback.onPcoDataChanged(DataNetwork.this));
        if (mDataProfile.getApnSetting() != null) {
@@ -3271,13 +3269,35 @@ public class DataNetwork extends StateMachine {
            }
        }
    }

    /**
     * Called when receiving PCO (Protocol Configuration Options) data from the cellular network.
     *
     * @param pcoData PCO data.
     */
    private void onPcoDataReceived(@NonNull PcoData pcoData) {
        // Save all the PCO data received, even though it might be unrelated to this data network.
        // The network might be still in connecting state. Save all now and use it when entering
        // connected state.
        log("onPcoDataReceived: " + pcoData);
        PcoData oldData = mPcoData.computeIfAbsent(pcoData.cid, m -> new ArrayMap<>())
                .put(pcoData.pcoId, pcoData);
        if (getId() == INVALID_CID || pcoData.cid != getId()) return;
        if (!Objects.equals(oldData, pcoData)) {
            onPcoDataChanged(pcoData);
        }
    }

    /**
     * @return The PCO data received from the network.
     * @return The PCO data map of the network. The key is the PCO id, the value is the PCO data.
     * An empty map if PCO data is not available.
     */
    public @NonNull Map<Integer, PcoData> getPcoData() {
        return mPcoData;
        if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN
                || mCid.get(mTransport) == INVALID_CID) {
            return Collections.emptyMap();
        }
        return mPcoData.get(mCid.get(mTransport));
    }

    /**
+1 −1
Original line number Diff line number Diff line
@@ -3029,7 +3029,7 @@ public class DataNetworkController extends Handler {
            }

            if (nrAdvancedCapableByPco != mNrAdvancedCapableByPco) {
                log("onPcoDataChanged: mNrAdvancedCapableByPco = " + mNrAdvancedCapableByPco);
                log("onPcoDataChanged: mNrAdvancedCapableByPco = " + nrAdvancedCapableByPco);
                mNrAdvancedCapableByPco = nrAdvancedCapableByPco;
                mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
                        () -> callback.onNrAdvancedCapableByPcoChanged(mNrAdvancedCapableByPco)));
+56 −0
Original line number Diff line number Diff line
@@ -2453,6 +2453,62 @@ public class DataNetworkControllerTest extends TelephonyTest {
        verify(mMockedDataNetworkControllerCallback).onNrAdvancedCapableByPcoChanged(eq(false));
    }

    @Test
    public void testNrAdvancedByEarlyPco() {
        Mockito.reset(mMockedWwanDataServiceManager);
        mDataNetworkControllerUT.addNetworkRequest(
                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
        processAllMessages();

        // PCO data arrives before data network entering connected state.
        mSimulatedCommands.triggerPcoData(1, "IPV6", 1234, new byte[]{1});
        processAllMessages();

        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
        verify(mMockedWwanDataServiceManager).setupDataCall(anyInt(), any(DataProfile.class),
                anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(), any(), any(), anyBoolean(),
                messageCaptor.capture());

        // Send setup data call complete message.
        Message msg = messageCaptor.getValue();
        msg.getData().putParcelable("data_call_response",
                createDataCallResponse(1, DataCallResponse.LINK_STATUS_ACTIVE));
        msg.arg1 = DataServiceCallback.RESULT_SUCCESS;
        msg.sendToTarget();
        processAllMessages();

        verify(mMockedDataNetworkControllerCallback).onNrAdvancedCapableByPcoChanged(eq(true));
    }

    @Test
    public void testNrAdvancedByEarlyUnrelatedPco() {
        Mockito.reset(mMockedWwanDataServiceManager);
        mDataNetworkControllerUT.addNetworkRequest(
                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
        processAllMessages();

        // Unrelated PCO data arrives before data network entering connected state.
        mSimulatedCommands.triggerPcoData(2, "IPV6", 1234, new byte[]{1});
        processAllMessages();

        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
        verify(mMockedWwanDataServiceManager).setupDataCall(anyInt(), any(DataProfile.class),
                anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(), any(), any(), anyBoolean(),
                messageCaptor.capture());

        // Send setup data call complete message.
        Message msg = messageCaptor.getValue();
        msg.getData().putParcelable("data_call_response",
                createDataCallResponse(1, DataCallResponse.LINK_STATUS_ACTIVE));
        msg.arg1 = DataServiceCallback.RESULT_SUCCESS;
        msg.sendToTarget();
        processAllMessages();

        verify(mMockedDataNetworkControllerCallback, never()).onNrAdvancedCapableByPcoChanged(
                anyBoolean());
    }


    @Test
    public void testSetupDataNetworkVcnManaged() throws Exception {
        // VCN managed