diff options
Diffstat (limited to 'java/com')
3 files changed, 108 insertions, 33 deletions
diff --git a/java/com/android/server/ethernet/EthernetNetworkFactory.java b/java/com/android/server/ethernet/EthernetNetworkFactory.java index a15fec4..2823391 100644 --- a/java/com/android/server/ethernet/EthernetNetworkFactory.java +++ b/java/com/android/server/ethernet/EthernetNetworkFactory.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.net.ConnectivityManager; +import android.net.EthernetManager; import android.net.EthernetNetworkSpecifier; import android.net.IEthernetNetworkManagementListener; import android.net.EthernetNetworkManagementException; @@ -186,6 +187,18 @@ public class EthernetNetworkFactory extends NetworkFactory { updateCapabilityFilter(); } + @VisibleForTesting + protected int getInterfaceState(@NonNull String iface) { + final NetworkInterfaceState interfaceState = mTrackingInterfaces.get(iface); + if (interfaceState == null) { + return EthernetManager.STATE_ABSENT; + } else if (!interfaceState.mLinkUp) { + return EthernetManager.STATE_LINK_DOWN; + } else { + return EthernetManager.STATE_LINK_UP; + } + } + /** * Update a network's configuration and restart it if necessary. * @@ -270,7 +283,8 @@ public class EthernetNetworkFactory extends NetworkFactory { return iface.updateLinkState(up, listener); } - boolean hasInterface(String ifaceName) { + @VisibleForTesting + protected boolean hasInterface(String ifaceName) { return mTrackingInterfaces.containsKey(ifaceName); } diff --git a/java/com/android/server/ethernet/EthernetServiceImpl.java b/java/com/android/server/ethernet/EthernetServiceImpl.java index ffd6d40..c1c6d3a 100644 --- a/java/com/android/server/ethernet/EthernetServiceImpl.java +++ b/java/com/android/server/ethernet/EthernetServiceImpl.java @@ -143,10 +143,8 @@ public class EthernetServiceImpl extends IEthernetManager.Stub { * Adds a listener. * @param listener A {@link IEthernetServiceListener} to add. */ - public void addListener(IEthernetServiceListener listener) { - if (listener == null) { - throw new IllegalArgumentException("listener must not be null"); - } + public void addListener(IEthernetServiceListener listener) throws RemoteException { + Objects.requireNonNull(listener, "listener must not be null"); PermissionUtils.enforceAccessNetworkStatePermission(mContext, TAG); mTracker.addListener(listener, checkUseRestrictedNetworksPermission()); } diff --git a/java/com/android/server/ethernet/EthernetTracker.java b/java/com/android/server/ethernet/EthernetTracker.java index 6c8e6d3..2571fe6 100644 --- a/java/com/android/server/ethernet/EthernetTracker.java +++ b/java/com/android/server/ethernet/EthernetTracker.java @@ -23,6 +23,7 @@ import static com.android.internal.annotations.VisibleForTesting.Visibility.PACK import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; +import android.net.EthernetManager; import android.net.IEthernetServiceListener; import android.net.IEthernetNetworkManagementListener; import android.net.INetd; @@ -165,7 +166,10 @@ public class EthernetTracker { Log.i(TAG, "updateIpConfiguration, iface: " + iface + ", cfg: " + ipConfiguration); } writeIpConfiguration(iface, ipConfiguration); - mHandler.post(() -> mFactory.updateInterface(iface, ipConfiguration, null, null)); + mHandler.post(() -> { + mFactory.updateInterface(iface, ipConfiguration, null, null); + broadcastInterfaceStateChange(iface); + }); } private void writeIpConfiguration(@NonNull final String iface, @@ -174,6 +178,55 @@ public class EthernetTracker { mIpConfigurations.put(iface, ipConfig); } + private IpConfiguration getIpConfigurationForCallback(String iface, int state) { + return (state == EthernetManager.STATE_ABSENT) ? null : getOrCreateIpConfiguration(iface); + } + + private void ensureRunningOnEthernetServiceThread() { + if (mHandler.getLooper().getThread() != Thread.currentThread()) { + throw new IllegalStateException( + "Not running on EthernetService thread: " + + Thread.currentThread().getName()); + } + } + + /** + * Broadcast the link state or IpConfiguration change of existing Ethernet interfaces to all + * listeners. + */ + protected void broadcastInterfaceStateChange(@NonNull String iface) { + ensureRunningOnEthernetServiceThread(); + final int state = mFactory.getInterfaceState(iface); + final int role = getInterfaceRole(iface); + final IpConfiguration config = getIpConfigurationForCallback(iface, state); + final int n = mListeners.beginBroadcast(); + for (int i = 0; i < n; i++) { + try { + mListeners.getBroadcastItem(i).onInterfaceStateChanged(iface, state, role, config); + } catch (RemoteException e) { + // Do nothing here. + } + } + mListeners.finishBroadcast(); + } + + /** + * Unicast the interface state or IpConfiguration change of existing Ethernet interfaces to a + * specific listener. + */ + protected void unicastInterfaceStateChange(@NonNull IEthernetServiceListener listener, + @NonNull String iface) { + ensureRunningOnEthernetServiceThread(); + final int state = mFactory.getInterfaceState(iface); + final int role = getInterfaceRole(iface); + final IpConfiguration config = getIpConfigurationForCallback(iface, state); + try { + listener.onInterfaceStateChanged(iface, state, role, config); + } catch (RemoteException e) { + // Do nothing here. + } + } + @VisibleForTesting(visibility = PACKAGE) protected void updateConfiguration(@NonNull final String iface, @NonNull final StaticIpConfiguration staticIpConfig, @@ -186,8 +239,10 @@ public class EthernetTracker { final IpConfiguration ipConfig = createIpConfiguration(staticIpConfig); writeIpConfiguration(iface, ipConfig); mNetworkCapabilities.put(iface, capabilities); - mHandler.post(() -> - mFactory.updateInterface(iface, ipConfig, capabilities, listener)); + mHandler.post(() -> { + mFactory.updateInterface(iface, ipConfig, capabilities, listener); + broadcastInterfaceStateChange(iface); + }); } @VisibleForTesting(visibility = PACKAGE) @@ -225,11 +280,19 @@ public class EthernetTracker { } void addListener(IEthernetServiceListener listener, boolean canUseRestrictedNetworks) { - mListeners.register(listener, new ListenerInfo(canUseRestrictedNetworks)); + mHandler.post(() -> { + if (!mListeners.register(listener, new ListenerInfo(canUseRestrictedNetworks))) { + // Remote process has already died + return; + } + for (String iface : getInterfaces(canUseRestrictedNetworks)) { + unicastInterfaceStateChange(listener, iface); + } + }); } void removeListener(IEthernetServiceListener listener) { - mListeners.unregister(listener); + mHandler.post(() -> mListeners.unregister(listener)); } public void setIncludeTestInterfaces(boolean include) { @@ -295,6 +358,14 @@ public class EthernetTracker { } } + private int getInterfaceRole(final String iface) { + if (!mFactory.hasInterface(iface)) return EthernetManager.ROLE_NONE; + final int mode = getInterfaceMode(iface); + return (mode == INTERFACE_MODE_CLIENT) + ? EthernetManager.ROLE_CLIENT + : EthernetManager.ROLE_SERVER; + } + private int getInterfaceMode(final String iface) { if (iface.equals(mDefaultInterface)) { return mDefaultInterfaceMode; @@ -312,6 +383,7 @@ public class EthernetTracker { if (iface.equals(mDefaultInterface)) { mDefaultInterface = null; } + broadcastInterfaceStateChange(iface); } private void addInterface(String iface) { @@ -346,11 +418,7 @@ public class EthernetTracker { final int mode = getInterfaceMode(iface); if (mode == INTERFACE_MODE_CLIENT) { - IpConfiguration ipConfiguration = mIpConfigurations.get(iface); - if (ipConfiguration == null) { - ipConfiguration = createDefaultIpConfiguration(); - } - + IpConfiguration ipConfiguration = getOrCreateIpConfiguration(iface); Log.d(TAG, "Tracking interface in client mode: " + iface); mFactory.addInterface(iface, hwAddress, ipConfiguration, nc); } else { @@ -376,22 +444,7 @@ public class EthernetTracker { && mFactory.updateInterfaceLinkState(iface, up, listener); if (factoryLinkStateUpdated) { - boolean restricted = isRestrictedInterface(iface); - int n = mListeners.beginBroadcast(); - for (int i = 0; i < n; i++) { - try { - if (restricted) { - ListenerInfo listenerInfo = (ListenerInfo) mListeners.getBroadcastCookie(i); - if (!listenerInfo.canUseRestrictedNetworks) { - continue; - } - } - mListeners.getBroadcastItem(i).onAvailabilityChanged(iface, up); - } catch (RemoteException e) { - // Do nothing here. - } - } - mListeners.finishBroadcast(); + broadcastInterfaceStateChange(iface); } } @@ -438,6 +491,8 @@ public class EthernetTracker { } addInterface(iface); + + broadcastInterfaceStateChange(iface); } private void trackAvailableInterfaces() { @@ -463,11 +518,17 @@ public class EthernetTracker { @Override public void onInterfaceAdded(String iface) { + if (DBG) { + Log.i(TAG, "onInterfaceAdded, iface: " + iface); + } mHandler.post(() -> maybeTrackInterface(iface)); } @Override public void onInterfaceRemoved(String iface) { + if (DBG) { + Log.i(TAG, "onInterfaceRemoved, iface: " + iface); + } mHandler.post(() -> stopTrackingInterface(iface)); } } @@ -663,8 +724,10 @@ public class EthernetTracker { return ret; } - private static IpConfiguration createDefaultIpConfiguration() { - final IpConfiguration ret = new IpConfiguration(); + private IpConfiguration getOrCreateIpConfiguration(String iface) { + IpConfiguration ret = mIpConfigurations.get(iface); + if (ret != null) return ret; + ret = new IpConfiguration(); ret.setIpAssignment(IpAssignment.DHCP); ret.setProxySettings(ProxySettings.NONE); return ret; |