Implement the new added EthernetManager APIs. am: b8ab4c869f

Original change: https://android-review.googlesource.com/c/platform/frameworks/opt/net/ethernet/+/1968579

Change-Id: I3aa995605defb39d45e7c4ed2accdde4b87fa452
This commit is contained in:
Xiao Ma
2022-02-12 05:04:55 +00:00
committed by Automerger Merge Worker
3 changed files with 108 additions and 33 deletions

View File

@@ -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);
}

View File

@@ -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());
}

View File

@@ -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;