ethernet: add EthernetCallback class to wrap OutcomeReceiver

The OutcomeReceiver that gets passed into the EthernetServiceImpl is
hard to use (it is nullable and both onError and onResult can throw
RemoteExceptions).

Note: This is an intermediary state.
The next step will be to completely tear EthernetCallback out of
EthernetNetworkFactory, which will remove a lot of boilerplate code.

Bug: 225317892
Test: atest EthernetManagerTest
Change-Id: Ifc0e1ba29ded933c418e4b335cb731c3496d7e44
This commit is contained in:
Patrick Rohr
2022-08-19 14:35:52 -07:00
parent 0d3c8b692d
commit 251f2fcf13
7 changed files with 157 additions and 111 deletions

View File

@@ -0,0 +1,57 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.ethernet;
import android.net.EthernetNetworkManagementException;
import android.net.INetworkInterfaceOutcomeReceiver;
import android.os.RemoteException;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
/** Convenience wrapper for INetworkInterfaceOutcomeReceiver */
@VisibleForTesting
public class EthernetCallback {
private static final String TAG = EthernetCallback.class.getSimpleName();
private final INetworkInterfaceOutcomeReceiver mReceiver;
public EthernetCallback(INetworkInterfaceOutcomeReceiver receiver) {
mReceiver = receiver;
}
/** Calls INetworkInterfaceOutcomeReceiver#onResult */
public void onResult(String ifname) {
try {
if (mReceiver != null) {
mReceiver.onResult(ifname);
}
} catch (RemoteException e) {
Log.e(TAG, "Failed to report error to OutcomeReceiver", e);
}
}
/** Calls INetworkInterfaceOutcomeReceiver#onError */
public void onError(String msg) {
try {
if (mReceiver != null) {
mReceiver.onError(new EthernetNetworkManagementException(msg));
}
} catch (RemoteException e) {
Log.e(TAG, "Failed to report error to OutcomeReceiver", e);
}
}
}

View File

