diff options
Diffstat (limited to 'java/com/android/server/ethernet/EthernetTracker.java')
-rw-r--r-- | java/com/android/server/ethernet/EthernetTracker.java | 119 |
1 files changed, 91 insertions, 28 deletions
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; |