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

Commit eea9edf7 authored by Patrick Rohr's avatar Patrick Rohr
Browse files

Change Ethernet API to use OutcomeReceiver

This change addresses API review feedback. In addition, it changes the
returned result from Network to the interface name. The current API
returning a Network object is racy and cannot be implemented correctly.
Users should instead use the ConnectivityManager#requestNetwork() API to
get hold of the Network for a given interface.

Bug: 220017952
Test: TH
Change-Id: I7c46545a47034be409071c2ec007d9e1480c6ed0
parent edae1f64
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -131,8 +131,8 @@ filegroup {
        "src/android/net/EthernetNetworkUpdateRequest.java",
        "src/android/net/EthernetNetworkUpdateRequest.java",
        "src/android/net/EthernetNetworkUpdateRequest.aidl",
        "src/android/net/EthernetNetworkUpdateRequest.aidl",
        "src/android/net/IEthernetManager.aidl",
        "src/android/net/IEthernetManager.aidl",
        "src/android/net/IEthernetNetworkManagementListener.aidl",
        "src/android/net/IEthernetServiceListener.aidl",
        "src/android/net/IEthernetServiceListener.aidl",
        "src/android/net/INetworkInterfaceOutcomeReceiver.aidl",
        "src/android/net/ITetheredInterfaceCallback.aidl",
        "src/android/net/ITetheredInterfaceCallback.aidl",
    ],
    ],
    path: "src",
    path: "src",
+57 −45
Original line number Original line Diff line number Diff line
@@ -30,6 +30,7 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Build;
import android.os.OutcomeReceiver;
import android.os.RemoteException;
import android.os.RemoteException;


import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.GuardedBy;
@@ -40,7 +41,6 @@ import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.concurrent.Executor;
import java.util.function.BiConsumer;


