[SP33] Adapt ITetheringOffloadCallback V1.1
This is a no-op change that redirect both V1.0 and V1.1 callback
events to the same handling function. Since the V1.1 callback
is extended from V1.0 callback, we can safely use V1.1
callback for both V1.0 and V1.1 control.
The change also provides interface for subsequent
OffloadController changes to set warning and limit at the
same time.
Test: atest TetheringTests
Bug: 149467454
Merged-In: I6505a04de8c57357dd1fa9ce898c13395e497816
Change-Id: I6505a04de8c57357dd1fa9ce898c13395e497816
(cherry-picked from ag/13973147)
diff --git a/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java b/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
index 7685847..e3ac660 100644
--- a/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
+++ b/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
@@ -24,10 +24,10 @@
import android.annotation.NonNull;
import android.hardware.tetheroffload.config.V1_0.IOffloadConfig;
import android.hardware.tetheroffload.control.V1_0.IOffloadControl;
-import android.hardware.tetheroffload.control.V1_0.ITetheringOffloadCallback;
import android.hardware.tetheroffload.control.V1_0.NatTimeoutUpdate;
import android.hardware.tetheroffload.control.V1_0.NetworkProtocol;
import android.hardware.tetheroffload.control.V1_0.OffloadCallbackEvent;
+import android.hardware.tetheroffload.control.V1_1.ITetheringOffloadCallback;
import android.net.netlink.NetlinkSocket;
import android.net.netlink.StructNfGenMsg;
import android.net.netlink.StructNlMsgHdr;
@@ -39,6 +39,7 @@
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
+import android.util.Log;
import android.util.Pair;
import com.android.internal.annotations.VisibleForTesting;
@@ -140,6 +141,8 @@
public void onSupportAvailable() {}
/** Offload stopped because of usage limit reached. */
public void onStoppedLimitReached() {}
+ /** Indicate that data warning quota is reached. */
+ public void onWarningReached() {}
/** Indicate to update NAT timeout. */
public void onNatTimeoutUpdate(int proto,
@@ -381,7 +384,8 @@
(controlCb == null) ? "null"
: "0x" + Integer.toHexString(System.identityHashCode(controlCb)));
- mTetheringOffloadCallback = new TetheringOffloadCallback(mHandler, mControlCallback, mLog);
+ mTetheringOffloadCallback = new TetheringOffloadCallback(
+ mHandler, mControlCallback, mLog, mOffloadControlVersion);
final CbResults results = new CbResults();
try {
mOffloadControl.initOffload(
@@ -480,6 +484,33 @@
return results.mSuccess;
}
+ /** Set data warning and limit value to offload management process. */
+ public boolean setDataWarningAndLimit(String iface, long warning, long limit) {
+ if (mOffloadControlVersion < OFFLOAD_HAL_VERSION_1_1) {
+ throw new IllegalArgumentException(
+ "setDataWarningAndLimit is not supported below HAL V1.1");
+ }
+ final String logmsg =
+ String.format("setDataWarningAndLimit(%s, %d, %d)", iface, warning, limit);
+
+ final CbResults results = new CbResults();
+ try {
+ ((android.hardware.tetheroffload.control.V1_1.IOffloadControl) mOffloadControl)
+ .setDataWarningAndLimit(
+ iface, warning, limit,
+ (boolean success, String errMsg) -> {
+ results.mSuccess = success;
+ results.mErrMsg = errMsg;
+ });
+ } catch (RemoteException e) {
+ record(logmsg, e);
+ return false;
+ }
+
+ record(logmsg, results);
+ return results.mSuccess;
+ }
+
/** Set upstream parameters to offload management process. */
public boolean setUpstreamParameters(
String iface, String v4addr, String v4gateway, ArrayList<String> v6gws) {
@@ -565,35 +596,64 @@
public final Handler handler;
public final ControlCallback controlCb;
public final SharedLog log;
+ private final int mOffloadControlVersion;
- TetheringOffloadCallback(Handler h, ControlCallback cb, SharedLog sharedLog) {
+ TetheringOffloadCallback(
+ Handler h, ControlCallback cb, SharedLog sharedLog, int offloadControlVersion) {
handler = h;
controlCb = cb;
log = sharedLog;
+ this.mOffloadControlVersion = offloadControlVersion;
+ }
+
+ private void handleOnEvent(int event) {
+ switch (event) {
+ case OffloadCallbackEvent.OFFLOAD_STARTED:
+ controlCb.onStarted();
+ break;
+ case OffloadCallbackEvent.OFFLOAD_STOPPED_ERROR:
+ controlCb.onStoppedError();
+ break;
+ case OffloadCallbackEvent.OFFLOAD_STOPPED_UNSUPPORTED:
+ controlCb.onStoppedUnsupported();
+ break;
+ case OffloadCallbackEvent.OFFLOAD_SUPPORT_AVAILABLE:
+ controlCb.onSupportAvailable();
+ break;
+ case OffloadCallbackEvent.OFFLOAD_STOPPED_LIMIT_REACHED:
+ controlCb.onStoppedLimitReached();
+ break;
+ case android.hardware.tetheroffload.control
+ .V1_1.OffloadCallbackEvent.OFFLOAD_WARNING_REACHED:
+ controlCb.onWarningReached();
+ break;
+ default:
+ log.e("Unsupported OffloadCallbackEvent: " + event);
+ }
}
@Override
public void onEvent(int event) {
+ // The implementation should never call onEvent()) if the event is already reported
+ // through newer callback.
+ if (mOffloadControlVersion > OFFLOAD_HAL_VERSION_1_0) {
+ Log.wtf(TAG, "onEvent(" + event + ") fired on HAL "
+ + halVerToString(mOffloadControlVersion));
+ }
handler.post(() -> {
- switch (event) {
- case OffloadCallbackEvent.OFFLOAD_STARTED:
- controlCb.onStarted();
- break;
- case OffloadCallbackEvent.OFFLOAD_STOPPED_ERROR:
- controlCb.onStoppedError();
- break;
- case OffloadCallbackEvent.OFFLOAD_STOPPED_UNSUPPORTED:
- controlCb.onStoppedUnsupported();
- break;
- case OffloadCallbackEvent.OFFLOAD_SUPPORT_AVAILABLE:
- controlCb.onSupportAvailable();
- break;
- case OffloadCallbackEvent.OFFLOAD_STOPPED_LIMIT_REACHED:
- controlCb.onStoppedLimitReached();
- break;
- default:
- log.e("Unsupported OffloadCallbackEvent: " + event);
- }
+ handleOnEvent(event);
+ });
+ }
+
+ @Override
+ public void onEvent_1_1(int event) {
+ if (mOffloadControlVersion < OFFLOAD_HAL_VERSION_1_1) {
+ Log.wtf(TAG, "onEvent_1_1(" + event + ") fired on HAL "
+ + halVerToString(mOffloadControlVersion));
+ return;
+ }
+ handler.post(() -> {
+ handleOnEvent(event);
});
}
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
index f4194e5..a8b3b92 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
@@ -22,22 +22,27 @@
import static android.system.OsConstants.SOCK_STREAM;
import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_1_0;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_1_1;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.hardware.tetheroffload.config.V1_0.IOffloadConfig;
import android.hardware.tetheroffload.control.V1_0.IOffloadControl;
-import android.hardware.tetheroffload.control.V1_0.ITetheringOffloadCallback;
import android.hardware.tetheroffload.control.V1_0.NatTimeoutUpdate;
import android.hardware.tetheroffload.control.V1_0.NetworkProtocol;
-import android.hardware.tetheroffload.control.V1_0.OffloadCallbackEvent;
+import android.hardware.tetheroffload.control.V1_1.ITetheringOffloadCallback;
+import android.hardware.tetheroffload.control.V1_1.OffloadCallbackEvent;
import android.net.netlink.StructNfGenMsg;
import android.net.netlink.StructNlMsgHdr;
import android.net.util.SharedLog;
@@ -56,6 +61,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -76,7 +82,7 @@
private OffloadHardwareInterface.ControlCallback mControlCallback;
@Mock private IOffloadConfig mIOffloadConfig;
- @Mock private IOffloadControl mIOffloadControl;
+ private IOffloadControl mIOffloadControl;
@Mock private NativeHandle mNativeHandle;
// Random values to test Netlink message.
@@ -84,8 +90,10 @@
private static final short TEST_FLAGS = 263;
class MyDependencies extends OffloadHardwareInterface.Dependencies {
- MyDependencies(SharedLog log) {
+ private final int mMockControlVersion;
+ MyDependencies(SharedLog log, final int mockControlVersion) {
super(log);
+ mMockControlVersion = mockControlVersion;
}
@Override
@@ -95,7 +103,19 @@
@Override
public Pair<IOffloadControl, Integer> getOffloadControl() {
- return new Pair<IOffloadControl, Integer>(mIOffloadControl, OFFLOAD_HAL_VERSION_1_0);
+ switch (mMockControlVersion) {
+ case OFFLOAD_HAL_VERSION_1_0:
+ mIOffloadControl = mock(IOffloadControl.class);
+ break;
+ case OFFLOAD_HAL_VERSION_1_1:
+ mIOffloadControl =
+ mock(android.hardware.tetheroffload.control.V1_1.IOffloadControl.class);
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid offload control version "
+ + mMockControlVersion);
+ }
+ return new Pair<IOffloadControl, Integer>(mIOffloadControl, mMockControlVersion);
}
@Override
@@ -107,14 +127,13 @@
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- final SharedLog log = new SharedLog("test");
- mOffloadHw = new OffloadHardwareInterface(new Handler(mTestLooper.getLooper()), log,
- new MyDependencies(log));
mControlCallback = spy(new OffloadHardwareInterface.ControlCallback());
}
- // TODO: Pass version to test version specific operations.
- private void startOffloadHardwareInterface() throws Exception {
+ private void startOffloadHardwareInterface(int controlVersion) throws Exception {
+ final SharedLog log = new SharedLog("test");
+ mOffloadHw = new OffloadHardwareInterface(new Handler(mTestLooper.getLooper()), log,
+ new MyDependencies(log, controlVersion));
mOffloadHw.initOffloadConfig();
mOffloadHw.initOffloadControl(mControlCallback);
final ArgumentCaptor<ITetheringOffloadCallback> mOffloadCallbackCaptor =
@@ -125,7 +144,7 @@
@Test
public void testGetForwardedStats() throws Exception {
- startOffloadHardwareInterface();
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
final OffloadHardwareInterface.ForwardedStats stats = mOffloadHw.getForwardedStats(RMNET0);
verify(mIOffloadControl).getForwardedStats(eq(RMNET0), any());
assertNotNull(stats);
@@ -133,7 +152,7 @@
@Test
public void testSetLocalPrefixes() throws Exception {
- startOffloadHardwareInterface();
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
final ArrayList<String> localPrefixes = new ArrayList<>();
localPrefixes.add("127.0.0.0/8");
localPrefixes.add("fe80::/64");
@@ -143,15 +162,32 @@
@Test
public void testSetDataLimit() throws Exception {
- startOffloadHardwareInterface();
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
final long limit = 12345;
mOffloadHw.setDataLimit(RMNET0, limit);
verify(mIOffloadControl).setDataLimit(eq(RMNET0), eq(limit), any());
}
@Test
+ public void testSetDataWarningAndLimit() throws Exception {
+ // Verify V1.0 control HAL would reject the function call with exception.
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
+ final long warning = 12345;
+ final long limit = 67890;
+ assertThrows(IllegalArgumentException.class,
+ () -> mOffloadHw.setDataWarningAndLimit(RMNET0, warning, limit));
+ reset(mIOffloadControl);
+
+ // Verify V1.1 control HAL could receive this function call.
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_1);
+ mOffloadHw.setDataWarningAndLimit(RMNET0, warning, limit);
+ verify((android.hardware.tetheroffload.control.V1_1.IOffloadControl) mIOffloadControl)
+ .setDataWarningAndLimit(eq(RMNET0), eq(warning), eq(limit), any());
+ }
+
+ @Test
public void testSetUpstreamParameters() throws Exception {
- startOffloadHardwareInterface();
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
final String v4addr = "192.168.10.1";
final String v4gateway = "192.168.10.255";
final ArrayList<String> v6gws = new ArrayList<>(0);
@@ -170,7 +206,7 @@
@Test
public void testUpdateDownstreamPrefix() throws Exception {
- startOffloadHardwareInterface();
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
final String ifName = "wlan1";
final String prefix = "192.168.43.0/24";
mOffloadHw.addDownstreamPrefix(ifName, prefix);
@@ -182,7 +218,7 @@
@Test
public void testTetheringOffloadCallback() throws Exception {
- startOffloadHardwareInterface();
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STARTED);
mTestLooper.dispatchAll();
@@ -221,10 +257,26 @@
eq(uint16(udpParams.src.port)),
eq(udpParams.dst.addr),
eq(uint16(udpParams.dst.port)));
+ reset(mControlCallback);
+
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_1);
+
+ // Verify the interface will process the events that comes from V1.1 HAL.
+ mTetheringOffloadCallback.onEvent_1_1(OffloadCallbackEvent.OFFLOAD_STARTED);
+ mTestLooper.dispatchAll();
+ final InOrder inOrder = inOrder(mControlCallback);
+ inOrder.verify(mControlCallback).onStarted();
+ inOrder.verifyNoMoreInteractions();
+
+ mTetheringOffloadCallback.onEvent_1_1(OffloadCallbackEvent.OFFLOAD_WARNING_REACHED);
+ mTestLooper.dispatchAll();
+ inOrder.verify(mControlCallback).onWarningReached();
+ inOrder.verifyNoMoreInteractions();
}
@Test
public void testSendIpv4NfGenMsg() throws Exception {
+ startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
FileDescriptor writeSocket = new FileDescriptor();
FileDescriptor readSocket = new FileDescriptor();
try {