diff --git a/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java b/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java index 4f61dbf38b240..217d670743d7f 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java +++ b/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java @@ -41,6 +41,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Objects; import java.util.concurrent.Executor; +import java.util.function.IntConsumer; /** * A class that manages and configures Ethernet interfaces. @@ -53,15 +54,31 @@ public class EthernetManager { private static final String TAG = "EthernetManager"; private final IEthernetManager mService; - @GuardedBy("mListeners") - private final ArrayList mListeners = new ArrayList<>(); + @GuardedBy("mListenerLock") + private final ArrayList> mIfaceListeners = + new ArrayList<>(); + @GuardedBy("mListenerLock") + private final ArrayList> mEthernetStateListeners = + new ArrayList<>(); + final Object mListenerLock = new Object(); private final IEthernetServiceListener.Stub mServiceListener = new IEthernetServiceListener.Stub() { + @Override + public void onEthernetStateChanged(int state) { + synchronized (mListenerLock) { + for (ListenerInfo li : mEthernetStateListeners) { + li.executor.execute(() -> { + li.listener.accept(state); + }); + } + } + } + @Override public void onInterfaceStateChanged(String iface, int state, int role, IpConfiguration configuration) { - synchronized (mListeners) { - for (ListenerInfo li : mListeners) { + synchronized (mListenerLock) { + for (ListenerInfo li : mIfaceListeners) { li.executor.execute(() -> li.listener.onInterfaceStateChanged(iface, state, role, configuration)); @@ -70,13 +87,29 @@ public class EthernetManager { } }; - private static class ListenerInfo { + /** + * Indicates that Ethernet is disabled. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static final int ETHERNET_STATE_DISABLED = 0; + + /** + * Indicates that Ethernet is enabled. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static final int ETHERNET_STATE_ENABLED = 1; + + private static class ListenerInfo { @NonNull public final Executor executor; @NonNull - public final InterfaceStateListener listener; + public final T listener; - private ListenerInfo(@NonNull Executor executor, @NonNull InterfaceStateListener listener) { + private ListenerInfo(@NonNull Executor executor, @NonNull T listener) { this.executor = executor; this.listener = listener; } @@ -289,18 +322,24 @@ public class EthernetManager { if (listener == null || executor == null) { throw new NullPointerException("listener and executor must not be null"); } - synchronized (mListeners) { - mListeners.add(new ListenerInfo(executor, listener)); - if (mListeners.size() == 1) { - try { - mService.addListener(mServiceListener); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } + synchronized (mListenerLock) { + maybeAddServiceListener(); + mIfaceListeners.add(new ListenerInfo(executor, listener)); } } + @GuardedBy("mListenerLock") + private void maybeAddServiceListener() { + if (!mIfaceListeners.isEmpty() || !mEthernetStateListeners.isEmpty()) return; + + try { + mService.addListener(mServiceListener); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + + } + /** * Returns an array of available Ethernet interface names. * @hide @@ -323,15 +362,20 @@ public class EthernetManager { @SystemApi(client = MODULE_LIBRARIES) public void removeInterfaceStateListener(@NonNull InterfaceStateListener listener) { Objects.requireNonNull(listener); - synchronized (mListeners) { - mListeners.removeIf(l -> l.listener == listener); - if (mListeners.isEmpty()) { - try { - mService.removeListener(mServiceListener); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } + synchronized (mListenerLock) { + mIfaceListeners.removeIf(l -> l.listener == listener); + maybeRemoveServiceListener(); + } + } + + @GuardedBy("mListenerLock") + private void maybeRemoveServiceListener() { + if (!mIfaceListeners.isEmpty() || !mEthernetStateListeners.isEmpty()) return; + + try { + mService.removeListener(mServiceListener); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); } } @@ -611,4 +655,61 @@ public class EthernetManager { throw e.rethrowFromSystemServer(); } } + + /** + * Change ethernet setting. + * + * @param enabled enable or disable ethernet settings. + * + * @hide + */ + @RequiresPermission(anyOf = { + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, + android.Manifest.permission.NETWORK_STACK, + android.Manifest.permission.NETWORK_SETTINGS}) + @SystemApi(client = MODULE_LIBRARIES) + public void setEthernetEnabled(boolean enabled) { + try { + mService.setEthernetEnabled(enabled); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Listen to changes in the state of ethernet. + * + * @param executor to run callbacks on. + * @param listener to listen ethernet state changed. + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) + @SystemApi(client = MODULE_LIBRARIES) + public void addEthernetStateListener(@NonNull Executor executor, + @NonNull IntConsumer listener) { + Objects.requireNonNull(executor); + Objects.requireNonNull(listener); + synchronized (mListenerLock) { + maybeAddServiceListener(); + mEthernetStateListeners.add(new ListenerInfo(executor, listener)); + } + } + + /** + * Removes a listener. + * + * @param listener to listen ethernet state changed. + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) + @SystemApi(client = MODULE_LIBRARIES) + public void removeEthernetStateListener(@NonNull IntConsumer listener) { + Objects.requireNonNull(listener); + synchronized (mListenerLock) { + mEthernetStateListeners.removeIf(l -> l.listener == listener); + maybeRemoveServiceListener(); + } + } } diff --git a/packages/ConnectivityT/framework-t/src/android/net/IEthernetManager.aidl b/packages/ConnectivityT/framework-t/src/android/net/IEthernetManager.aidl index 95ae907a3d213..44e27e26f5d20 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/IEthernetManager.aidl +++ b/packages/ConnectivityT/framework-t/src/android/net/IEthernetManager.aidl @@ -43,4 +43,5 @@ interface IEthernetManager in INetworkInterfaceOutcomeReceiver listener); void connectNetwork(String iface, in INetworkInterfaceOutcomeReceiver listener); void disconnectNetwork(String iface, in INetworkInterfaceOutcomeReceiver listener); + void setEthernetEnabled(boolean enabled); } diff --git a/packages/ConnectivityT/framework-t/src/android/net/IEthernetServiceListener.aidl b/packages/ConnectivityT/framework-t/src/android/net/IEthernetServiceListener.aidl index 6d2ba03f78d4c..751605bb38499 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/IEthernetServiceListener.aidl +++ b/packages/ConnectivityT/framework-t/src/android/net/IEthernetServiceListener.aidl @@ -21,6 +21,7 @@ import android.net.IpConfiguration; /** @hide */ oneway interface IEthernetServiceListener { + void onEthernetStateChanged(int state); void onInterfaceStateChanged(String iface, int state, int role, in IpConfiguration configuration); }