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

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

Fixed a race condition when attaching network request

When attaching the network request to the data network,
the network request might have been removed by the
clients. Need to check if the request is present or not
when we are attaching it.

Fix: 223468685
Test: atest DataNetworkControllerTest
Merged-In: I87a37849caefb62c7da5004a1f51ad6d81b2d820
Change-Id: I87a37849caefb62c7da5004a1f51ad6d81b2d820
parent 7a6f112b
Loading
Loading
Loading
Loading
+32 −21
Original line number Original line Diff line number Diff line
@@ -947,25 +947,7 @@ public class DataNetwork extends StateMachine {
                    break;
                    break;
                }
                }
                case EVENT_ATTACH_NETWORK_REQUEST: {
                case EVENT_ATTACH_NETWORK_REQUEST: {
                    NetworkRequestList requestList = (NetworkRequestList) msg.obj;
                    onAttachNetworkRequests((NetworkRequestList) msg.obj);
                    NetworkRequestList failedList = new NetworkRequestList();
                    for (TelephonyNetworkRequest networkRequest : requestList) {
                        if (networkRequest.canBeSatisfiedBy(getNetworkCapabilities())) {
                            mAttachedNetworkRequestList.add(networkRequest);
                            networkRequest.setAttachedNetwork(DataNetwork.this);
                            networkRequest.setState(
                                    TelephonyNetworkRequest.REQUEST_STATE_SATISFIED);
                            log("Successfully attached network request " + networkRequest);
                        } else {
                            failedList.add(networkRequest);
                            log("Attached failed. Cannot satisfy the network request "
                                    + networkRequest);
                        }
                        if (failedList.size() > 0) {
                            mDataNetworkCallback.invokeFromExecutor(() -> mDataNetworkCallback
                                    .onAttachFailed(DataNetwork.this, failedList));
                        }
                    }
                    break;
                    break;
                }
                }
                case EVENT_DETACH_NETWORK_REQUEST: {
                case EVENT_DETACH_NETWORK_REQUEST: {
@@ -1452,14 +1434,14 @@ public class DataNetwork extends StateMachine {
     * Attempt to attach the network request list to this data network. Whether the network can
     * Attempt to attach the network request list to this data network. Whether the network can
     * satisfy the request or not will be checked when EVENT_ATTACH_NETWORK_REQUEST is processed.
     * satisfy the request or not will be checked when EVENT_ATTACH_NETWORK_REQUEST is processed.
     * If the request can't be attached, {@link DataNetworkCallback#onAttachFailed(
     * If the request can't be attached, {@link DataNetworkCallback#onAttachFailed(
     * DataNetwork, NetworkRequestList)} will be called, and retry should be scheduled.
     * DataNetwork, NetworkRequestList)}.
     *
     *
     * @param requestList Network request list to attach.
     * @param requestList Network request list to attach.
     * @return {@code false} if the network is already disconnected. {@code true} means the request
     * @return {@code false} if the network is already disconnected. {@code true} means the request
     * has been scheduled to attach to the network. If attach succeeds, the network request's state
     * has been scheduled to attach to the network. If attach succeeds, the network request's state
     * will be set to {@link TelephonyNetworkRequest#REQUEST_STATE_SATISFIED}. If failed, the
     * will be set to {@link TelephonyNetworkRequest#REQUEST_STATE_SATISFIED}. If failed, the
     * callback {@link DataNetworkCallback#onAttachFailed(DataNetwork, NetworkRequestList)} will
     * callback {@link DataNetworkCallback#onAttachFailed(DataNetwork, NetworkRequestList)} will
     * be called, and retry should be scheduled.
     * be called.
     */
     */
    public boolean attachNetworkRequests(@NonNull NetworkRequestList requestList) {
    public boolean attachNetworkRequests(@NonNull NetworkRequestList requestList) {
        // If the network is already ended, we still attach the network request to the data network,
        // If the network is already ended, we still attach the network request to the data network,
@@ -1472,6 +1454,35 @@ public class DataNetwork extends StateMachine {
        return true;
        return true;
    }
    }


    /**
     * Called when attaching network request list to this data network.
     *
     * @param requestList Network request list to attach.
     */
    public void onAttachNetworkRequests(@NonNull NetworkRequestList requestList) {
        NetworkRequestList failedList = new NetworkRequestList();
        for (TelephonyNetworkRequest networkRequest : requestList) {
            if (!mDataNetworkController.isNetworkRequestExisting(networkRequest)) {
                failedList.add(networkRequest);
                log("Attached failed. Network request was already removed.");
            } else if (!networkRequest.canBeSatisfiedBy(getNetworkCapabilities())) {
                failedList.add(networkRequest);
                log("Attached failed. Cannot satisfy the network request "
                        + networkRequest);
            } else {
                mAttachedNetworkRequestList.add(networkRequest);
                networkRequest.setAttachedNetwork(DataNetwork.this);
                networkRequest.setState(
                        TelephonyNetworkRequest.REQUEST_STATE_SATISFIED);
                log("Successfully attached network request " + networkRequest);
            }
        }
        if (failedList.size() > 0) {
            mDataNetworkCallback.invokeFromExecutor(() -> mDataNetworkCallback
                    .onAttachFailed(DataNetwork.this, failedList));
        }
    }

    /**
    /**
     * Detach the network request from this data network. Note that this will not tear down the
     * Detach the network request from this data network. Note that this will not tear down the
     * network.
     * network.
+12 −1
Original line number Original line Diff line number Diff line
@@ -1852,6 +1852,17 @@ public class DataNetworkController extends Handler {
        logv("onRemoveNetworkRequest: Removed " + networkRequest);
        logv("onRemoveNetworkRequest: Removed " + networkRequest);
    }
    }


    /**
     * Check if the network request is existing. Note this method is not thread safe so can be only
     * called within the modules in {@link com.android.internal.telephony.data}.
     *
     * @param networkRequest Telephony network request to check.
     * @return {@code true} if the network request exists.
     */
    public boolean isNetworkRequestExisting(@NonNull TelephonyNetworkRequest networkRequest) {
        return mAllNetworkRequestList.contains(networkRequest);
    }

    /**
    /**
     * Register for IMS feature registration state.
     * Register for IMS feature registration state.
     *
     *
@@ -2479,7 +2490,7 @@ public class DataNetworkController extends Handler {
     */
     */
    private void onAttachNetworkRequestsFailed(@NonNull DataNetwork dataNetwork,
    private void onAttachNetworkRequestsFailed(@NonNull DataNetwork dataNetwork,
            @NonNull NetworkRequestList requestList) {
            @NonNull NetworkRequestList requestList) {
        // TODO: Perform retry if needed.
        log("Failed to attach " + requestList + " to " + dataNetwork);
    }
    }


    /**
    /**