/**
/**
 * A class that manages and configures Ethernet interfaces.
 * A class that manages and configures Ethernet interfaces.
@@ -443,41 +443,45 @@ public class EthernetManager {
        return new TetheredInterfaceRequest(mService, cbInternal);
        return new TetheredInterfaceRequest(mService, cbInternal);
    }
    }


    private static final class InternalNetworkManagementListener
    private static final class NetworkInterfaceOutcomeReceiver
            extends IEthernetNetworkManagementListener.Stub {
            extends INetworkInterfaceOutcomeReceiver.Stub {
        @NonNull
        @NonNull
        private final Executor mExecutor;
        private final Executor mExecutor;
        @NonNull
        @NonNull
        private final BiConsumer<Network, EthernetNetworkManagementException> mListener;
        private final OutcomeReceiver<String, EthernetNetworkManagementException> mCallback;


        InternalNetworkManagementListener(
        NetworkInterfaceOutcomeReceiver(
                @NonNull final Executor executor,
                @NonNull final Executor executor,
                @NonNull final BiConsumer<Network, EthernetNetworkManagementException> listener) {
                @NonNull final OutcomeReceiver<String, EthernetNetworkManagementException>
                        callback) {
            Objects.requireNonNull(executor, "Pass a non-null executor");
            Objects.requireNonNull(executor, "Pass a non-null executor");
            Objects.requireNonNull(listener, "Pass a non-null listener");
            Objects.requireNonNull(callback, "Pass a non-null callback");
            mExecutor = executor;
            mExecutor = executor;
            mListener = listener;
            mCallback = callback;
        }
        }


        @Override
        @Override
        public void onComplete(
        public void onResult(@NonNull String iface) {
                @Nullable final Network network,
            mExecutor.execute(() -> mCallback.onResult(iface));
                @Nullable final EthernetNetworkManagementException e) {
        }
            mExecutor.execute(() -> mListener.accept(network, e));

        @Override
        public void onError(@NonNull EthernetNetworkManagementException e) {
            mExecutor.execute(() -> mCallback.onError(e));
        }
        }
    }
    }


    private InternalNetworkManagementListener getInternalNetworkManagementListener(
    private NetworkInterfaceOutcomeReceiver makeNetworkInterfaceOutcomeReceiver(
            @Nullable final Executor executor,
            @Nullable final Executor executor,
            @Nullable final BiConsumer<Network, EthernetNetworkManagementException> listener) {
            @Nullable final OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
        if (null != listener) {
        if (null != callback) {
            Objects.requireNonNull(executor, "Pass a non-null executor, or a null listener");
            Objects.requireNonNull(executor, "Pass a non-null executor, or a null callback");
        }
        }
        final InternalNetworkManagementListener proxy;
        final NetworkInterfaceOutcomeReceiver proxy;
        if (null == listener) {
        if (null == callback) {
            proxy = null;
            proxy = null;
        } else {
        } else {
            proxy = new InternalNetworkManagementListener(executor, listener);
            proxy = new NetworkInterfaceOutcomeReceiver(executor, callback);
        }
        }
        return proxy;
        return proxy;
    }
    }
@@ -492,14 +496,17 @@ public class EthernetManager {
     * Similarly, use {@link NetworkCapabilities.Builder} to build a {@code NetworkCapabilities}
     * Similarly, use {@link NetworkCapabilities.Builder} to build a {@code NetworkCapabilities}
     * object for this network to put inside the {@code request}.
     * object for this network to put inside the {@code request}.
     *
     *
     * If non-null, the listener will be called exactly once after this is called, unless
     * This function accepts an {@link OutcomeReceiver} that is called once the operation has
     * a synchronous exception was thrown.
     * finished execution.
     *
     *
     * @param iface the name of the interface to act upon.
     * @param iface the name of the interface to act upon.
     * @param request the {@link EthernetNetworkUpdateRequest} used to set an ethernet network's
     * @param request the {@link EthernetNetworkUpdateRequest} used to set an ethernet network's
     *                {@link StaticIpConfiguration} and {@link NetworkCapabilities} values.
     *                {@link StaticIpConfiguration} and {@link NetworkCapabilities} values.
     * @param executor an {@link Executor} to execute the listener on. Optional if listener is null.
     * @param executor an {@link Executor} to execute the callback on. Optional if callback is null.
     * @param listener an optional {@link BiConsumer} to listen for completion of the operation.
     * @param callback an optional {@link OutcomeReceiver} to listen for completion of the
     *                 operation. On success, {@link OutcomeReceiver#onResult} is called with the
     *                 interface name. On error, {@link OutcomeReceiver#onError} is called with more
     *                 information about the error.
     * @throws SecurityException if the process doesn't hold
     * @throws SecurityException if the process doesn't hold
     *                          {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}.
     *                          {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}.
     * @throws UnsupportedOperationException if called on a non-automotive device or on an
     * @throws UnsupportedOperationException if called on a non-automotive device or on an
@@ -515,11 +522,11 @@ public class EthernetManager {
            @NonNull String iface,
            @NonNull String iface,
            @NonNull EthernetNetworkUpdateRequest request,
            @NonNull EthernetNetworkUpdateRequest request,
            @Nullable @CallbackExecutor Executor executor,
            @Nullable @CallbackExecutor Executor executor,
            @Nullable BiConsumer<Network, EthernetNetworkManagementException> listener) {
            @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
        Objects.requireNonNull(iface, "iface must be non-null");
        Objects.requireNonNull(iface, "iface must be non-null");
        Objects.requireNonNull(request, "request must be non-null");
        Objects.requireNonNull(request, "request must be non-null");
        final InternalNetworkManagementListener proxy = getInternalNetworkManagementListener(
        final NetworkInterfaceOutcomeReceiver proxy = makeNetworkInterfaceOutcomeReceiver(
                executor, listener);
                executor, callback);
        try {
        try {
            mService.updateConfiguration(iface, request, proxy);
            mService.updateConfiguration(iface, request, proxy);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
@@ -530,15 +537,17 @@ public class EthernetManager {
    /**
    /**
     * Set an ethernet network's link state up.
     * Set an ethernet network's link state up.
     *
     *
     * When the link is successfully turned up, the listener will be called with the resulting
     * When the link is successfully turned up, the callback will be called with the network
     * network. If any error or unexpected condition happens while the system tries to turn the
     * interface was torn down, if any. If any error or unexpected condition happens while the
     * interface up, the listener will be called with an appropriate exception.
     * system tries to turn the interface down, the callback will be called with an appropriate
     * The listener is guaranteed to be called exactly once for each call to this method, but this
     * exception. The callback is guaranteed to be called exactly once for each call to this method.
     * may take an unbounded amount of time depending on the actual network conditions.
     *
     *
     * @param iface the name of the interface to act upon.
     * @param iface the name of the interface to act upon.
     * @param executor an {@link Executor} to execute the listener on. Optional if listener is null.
     * @param executor an {@link Executor} to execute the callback on. Optional if callback is null.
     * @param listener an optional {@link BiConsumer} to listen for completion of the operation.
     * @param callback an optional {@link OutcomeReceiver} to listen for completion of the
     *                 operation. On success, {@link OutcomeReceiver#onResult} is called with the
     *                 interface name. On error, {@link OutcomeReceiver#onError} is called with more
     *                 information about the error.
     * @throws SecurityException if the process doesn't hold
     * @throws SecurityException if the process doesn't hold
     *                          {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}.
     *                          {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}.
     * @throws UnsupportedOperationException if called on a non-automotive device.
     * @throws UnsupportedOperationException if called on a non-automotive device.
@@ -553,10 +562,10 @@ public class EthernetManager {
    public void connectNetwork(
    public void connectNetwork(
            @NonNull String iface,
            @NonNull String iface,
            @Nullable @CallbackExecutor Executor executor,
            @Nullable @CallbackExecutor Executor executor,
            @Nullable BiConsumer<Network, EthernetNetworkManagementException> listener) {
            @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
        Objects.requireNonNull(iface, "iface must be non-null");
        Objects.requireNonNull(iface, "iface must be non-null");
        final InternalNetworkManagementListener proxy = getInternalNetworkManagementListener(
        final NetworkInterfaceOutcomeReceiver proxy = makeNetworkInterfaceOutcomeReceiver(
                executor, listener);
                executor, callback);
        try {
        try {
            mService.connectNetwork(iface, proxy);
            mService.connectNetwork(iface, proxy);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
@@ -567,14 +576,17 @@ public class EthernetManager {
    /**
    /**
     * Set an ethernet network's link state down.
     * Set an ethernet network's link state down.
     *
     *
     * When the link is successfully turned down, the listener will be called with the network that
     * When the link is successfully turned down, the callback will be called with the network
     * was torn down, if any. If any error or unexpected condition happens while the system tries to
     * interface was torn down, if any. If any error or unexpected condition happens while the
     * turn the interface down, the listener will be called with an appropriate exception.
     * system tries to turn the interface down, the callback will be called with an appropriate
     * The listener is guaranteed to be called exactly once for each call to this method.
     * exception. The callback is guaranteed to be called exactly once for each call to this method.
     *
     *
     * @param iface the name of the interface to act upon.
     * @param iface the name of the interface to act upon.
     * @param executor an {@link Executor} to execute the listener on. Optional if listener is null.
     * @param executor an {@link Executor} to execute the callback on. Optional if callback is null.
     * @param listener an optional {@link BiConsumer} to listen for completion of the operation.
     * @param callback an optional {@link OutcomeReceiver} to listen for completion of the
     *                 operation. On success, {@link OutcomeReceiver#onResult} is called with the
     *                 interface name. On error, {@link OutcomeReceiver#onError} is called with more
     *                 information about the error.
     * @throws SecurityException if the process doesn't hold
     * @throws SecurityException if the process doesn't hold
     *                          {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}.
     *                          {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}.
     * @throws UnsupportedOperationException if called on a non-automotive device.
     * @throws UnsupportedOperationException if called on a non-automotive device.
@@ -589,10 +601,10 @@ public class EthernetManager {
    public void disconnectNetwork(
    public void disconnectNetwork(
            @NonNull String iface,
            @NonNull String iface,
            @Nullable @CallbackExecutor Executor executor,
            @Nullable @CallbackExecutor Executor executor,
            @Nullable BiConsumer<Network, EthernetNetworkManagementException> listener) {
            @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
        Objects.requireNonNull(iface, "iface must be non-null");
        Objects.requireNonNull(iface, "iface must be non-null");
        final InternalNetworkManagementListener proxy = getInternalNetworkManagementListener(
        final NetworkInterfaceOutcomeReceiver proxy = makeNetworkInterfaceOutcomeReceiver(
                executor, listener);
                executor, callback);
        try {
        try {
            mService.disconnectNetwork(iface, proxy);
            mService.disconnectNetwork(iface, proxy);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
+5 −4
Original line number Original line Diff line number Diff line
@@ -18,8 +18,9 @@ package android.net;


import android.net.IpConfiguration;
import android.net.IpConfiguration;
import android.net.IEthernetServiceListener;
import android.net.IEthernetServiceListener;
import android.net.IEthernetNetworkManagementListener;
import android.net.EthernetNetworkManagementException;
import android.net.EthernetNetworkUpdateRequest;
import android.net.EthernetNetworkUpdateRequest;
import android.net.INetworkInterfaceOutcomeReceiver;
import android.net.ITetheredInterfaceCallback;
import android.net.ITetheredInterfaceCallback;


/**
/**
@@ -39,7 +40,7 @@ interface IEthernetManager
    void requestTetheredInterface(in ITetheredInterfaceCallback callback);
    void requestTetheredInterface(in ITetheredInterfaceCallback callback);
    void releaseTetheredInterface(in ITetheredInterfaceCallback callback);
    void releaseTetheredInterface(in ITetheredInterfaceCallback callback);
    void updateConfiguration(String iface, in EthernetNetworkUpdateRequest request,
    void updateConfiguration(String iface, in EthernetNetworkUpdateRequest request,
        in IEthernetNetworkManagementListener listener);
        in INetworkInterfaceOutcomeReceiver listener);
    void connectNetwork(String iface, in IEthernetNetworkManagementListener listener);
    void connectNetwork(String iface, in INetworkInterfaceOutcomeReceiver listener);
    void disconnectNetwork(String iface, in IEthernetNetworkManagementListener listener);
    void disconnectNetwork(String iface, in INetworkInterfaceOutcomeReceiver listener);
}
}
+3 −3
Original line number Original line Diff line number Diff line
@@ -17,9 +17,9 @@
package android.net;
package android.net;


import android.net.EthernetNetworkManagementException;
import android.net.EthernetNetworkManagementException;
import android.net.Network;


/** @hide */
/** @hide */
oneway interface IEthernetNetworkManagementListener {
oneway interface INetworkInterfaceOutcomeReceiver {
    void onComplete(in Network network, in EthernetNetworkManagementException exception);
    void onResult(in String iface);
    void onError(in EthernetNetworkManagementException e);
}
}
 No newline at end of file