@@ -22,9 +22,7 @@ import android.content.Context;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.ConnectivityResources; import android.net.ConnectivityResources;
import android.net.EthernetManager; import android.net.EthernetManager;
import android.net.EthernetNetworkManagementException;
import android.net.EthernetNetworkSpecifier; import android.net.EthernetNetworkSpecifier;
import android.net.INetworkInterfaceOutcomeReceiver;
import android.net.IpConfiguration; import android.net.IpConfiguration;
import android.net.IpConfiguration.IpAssignment; import android.net.IpConfiguration.IpAssignment;
import android.net.IpConfiguration.ProxySettings; import android.net.IpConfiguration.ProxySettings;
@@ -42,7 +40,6 @@ import android.net.shared.ProvisioningConfiguration;
import android.os.ConditionVariable; import android.os.ConditionVariable;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.os.RemoteException;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.AndroidRuntimeException; import android.util.AndroidRuntimeException;
import android.util.ArraySet; import android.util.ArraySet;
@@ -190,21 +187,21 @@ public class EthernetNetworkFactory {
* {@code null} is passed, then the network's current * {@code null} is passed, then the network's current
* {@link NetworkCapabilities} will be used in support of existing APIs as * {@link NetworkCapabilities} will be used in support of existing APIs as
* the public API does not allow this. * the public API does not allow this.
* @param listener an optional {@link INetworkInterfaceOutcomeReceiver} to notify callers of * @param cb a {@link EthernetCallback} to notify callers of
* completion. * completion.
*/ */
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
protected void updateInterface(@NonNull final String ifaceName, protected void updateInterface(@NonNull final String ifaceName,
@Nullable final IpConfiguration ipConfig, @Nullable final IpConfiguration ipConfig,
@Nullable final NetworkCapabilities capabilities, @Nullable final NetworkCapabilities capabilities,
@Nullable final INetworkInterfaceOutcomeReceiver listener) { final EthernetCallback cb) {
if (!hasInterface(ifaceName)) { if (!hasInterface(ifaceName)) {
maybeSendNetworkManagementCallbackForUntracked(ifaceName, listener); maybeSendNetworkManagementCallbackForUntracked(ifaceName, cb);
return; return;
} }
final NetworkInterfaceState iface = mTrackingInterfaces.get(ifaceName); final NetworkInterfaceState iface = mTrackingInterfaces.get(ifaceName);
iface.updateInterface(ipConfig, capabilities, listener); iface.updateInterface(ipConfig, capabilities, cb);
mTrackingInterfaces.put(ifaceName, iface); mTrackingInterfaces.put(ifaceName, iface);
} }
@@ -239,9 +236,9 @@ public class EthernetNetworkFactory {
/** Returns true if state has been modified */ /** Returns true if state has been modified */
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
protected boolean updateInterfaceLinkState(@NonNull final String ifaceName, final boolean up, protected boolean updateInterfaceLinkState(@NonNull final String ifaceName, final boolean up,
@Nullable final INetworkInterfaceOutcomeReceiver listener) { final EthernetCallback cb) {
if (!hasInterface(ifaceName)) { if (!hasInterface(ifaceName)) {
maybeSendNetworkManagementCallbackForUntracked(ifaceName, listener); maybeSendNetworkManagementCallbackForUntracked(ifaceName, cb);
return false; return false;
} }
@@ -250,14 +247,13 @@ public class EthernetNetworkFactory {
} }
NetworkInterfaceState iface = mTrackingInterfaces.get(ifaceName); NetworkInterfaceState iface = mTrackingInterfaces.get(ifaceName);
return iface.updateLinkState(up, listener); return iface.updateLinkState(up, cb);
} }
private void maybeSendNetworkManagementCallbackForUntracked( private void maybeSendNetworkManagementCallbackForUntracked(
String ifaceName, INetworkInterfaceOutcomeReceiver listener) { String ifaceName, EthernetCallback cb) {
maybeSendNetworkManagementCallback(listener, null, maybeSendNetworkManagementCallback(cb, null,
new EthernetNetworkManagementException( ifaceName + " can't be updated as it is not available.");
ifaceName + " can't be updated as it is not available."));
} }
@VisibleForTesting @VisibleForTesting
@@ -266,21 +262,14 @@ public class EthernetNetworkFactory {
} }
private static void maybeSendNetworkManagementCallback( private static void maybeSendNetworkManagementCallback(
@Nullable final INetworkInterfaceOutcomeReceiver listener, final EthernetCallback cb,
@Nullable final String iface, @Nullable final String iface,
@Nullable final EthernetNetworkManagementException e) { @Nullable final String msg) {
if (null == listener) { Objects.requireNonNull(cb, "EthernetCallback may never be null");
return; if (iface != null) {
} cb.onResult(iface);
} else {
try { cb.onError(msg);
if (iface != null) {
listener.onResult(iface);
} else {
listener.onError(e);
}
} catch (RemoteException re) {
Log.e(TAG, "Can't send onComplete for network management callback", re);
} }
} }
@@ -332,10 +321,10 @@ public class EthernetNetworkFactory {
private class EthernetIpClientCallback extends IpClientCallbacks { private class EthernetIpClientCallback extends IpClientCallbacks {
private final ConditionVariable mIpClientStartCv = new ConditionVariable(false); private final ConditionVariable mIpClientStartCv = new ConditionVariable(false);
private final ConditionVariable mIpClientShutdownCv = new ConditionVariable(false); private final ConditionVariable mIpClientShutdownCv = new ConditionVariable(false);
@Nullable INetworkInterfaceOutcomeReceiver mNetworkManagementListener; EthernetCallback mCb;
EthernetIpClientCallback(@Nullable final INetworkInterfaceOutcomeReceiver listener) { EthernetIpClientCallback(EthernetCallback cb) {
mNetworkManagementListener = listener; mCb = cb;
} }
@Override @Override
@@ -372,14 +361,14 @@ public class EthernetNetworkFactory {
@Override @Override
public void onProvisioningSuccess(LinkProperties newLp) { public void onProvisioningSuccess(LinkProperties newLp) {
handleIpEvent(() -> onIpLayerStarted(newLp, mNetworkManagementListener)); handleIpEvent(() -> onIpLayerStarted(newLp));
} }
@Override @Override
public void onProvisioningFailure(LinkProperties newLp) { public void onProvisioningFailure(LinkProperties newLp) {
// This cannot happen due to provisioning timeout, because our timeout is 0. It can // This cannot happen due to provisioning timeout, because our timeout is 0. It can
// happen due to errors while provisioning or on provisioning loss. // happen due to errors while provisioning or on provisioning loss.
handleIpEvent(() -> onIpLayerStopped(mNetworkManagementListener)); handleIpEvent(() -> onIpLayerStopped(mCb));
} }
@Override @Override
@@ -492,12 +481,12 @@ public class EthernetNetworkFactory {
void updateInterface(@Nullable final IpConfiguration ipConfig, void updateInterface(@Nullable final IpConfiguration ipConfig,
@Nullable final NetworkCapabilities capabilities, @Nullable final NetworkCapabilities capabilities,
@Nullable final INetworkInterfaceOutcomeReceiver listener) { final EthernetCallback cb) {
if (DBG) { if (DBG) {
Log.d(TAG, "updateInterface, iface: " + name Log.d(TAG, "updateInterface, iface: " + name
+ ", ipConfig: " + ipConfig + ", old ipConfig: " + mIpConfig + ", ipConfig: " + ipConfig + ", old ipConfig: " + mIpConfig
+ ", capabilities: " + capabilities + ", old capabilities: " + mCapabilities + ", capabilities: " + capabilities + ", old capabilities: " + mCapabilities
+ ", listener: " + listener + ", cb: " + cb
); );
} }
@@ -510,7 +499,7 @@ public class EthernetNetworkFactory {
// TODO: Update this logic to only do a restart if required. Although a restart may // TODO: Update this logic to only do a restart if required. Although a restart may
// be required due to the capabilities or ipConfiguration values, not all // be required due to the capabilities or ipConfiguration values, not all
// capabilities changes require a restart. // capabilities changes require a restart.
restart(listener); restart(cb);
} }
boolean isRestricted() { boolean isRestricted() {
@@ -518,10 +507,11 @@ public class EthernetNetworkFactory {
} }
private void start() { private void start() {
start(null); // TODO: remove EthernetCallback from this class entirely.
start(new EthernetCallback(null));
} }
private void start(@Nullable final INetworkInterfaceOutcomeReceiver listener) { private void start(EthernetCallback cb) {
if (mIpClient != null) { if (mIpClient != null) {
if (DBG) Log.d(TAG, "IpClient already started"); if (DBG) Log.d(TAG, "IpClient already started");
return; return;
@@ -530,7 +520,7 @@ public class EthernetNetworkFactory {
Log.d(TAG, String.format("Starting Ethernet IpClient(%s)", name)); Log.d(TAG, String.format("Starting Ethernet IpClient(%s)", name));
} }
mIpClientCallback = new EthernetIpClientCallback(listener); mIpClientCallback = new EthernetIpClientCallback(cb);
mDeps.makeIpClient(mContext, name, mIpClientCallback); mDeps.makeIpClient(mContext, name, mIpClientCallback);
mIpClientCallback.awaitIpClientStart(); mIpClientCallback.awaitIpClientStart();
@@ -540,8 +530,7 @@ public class EthernetNetworkFactory {
provisionIpClient(mIpClient, mIpConfig, sTcpBufferSizes); provisionIpClient(mIpClient, mIpConfig, sTcpBufferSizes);
} }
void onIpLayerStarted(@NonNull final LinkProperties linkProperties, void onIpLayerStarted(@NonNull final LinkProperties linkProperties) {
@Nullable final INetworkInterfaceOutcomeReceiver listener) {
if (mNetworkAgent != null) { if (mNetworkAgent != null) {
Log.e(TAG, "Already have a NetworkAgent - aborting new request"); Log.e(TAG, "Already have a NetworkAgent - aborting new request");
stop(); stop();
@@ -576,7 +565,7 @@ public class EthernetNetworkFactory {
realizeNetworkManagementCallback(name, null); realizeNetworkManagementCallback(name, null);
} }
void onIpLayerStopped(@Nullable final INetworkInterfaceOutcomeReceiver listener) { void onIpLayerStopped(EthernetCallback cb) {
// There is no point in continuing if the interface is gone as stop() will be triggered // There is no point in continuing if the interface is gone as stop() will be triggered
// by removeInterface() when processed on the handler thread and start() won't // by removeInterface() when processed on the handler thread and start() won't
// work for a non-existent interface. // work for a non-existent interface.
@@ -586,27 +575,25 @@ public class EthernetNetworkFactory {
maybeSendNetworkManagementCallbackForAbort(); maybeSendNetworkManagementCallbackForAbort();
return; return;
} }
restart(listener); restart(cb);
} }
private void maybeSendNetworkManagementCallbackForAbort() { private void maybeSendNetworkManagementCallbackForAbort() {
realizeNetworkManagementCallback(null, realizeNetworkManagementCallback(null, "The IP provisioning request has been aborted.");
new EthernetNetworkManagementException(
"The IP provisioning request has been aborted."));
} }
// Must be called on the handler thread // Must be called on the handler thread
private void realizeNetworkManagementCallback(@Nullable final String iface, private void realizeNetworkManagementCallback(@Nullable final String iface,
@Nullable final EthernetNetworkManagementException e) { @Nullable String msg) {
ensureRunningOnEthernetHandlerThread(); ensureRunningOnEthernetHandlerThread();
if (null == mIpClientCallback) { if (null == mIpClientCallback) {
return; return;
} }
EthernetNetworkFactory.maybeSendNetworkManagementCallback( EthernetNetworkFactory.maybeSendNetworkManagementCallback(
mIpClientCallback.mNetworkManagementListener, iface, e); mIpClientCallback.mCb, iface, msg);
// Only send a single callback per listener. // Only send a single callback per cb.
mIpClientCallback.mNetworkManagementListener = null; mIpClientCallback.mCb = new EthernetCallback(null /* null */);
} }
private void ensureRunningOnEthernetHandlerThread() { private void ensureRunningOnEthernetHandlerThread() {
@@ -636,12 +623,10 @@ public class EthernetNetworkFactory {
} }
/** Returns true if state has been modified */ /** Returns true if state has been modified */
boolean updateLinkState(final boolean up, boolean updateLinkState(final boolean up, final EthernetCallback cb) {
@Nullable final INetworkInterfaceOutcomeReceiver listener) {
if (mLinkUp == up) { if (mLinkUp == up) {
EthernetNetworkFactory.maybeSendNetworkManagementCallback(listener, null, EthernetNetworkFactory.maybeSendNetworkManagementCallback(cb, null,
new EthernetNetworkManagementException( "No changes with requested link state " + up + " for " + name);
"No changes with requested link state " + up + " for " + name));
return false; return false;
} }
mLinkUp = up; mLinkUp = up;
@@ -654,7 +639,7 @@ public class EthernetNetworkFactory {
registerNetworkOffer(); registerNetworkOffer();
} }
EthernetNetworkFactory.maybeSendNetworkManagementCallback(listener, name, null); EthernetNetworkFactory.maybeSendNetworkManagementCallback(cb, name, null);
return true; return true;
} }
@@ -723,13 +708,14 @@ public class EthernetNetworkFactory {
} }
void restart() { void restart() {
restart(null); // TODO: remove EthernetCallback from this class entirely
restart(new EthernetCallback(null));
} }
void restart(@Nullable final INetworkInterfaceOutcomeReceiver listener) { void restart(EthernetCallback cb) {
if (DBG) Log.d(TAG, "reconnecting Ethernet"); if (DBG) Log.d(TAG, "reconnecting Ethernet");
stop(); stop();
start(listener); start(cb);
} }
@Override @Override

View File

@@ -260,7 +260,7 @@ public class EthernetServiceImpl extends IEthernetManager.Stub {
@Override @Override
public void updateConfiguration(@NonNull final String iface, public void updateConfiguration(@NonNull final String iface,
@NonNull final EthernetNetworkUpdateRequest request, @NonNull final EthernetNetworkUpdateRequest request,
@Nullable final INetworkInterfaceOutcomeReceiver listener) { @Nullable final INetworkInterfaceOutcomeReceiver cb) {
Objects.requireNonNull(iface); Objects.requireNonNull(iface);
Objects.requireNonNull(request); Objects.requireNonNull(request);
throwIfEthernetNotStarted(); throwIfEthernetNotStarted();
@@ -277,31 +277,31 @@ public class EthernetServiceImpl extends IEthernetManager.Stub {
} }
mTracker.updateConfiguration( mTracker.updateConfiguration(
iface, request.getIpConfiguration(), nc, listener); iface, request.getIpConfiguration(), nc, new EthernetCallback(cb));
} }
@Override @Override
public void enableInterface(@NonNull final String iface, public void enableInterface(@NonNull final String iface,
@Nullable final INetworkInterfaceOutcomeReceiver listener) { @Nullable final INetworkInterfaceOutcomeReceiver cb) {
Log.i(TAG, "enableInterface called with: iface=" + iface + ", listener=" + listener); Log.i(TAG, "enableInterface called with: iface=" + iface + ", cb=" + cb);
Objects.requireNonNull(iface); Objects.requireNonNull(iface);
throwIfEthernetNotStarted(); throwIfEthernetNotStarted();
enforceAdminPermission(iface, false, "enableInterface()"); enforceAdminPermission(iface, false, "enableInterface()");
mTracker.enableInterface(iface, listener); mTracker.enableInterface(iface, new EthernetCallback(cb));
} }
@Override @Override
public void disableInterface(@NonNull final String iface, public void disableInterface(@NonNull final String iface,
@Nullable final INetworkInterfaceOutcomeReceiver listener) { @Nullable final INetworkInterfaceOutcomeReceiver cb) {
Log.i(TAG, "disableInterface called with: iface=" + iface + ", listener=" + listener); Log.i(TAG, "disableInterface called with: iface=" + iface + ", cb=" + cb);
Objects.requireNonNull(iface); Objects.requireNonNull(iface);
throwIfEthernetNotStarted(); throwIfEthernetNotStarted();
enforceAdminPermission(iface, false, "disableInterface()"); enforceAdminPermission(iface, false, "disableInterface()");
mTracker.disableInterface(iface, listener); mTracker.disableInterface(iface, new EthernetCallback(cb));
} }
@Override @Override

View File

@@ -29,7 +29,6 @@ import android.net.ConnectivityResources;
import android.net.EthernetManager; import android.net.EthernetManager;
import android.net.IEthernetServiceListener; import android.net.IEthernetServiceListener;
import android.net.INetd; import android.net.INetd;
import android.net.INetworkInterfaceOutcomeReceiver;
import android.net.ITetheredInterfaceCallback; import android.net.ITetheredInterfaceCallback;
import android.net.InterfaceConfigurationParcel; import android.net.InterfaceConfigurationParcel;
import android.net.IpConfiguration; import android.net.IpConfiguration;
@@ -335,7 +334,7 @@ public class EthernetTracker {
protected void updateConfiguration(@NonNull final String iface, protected void updateConfiguration(@NonNull final String iface,
@Nullable final IpConfiguration ipConfig, @Nullable final IpConfiguration ipConfig,
@Nullable final NetworkCapabilities capabilities, @Nullable final NetworkCapabilities capabilities,
@Nullable final INetworkInterfaceOutcomeReceiver listener) { @Nullable final EthernetCallback cb) {
if (DBG) { if (DBG) {
Log.i(TAG, "updateConfiguration, iface: " + iface + ", capabilities: " + capabilities Log.i(TAG, "updateConfiguration, iface: " + iface + ", capabilities: " + capabilities
+ ", ipConfig: " + ipConfig); + ", ipConfig: " + ipConfig);
@@ -353,21 +352,21 @@ public class EthernetTracker {
mNetworkCapabilities.put(iface, capabilities); mNetworkCapabilities.put(iface, capabilities);
} }
mHandler.post(() -> { mHandler.post(() -> {
mFactory.updateInterface(iface, localIpConfig, capabilities, listener); mFactory.updateInterface(iface, localIpConfig, capabilities, cb);
broadcastInterfaceStateChange(iface); broadcastInterfaceStateChange(iface);
}); });
} }
@VisibleForTesting(visibility = PACKAGE) @VisibleForTesting(visibility = PACKAGE)
protected void enableInterface(@NonNull final String iface, protected void enableInterface(@NonNull final String iface,
@Nullable final INetworkInterfaceOutcomeReceiver listener) { @Nullable final EthernetCallback cb) {
mHandler.post(() -> updateInterfaceState(iface, true, listener)); mHandler.post(() -> updateInterfaceState(iface, true, cb));
} }
@VisibleForTesting(visibility = PACKAGE) @VisibleForTesting(visibility = PACKAGE)
protected void disableInterface(@NonNull final String iface, protected void disableInterface(@NonNull final String iface,
@Nullable final INetworkInterfaceOutcomeReceiver listener) { @Nullable final EthernetCallback cb) {
mHandler.post(() -> updateInterfaceState(iface, false, listener)); mHandler.post(() -> updateInterfaceState(iface, false, cb));
} }
IpConfiguration getIpConfiguration(String iface) { IpConfiguration getIpConfiguration(String iface) {
@@ -614,14 +613,15 @@ public class EthernetTracker {
} }
private void updateInterfaceState(String iface, boolean up) { private void updateInterfaceState(String iface, boolean up) {
updateInterfaceState(iface, up, null /* listener */); // TODO: pull EthernetCallbacks out of EthernetNetworkFactory.
updateInterfaceState(iface, up, new EthernetCallback(null /* cb */));
} }
private void updateInterfaceState(@NonNull final String iface, final boolean up, private void updateInterfaceState(@NonNull final String iface, final boolean up,
@Nullable final INetworkInterfaceOutcomeReceiver listener) { @Nullable final EthernetCallback cb) {
final int mode = getInterfaceMode(iface); final int mode = getInterfaceMode(iface);
final boolean factoryLinkStateUpdated = (mode == INTERFACE_MODE_CLIENT) final boolean factoryLinkStateUpdated = (mode == INTERFACE_MODE_CLIENT)
&& mFactory.updateInterfaceLinkState(iface, up, listener); && mFactory.updateInterfaceLinkState(iface, up, cb);
if (factoryLinkStateUpdated) { if (factoryLinkStateUpdated) {
broadcastInterfaceStateChange(iface); broadcastInterfaceStateChange(iface);

View File

@@ -40,7 +40,6 @@ import android.content.res.Resources;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.EthernetNetworkManagementException; import android.net.EthernetNetworkManagementException;
import android.net.EthernetNetworkSpecifier; import android.net.EthernetNetworkSpecifier;
import android.net.INetworkInterfaceOutcomeReceiver;
import android.net.IpConfiguration; import android.net.IpConfiguration;
import android.net.LinkAddress; import android.net.LinkAddress;
import android.net.LinkProperties; import android.net.LinkProperties;
@@ -55,7 +54,6 @@ import android.net.ip.IpClientCallbacks;
import android.net.ip.IpClientManager; import android.net.ip.IpClientManager;
import android.os.Build; import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder;
import android.os.Looper; import android.os.Looper;
import android.os.test.TestLooper; import android.os.test.TestLooper;
@@ -84,7 +82,7 @@ import java.util.concurrent.TimeUnit;
public class EthernetNetworkFactoryTest { public class EthernetNetworkFactoryTest {
private static final int TIMEOUT_MS = 2_000; private static final int TIMEOUT_MS = 2_000;
private static final String TEST_IFACE = "test123"; private static final String TEST_IFACE = "test123";
private static final INetworkInterfaceOutcomeReceiver NULL_LISTENER = null; private static final EthernetCallback NULL_CB = new EthernetCallback(null);
private static final String IP_ADDR = "192.0.2.2/25"; private static final String IP_ADDR = "192.0.2.2/25";
private static final LinkAddress LINK_ADDR = new LinkAddress(IP_ADDR); private static final LinkAddress LINK_ADDR = new LinkAddress(IP_ADDR);
private static final String HW_ADDR = "01:02:03:04:05:06"; private static final String HW_ADDR = "01:02:03:04:05:06";
@@ -241,7 +239,7 @@ public class EthernetNetworkFactoryTest {
final IpConfiguration ipConfig = createDefaultIpConfig(); final IpConfiguration ipConfig = createDefaultIpConfig();
mNetFactory.addInterface(iface, HW_ADDR, ipConfig, mNetFactory.addInterface(iface, HW_ADDR, ipConfig,
createInterfaceCapsBuilder(transportType).build()); createInterfaceCapsBuilder(transportType).build());
assertTrue(mNetFactory.updateInterfaceLinkState(iface, true, NULL_LISTENER)); assertTrue(mNetFactory.updateInterfaceLinkState(iface, true, NULL_CB));
ArgumentCaptor<NetworkOfferCallback> captor = ArgumentCaptor.forClass( ArgumentCaptor<NetworkOfferCallback> captor = ArgumentCaptor.forClass(
NetworkOfferCallback.class); NetworkOfferCallback.class);
@@ -295,7 +293,7 @@ public class EthernetNetworkFactoryTest {
// then calling onNetworkUnwanted. // then calling onNetworkUnwanted.
mNetFactory.addInterface(iface, HW_ADDR, createDefaultIpConfig(), mNetFactory.addInterface(iface, HW_ADDR, createDefaultIpConfig(),
createInterfaceCapsBuilder(NetworkCapabilities.TRANSPORT_ETHERNET).build()); createInterfaceCapsBuilder(NetworkCapabilities.TRANSPORT_ETHERNET).build());
assertTrue(mNetFactory.updateInterfaceLinkState(iface, true, NULL_LISTENER)); assertTrue(mNetFactory.updateInterfaceLinkState(iface, true, NULL_CB));
clearInvocations(mIpClient); clearInvocations(mIpClient);
clearInvocations(mNetworkAgent); clearInvocations(mNetworkAgent);
@@ -572,17 +570,21 @@ public class EthernetNetworkFactoryTest {
} }
private static final class TestNetworkManagementListener private static final class TestNetworkManagementListener
implements INetworkInterfaceOutcomeReceiver { extends EthernetCallback {
private final CompletableFuture<String> mResult = new CompletableFuture<>(); private final CompletableFuture<String> mResult = new CompletableFuture<>();
TestNetworkManagementListener() {
super(null);
}
@Override @Override
public void onResult(@NonNull String iface) { public void onResult(@NonNull String iface) {
mResult.complete(iface); mResult.complete(iface);
} }
@Override @Override
public void onError(@NonNull EthernetNetworkManagementException exception) { public void onError(String msg) {
mResult.completeExceptionally(exception); mResult.completeExceptionally(new EthernetNetworkManagementException(msg));
} }
String expectOnResult() throws Exception { String expectOnResult() throws Exception {
@@ -598,11 +600,6 @@ public class EthernetNetworkFactoryTest {
} }
}); });
} }
@Override
public IBinder asBinder() {
return null;
}
} }
@Test @Test
@@ -632,7 +629,7 @@ public class EthernetNetworkFactoryTest {
initEthernetNetworkFactory(); initEthernetNetworkFactory();
verifyNetworkManagementCallIsAbortedWhenInterrupted( verifyNetworkManagementCallIsAbortedWhenInterrupted(
TEST_IFACE, TEST_IFACE,
() -> mNetFactory.updateInterfaceLinkState(TEST_IFACE, false, NULL_LISTENER)); () -> mNetFactory.updateInterfaceLinkState(TEST_IFACE, false, NULL_CB));
} }
@Test @Test
@@ -718,7 +715,7 @@ public class EthernetNetworkFactoryTest {
final IpConfiguration initialIpConfig = createStaticIpConfig(); final IpConfiguration initialIpConfig = createStaticIpConfig();
mNetFactory.updateInterface(TEST_IFACE, initialIpConfig, null /*capabilities*/, mNetFactory.updateInterface(TEST_IFACE, initialIpConfig, null /*capabilities*/,
null /*listener*/); new EthernetCallback(null /* cb */));
triggerOnProvisioningSuccess(); triggerOnProvisioningSuccess();
verifyRestart(initialIpConfig); verifyRestart(initialIpConfig);
@@ -730,7 +727,7 @@ public class EthernetNetworkFactoryTest {
// verify that sending a null ipConfig does not update the current ipConfig. // verify that sending a null ipConfig does not update the current ipConfig.
mNetFactory.updateInterface(TEST_IFACE, null /*ipConfig*/, null /*capabilities*/, mNetFactory.updateInterface(TEST_IFACE, null /*ipConfig*/, null /*capabilities*/,
null /*listener*/); new EthernetCallback(null /* cb */));
triggerOnProvisioningSuccess(); triggerOnProvisioningSuccess();
verifyRestart(initialIpConfig); verifyRestart(initialIpConfig);
} }
@@ -739,7 +736,7 @@ public class EthernetNetworkFactoryTest {
public void testOnNetworkNeededOnStaleNetworkOffer() throws Exception { public void testOnNetworkNeededOnStaleNetworkOffer() throws Exception {
initEthernetNetworkFactory(); initEthernetNetworkFactory();
createAndVerifyProvisionedInterface(TEST_IFACE); createAndVerifyProvisionedInterface(TEST_IFACE);
mNetFactory.updateInterfaceLinkState(TEST_IFACE, false, null); mNetFactory.updateInterfaceLinkState(TEST_IFACE, false, new EthernetCallback(null));
verify(mNetworkProvider).unregisterNetworkOffer(mNetworkOfferCallback); verify(mNetworkProvider).unregisterNetworkOffer(mNetworkOfferCallback);
// It is possible that even after a network offer is unregistered, CS still sends it // It is possible that even after a network offer is unregistered, CS still sends it
// onNetworkNeeded() callbacks. // onNetworkNeeded() callbacks.

View File

@@ -21,6 +21,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_TEST;
import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertThrows;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.ArgumentMatchers.isNull;
@@ -209,7 +210,8 @@ public class EthernetServiceImplTest {
NULL_LISTENER); NULL_LISTENER);
verify(mEthernetTracker).updateConfiguration(eq(TEST_IFACE), verify(mEthernetTracker).updateConfiguration(eq(TEST_IFACE),
eq(UPDATE_REQUEST_WITHOUT_CAPABILITIES.getIpConfiguration()), eq(UPDATE_REQUEST_WITHOUT_CAPABILITIES.getIpConfiguration()),
eq(UPDATE_REQUEST_WITHOUT_CAPABILITIES.getNetworkCapabilities()), isNull()); eq(UPDATE_REQUEST_WITHOUT_CAPABILITIES.getNetworkCapabilities()),
any(EthernetCallback.class));
} }
private void denyManageEthPermission() { private void denyManageEthPermission() {
@@ -285,7 +287,8 @@ public class EthernetServiceImplTest {
verify(mEthernetTracker).updateConfiguration( verify(mEthernetTracker).updateConfiguration(
eq(TEST_IFACE), eq(TEST_IFACE),
eq(UPDATE_REQUEST.getIpConfiguration()), eq(UPDATE_REQUEST.getIpConfiguration()),
eq(UPDATE_REQUEST.getNetworkCapabilities()), eq(NULL_LISTENER)); eq(UPDATE_REQUEST.getNetworkCapabilities()),
any(EthernetCallback.class));
} }
@Test @Test
@@ -303,19 +306,20 @@ public class EthernetServiceImplTest {
verify(mEthernetTracker).updateConfiguration( verify(mEthernetTracker).updateConfiguration(
eq(TEST_IFACE), eq(TEST_IFACE),
isNull(), isNull(),
eq(ncWithSpecifier), eq(NULL_LISTENER)); eq(ncWithSpecifier), any(EthernetCallback.class));
} }
@Test @Test
public void testEnableInterface() { public void testEnableInterface() {
mEthernetServiceImpl.enableInterface(TEST_IFACE, NULL_LISTENER); mEthernetServiceImpl.enableInterface(TEST_IFACE, NULL_LISTENER);
verify(mEthernetTracker).enableInterface(eq(TEST_IFACE), eq(NULL_LISTENER)); verify(mEthernetTracker).enableInterface(eq(TEST_IFACE),
any(EthernetCallback.class));
} }
@Test @Test
public void testDisableInterface() { public void testDisableInterface() {
mEthernetServiceImpl.disableInterface(TEST_IFACE, NULL_LISTENER); mEthernetServiceImpl.disableInterface(TEST_IFACE, NULL_LISTENER);
verify(mEthernetTracker).disableInterface(eq(TEST_IFACE), eq(NULL_LISTENER)); verify(mEthernetTracker).disableInterface(eq(TEST_IFACE), any(EthernetCallback.class));
} }
@Test @Test
@@ -328,7 +332,7 @@ public class EthernetServiceImplTest {
mEthernetServiceImpl.updateConfiguration(TEST_IFACE, request, NULL_LISTENER); mEthernetServiceImpl.updateConfiguration(TEST_IFACE, request, NULL_LISTENER);
verify(mEthernetTracker).updateConfiguration(eq(TEST_IFACE), verify(mEthernetTracker).updateConfiguration(eq(TEST_IFACE),
eq(request.getIpConfiguration()), eq(request.getIpConfiguration()),
eq(request.getNetworkCapabilities()), isNull()); eq(request.getNetworkCapabilities()), any(EthernetCallback.class));
} }
@Test @Test
@@ -337,7 +341,8 @@ public class EthernetServiceImplTest {
NULL_LISTENER); NULL_LISTENER);
verify(mEthernetTracker).updateConfiguration(eq(TEST_IFACE), verify(mEthernetTracker).updateConfiguration(eq(TEST_IFACE),
eq(UPDATE_REQUEST_WITHOUT_IP_CONFIG.getIpConfiguration()), eq(UPDATE_REQUEST_WITHOUT_IP_CONFIG.getIpConfiguration()),
eq(UPDATE_REQUEST_WITHOUT_IP_CONFIG.getNetworkCapabilities()), isNull()); eq(UPDATE_REQUEST_WITHOUT_IP_CONFIG.getNetworkCapabilities()),
any(EthernetCallback.class));
} }
@Test @Test
@@ -369,7 +374,7 @@ public class EthernetServiceImplTest {
verify(mEthernetTracker).updateConfiguration( verify(mEthernetTracker).updateConfiguration(
eq(TEST_IFACE), eq(TEST_IFACE),
eq(request.getIpConfiguration()), eq(request.getIpConfiguration()),
eq(request.getNetworkCapabilities()), eq(NULL_LISTENER)); eq(request.getNetworkCapabilities()), any(EthernetCallback.class));
} }
@Test @Test
@@ -379,7 +384,8 @@ public class EthernetServiceImplTest {
denyManageEthPermission(); denyManageEthPermission();
mEthernetServiceImpl.enableInterface(TEST_IFACE, NULL_LISTENER); mEthernetServiceImpl.enableInterface(TEST_IFACE, NULL_LISTENER);
verify(mEthernetTracker).enableInterface(eq(TEST_IFACE), eq(NULL_LISTENER)); verify(mEthernetTracker).enableInterface(eq(TEST_IFACE),
any(EthernetCallback.class));
} }
@Test @Test
@@ -389,7 +395,8 @@ public class EthernetServiceImplTest {
denyManageEthPermission(); denyManageEthPermission();
mEthernetServiceImpl.disableInterface(TEST_IFACE, NULL_LISTENER); mEthernetServiceImpl.disableInterface(TEST_IFACE, NULL_LISTENER);
verify(mEthernetTracker).disableInterface(eq(TEST_IFACE), eq(NULL_LISTENER)); verify(mEthernetTracker).disableInterface(eq(TEST_IFACE),
any(EthernetCallback.class));
} }
private void denyPermissions(String... permissions) { private void denyPermissions(String... permissions) {

View File

@@ -39,7 +39,6 @@ import android.content.Context;
import android.net.EthernetManager; import android.net.EthernetManager;
import android.net.IEthernetServiceListener; import android.net.IEthernetServiceListener;
import android.net.INetd; import android.net.INetd;
import android.net.INetworkInterfaceOutcomeReceiver;
import android.net.InetAddresses; import android.net.InetAddresses;
import android.net.InterfaceConfigurationParcel; import android.net.InterfaceConfigurationParcel;
import android.net.IpConfiguration; import android.net.IpConfiguration;
@@ -76,7 +75,7 @@ public class EthernetTrackerTest {
private static final String TEST_IFACE = "test123"; private static final String TEST_IFACE = "test123";
private static final int TIMEOUT_MS = 1_000; private static final int TIMEOUT_MS = 1_000;
private static final String THREAD_NAME = "EthernetServiceThread"; private static final String THREAD_NAME = "EthernetServiceThread";
private static final INetworkInterfaceOutcomeReceiver NULL_LISTENER = null; private static final EthernetCallback NULL_CB = new EthernetCallback(null);
private EthernetTracker tracker; private EthernetTracker tracker;
private HandlerThread mHandlerThread; private HandlerThread mHandlerThread;
@Mock private Context mContext; @Mock private Context mContext;
@@ -344,7 +343,7 @@ public class EthernetTrackerTest {
new StaticIpConfiguration.Builder().setIpAddress(linkAddr).build(); new StaticIpConfiguration.Builder().setIpAddress(linkAddr).build();
final IpConfiguration ipConfig = final IpConfiguration ipConfig =
new IpConfiguration.Builder().setStaticIpConfiguration(staticIpConfig).build(); new IpConfiguration.Builder().setStaticIpConfiguration(staticIpConfig).build();
final INetworkInterfaceOutcomeReceiver listener = null; final EthernetCallback listener = new EthernetCallback(null);
tracker.updateConfiguration(TEST_IFACE, ipConfig, capabilities, listener); tracker.updateConfiguration(TEST_IFACE, ipConfig, capabilities, listener);
waitForIdle(); waitForIdle();
@@ -355,20 +354,20 @@ public class EthernetTrackerTest {
@Test @Test
public void testEnableInterfaceCorrectlyCallsFactory() { public void testEnableInterfaceCorrectlyCallsFactory() {
tracker.enableInterface(TEST_IFACE, NULL_LISTENER); tracker.enableInterface(TEST_IFACE, NULL_CB);
waitForIdle(); waitForIdle();
verify(mFactory).updateInterfaceLinkState(eq(TEST_IFACE), eq(true /* up */), verify(mFactory).updateInterfaceLinkState(eq(TEST_IFACE), eq(true /* up */),
eq(NULL_LISTENER)); eq(NULL_CB));
} }
@Test @Test
public void testDisableInterfaceCorrectlyCallsFactory() { public void testDisableInterfaceCorrectlyCallsFactory() {
tracker.disableInterface(TEST_IFACE, NULL_LISTENER); tracker.disableInterface(TEST_IFACE, NULL_CB);
waitForIdle(); waitForIdle();
verify(mFactory).updateInterfaceLinkState(eq(TEST_IFACE), eq(false /* up */), verify(mFactory).updateInterfaceLinkState(eq(TEST_IFACE), eq(false /* up */),
eq(NULL_LISTENER)); eq(NULL_CB));
} }
@Test @Test