[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 Ignore-AOSP-First: avoid long automerger delay Change-Id: I6505a04de8c57357dd1fa9ce898c13395e497816
This commit is contained in:
@@ -24,10 +24,10 @@ import android.annotation.IntDef;
|
||||
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.os.RemoteException;
|
||||
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 class OffloadHardwareInterface {
|
||||
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 @@ public class OffloadHardwareInterface {
|
||||
(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 @@ public class OffloadHardwareInterface {
|
||||
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 class OffloadHardwareInterface {
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -22,22 +22,27 @@ import static android.system.OsConstants.AF_UNIX;
|
||||
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.Before;
|
||||
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 @@ public final class OffloadHardwareInterfaceTest {
|
||||
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 @@ public final class OffloadHardwareInterfaceTest {
|
||||
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 @@ public final class OffloadHardwareInterfaceTest {
|
||||
|
||||
@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 @@ public final class OffloadHardwareInterfaceTest {
|
||||
@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 @@ public final class OffloadHardwareInterfaceTest {
|
||||
|
||||
@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 @@ public final class OffloadHardwareInterfaceTest {
|
||||
|
||||
@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 @@ public final class OffloadHardwareInterfaceTest {
|
||||
|
||||
@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 @@ public final class OffloadHardwareInterfaceTest {
|
||||
|
||||
@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 @@ public final class OffloadHardwareInterfaceTest {
|
||||
|
||||
@Test
|
||||
public void testTetheringOffloadCallback() throws Exception {
|
||||
startOffloadHardwareInterface();
|
||||
startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
|
||||
|
||||
mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STARTED);
|
||||
mTestLooper.dispatchAll();
|
||||
@@ -221,10 +257,26 @@ public final class OffloadHardwareInterfaceTest {
|
||||
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 {
|
||||
|
||||
Reference in New Issue
Block a user