[SP33] Adapt ITetheringOffloadCallback V1.1 am: 37a7e620b4

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/1626080

Change-Id: I70100d1ad855a7963cfc2c4d9de288bc2e8fe4b0
This commit is contained in:
junyulai
2021-06-24 10:41:39 +00:00
committed by Automerger Merge Worker
2 changed files with 150 additions and 38 deletions

View File

@@ -24,10 +24,10 @@ import android.annotation.IntDef;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.hardware.tetheroffload.config.V1_0.IOffloadConfig; import android.hardware.tetheroffload.config.V1_0.IOffloadConfig;
import android.hardware.tetheroffload.control.V1_0.IOffloadControl; 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.NatTimeoutUpdate;
import android.hardware.tetheroffload.control.V1_0.NetworkProtocol; import android.hardware.tetheroffload.control.V1_0.NetworkProtocol;
import android.hardware.tetheroffload.control.V1_0.OffloadCallbackEvent; 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.NetlinkSocket;
import android.net.netlink.StructNfGenMsg; import android.net.netlink.StructNfGenMsg;
import android.net.netlink.StructNlMsgHdr; import android.net.netlink.StructNlMsgHdr;
@@ -39,6 +39,7 @@ import android.os.RemoteException;
import android.system.ErrnoException; import android.system.ErrnoException;
import android.system.Os; import android.system.Os;
import android.system.OsConstants; import android.system.OsConstants;
import android.util.Log;
import android.util.Pair; import android.util.Pair;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
@@ -140,6 +141,8 @@ public class OffloadHardwareInterface {
public void onSupportAvailable() {} public void onSupportAvailable() {}
/** Offload stopped because of usage limit reached. */ /** Offload stopped because of usage limit reached. */
public void onStoppedLimitReached() {} public void onStoppedLimitReached() {}
/** Indicate that data warning quota is reached. */
public void onWarningReached() {}
/** Indicate to update NAT timeout. */ /** Indicate to update NAT timeout. */
public void onNatTimeoutUpdate(int proto, public void onNatTimeoutUpdate(int proto,
@@ -381,7 +384,8 @@ public class OffloadHardwareInterface {
(controlCb == null) ? "null" (controlCb == null) ? "null"
: "0x" + Integer.toHexString(System.identityHashCode(controlCb))); : "0x" + Integer.toHexString(System.identityHashCode(controlCb)));
mTetheringOffloadCallback = new TetheringOffloadCallback(mHandler, mControlCallback, mLog); mTetheringOffloadCallback = new TetheringOffloadCallback(
mHandler, mControlCallback, mLog, mOffloadControlVersion);
final CbResults results = new CbResults(); final CbResults results = new CbResults();
try { try {
mOffloadControl.initOffload( mOffloadControl.initOffload(
@@ -480,6 +484,33 @@ public class OffloadHardwareInterface {
return results.mSuccess; 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. */ /** Set upstream parameters to offload management process. */
public boolean setUpstreamParameters( public boolean setUpstreamParameters(
String iface, String v4addr, String v4gateway, ArrayList<String> v6gws) { String iface, String v4addr, String v4gateway, ArrayList<String> v6gws) {
@@ -565,35 +596,64 @@ public class OffloadHardwareInterface {
public final Handler handler; public final Handler handler;
public final ControlCallback controlCb; public final ControlCallback controlCb;
public final SharedLog log; 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; handler = h;
controlCb = cb; controlCb = cb;
log = sharedLog; 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 @Override
public void onEvent(int event) { 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(() -> { handler.post(() -> {
switch (event) { handleOnEvent(event);
case OffloadCallbackEvent.OFFLOAD_STARTED: });
controlCb.onStarted(); }
break;
case OffloadCallbackEvent.OFFLOAD_STOPPED_ERROR: @Override
controlCb.onStoppedError(); public void onEvent_1_1(int event) {
break; if (mOffloadControlVersion < OFFLOAD_HAL_VERSION_1_1) {
case OffloadCallbackEvent.OFFLOAD_STOPPED_UNSUPPORTED: Log.wtf(TAG, "onEvent_1_1(" + event + ") fired on HAL "
controlCb.onStoppedUnsupported(); + halVerToString(mOffloadControlVersion));
break; return;
case OffloadCallbackEvent.OFFLOAD_SUPPORT_AVAILABLE: }
controlCb.onSupportAvailable(); handler.post(() -> {
break; handleOnEvent(event);
case OffloadCallbackEvent.OFFLOAD_STOPPED_LIMIT_REACHED:
controlCb.onStoppedLimitReached();
break;
default:
log.e("Unsupported OffloadCallbackEvent: " + event);
}
}); });
} }

View File

@@ -22,22 +22,27 @@ import static android.system.OsConstants.AF_UNIX;
import static android.system.OsConstants.SOCK_STREAM; 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_0;
import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_1_1;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
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.any;
import static org.mockito.ArgumentMatchers.eq; 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.spy;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.hardware.tetheroffload.config.V1_0.IOffloadConfig; import android.hardware.tetheroffload.config.V1_0.IOffloadConfig;
import android.hardware.tetheroffload.control.V1_0.IOffloadControl; 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.NatTimeoutUpdate;
import android.hardware.tetheroffload.control.V1_0.NetworkProtocol; 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.StructNfGenMsg;
import android.net.netlink.StructNlMsgHdr; import android.net.netlink.StructNlMsgHdr;
import android.net.util.SharedLog; import android.net.util.SharedLog;
@@ -56,6 +61,7 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
@@ -76,7 +82,7 @@ public final class OffloadHardwareInterfaceTest {
private OffloadHardwareInterface.ControlCallback mControlCallback; private OffloadHardwareInterface.ControlCallback mControlCallback;
@Mock private IOffloadConfig mIOffloadConfig; @Mock private IOffloadConfig mIOffloadConfig;
@Mock private IOffloadControl mIOffloadControl; private IOffloadControl mIOffloadControl;
@Mock private NativeHandle mNativeHandle; @Mock private NativeHandle mNativeHandle;
// Random values to test Netlink message. // Random values to test Netlink message.
@@ -84,8 +90,10 @@ public final class OffloadHardwareInterfaceTest {
private static final short TEST_FLAGS = 263; private static final short TEST_FLAGS = 263;
class MyDependencies extends OffloadHardwareInterface.Dependencies { class MyDependencies extends OffloadHardwareInterface.Dependencies {
MyDependencies(SharedLog log) { private final int mMockControlVersion;
MyDependencies(SharedLog log, final int mockControlVersion) {
super(log); super(log);
mMockControlVersion = mockControlVersion;
} }
@Override @Override
@@ -95,7 +103,19 @@ public final class OffloadHardwareInterfaceTest {
@Override @Override
public Pair<IOffloadControl, Integer> getOffloadControl() { 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 @Override
@@ -107,14 +127,13 @@ public final class OffloadHardwareInterfaceTest {
@Before @Before
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this); 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()); mControlCallback = spy(new OffloadHardwareInterface.ControlCallback());
} }
// TODO: Pass version to test version specific operations. private void startOffloadHardwareInterface(int controlVersion) throws Exception {
private void startOffloadHardwareInterface() throws Exception { final SharedLog log = new SharedLog("test");
mOffloadHw = new OffloadHardwareInterface(new Handler(mTestLooper.getLooper()), log,
new MyDependencies(log, controlVersion));
mOffloadHw.initOffloadConfig(); mOffloadHw.initOffloadConfig();
mOffloadHw.initOffloadControl(mControlCallback); mOffloadHw.initOffloadControl(mControlCallback);
final ArgumentCaptor<ITetheringOffloadCallback> mOffloadCallbackCaptor = final ArgumentCaptor<ITetheringOffloadCallback> mOffloadCallbackCaptor =
@@ -125,7 +144,7 @@ public final class OffloadHardwareInterfaceTest {
@Test @Test
public void testGetForwardedStats() throws Exception { public void testGetForwardedStats() throws Exception {
startOffloadHardwareInterface(); startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
final OffloadHardwareInterface.ForwardedStats stats = mOffloadHw.getForwardedStats(RMNET0); final OffloadHardwareInterface.ForwardedStats stats = mOffloadHw.getForwardedStats(RMNET0);
verify(mIOffloadControl).getForwardedStats(eq(RMNET0), any()); verify(mIOffloadControl).getForwardedStats(eq(RMNET0), any());
assertNotNull(stats); assertNotNull(stats);
@@ -133,7 +152,7 @@ public final class OffloadHardwareInterfaceTest {
@Test @Test
public void testSetLocalPrefixes() throws Exception { public void testSetLocalPrefixes() throws Exception {
startOffloadHardwareInterface(); startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
final ArrayList<String> localPrefixes = new ArrayList<>(); final ArrayList<String> localPrefixes = new ArrayList<>();
localPrefixes.add("127.0.0.0/8"); localPrefixes.add("127.0.0.0/8");
localPrefixes.add("fe80::/64"); localPrefixes.add("fe80::/64");
@@ -143,15 +162,32 @@ public final class OffloadHardwareInterfaceTest {
@Test @Test
public void testSetDataLimit() throws Exception { public void testSetDataLimit() throws Exception {
startOffloadHardwareInterface(); startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
final long limit = 12345; final long limit = 12345;
mOffloadHw.setDataLimit(RMNET0, limit); mOffloadHw.setDataLimit(RMNET0, limit);
verify(mIOffloadControl).setDataLimit(eq(RMNET0), eq(limit), any()); 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 @Test
public void testSetUpstreamParameters() throws Exception { public void testSetUpstreamParameters() throws Exception {
startOffloadHardwareInterface(); startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
final String v4addr = "192.168.10.1"; final String v4addr = "192.168.10.1";
final String v4gateway = "192.168.10.255"; final String v4gateway = "192.168.10.255";
final ArrayList<String> v6gws = new ArrayList<>(0); final ArrayList<String> v6gws = new ArrayList<>(0);
@@ -170,7 +206,7 @@ public final class OffloadHardwareInterfaceTest {
@Test @Test
public void testUpdateDownstreamPrefix() throws Exception { public void testUpdateDownstreamPrefix() throws Exception {
startOffloadHardwareInterface(); startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
final String ifName = "wlan1"; final String ifName = "wlan1";
final String prefix = "192.168.43.0/24"; final String prefix = "192.168.43.0/24";
mOffloadHw.addDownstreamPrefix(ifName, prefix); mOffloadHw.addDownstreamPrefix(ifName, prefix);
@@ -182,7 +218,7 @@ public final class OffloadHardwareInterfaceTest {
@Test @Test
public void testTetheringOffloadCallback() throws Exception { public void testTetheringOffloadCallback() throws Exception {
startOffloadHardwareInterface(); startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STARTED); mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STARTED);
mTestLooper.dispatchAll(); mTestLooper.dispatchAll();
@@ -221,10 +257,26 @@ public final class OffloadHardwareInterfaceTest {
eq(uint16(udpParams.src.port)), eq(uint16(udpParams.src.port)),
eq(udpParams.dst.addr), eq(udpParams.dst.addr),
eq(uint16(udpParams.dst.port))); 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 @Test
public void testSendIpv4NfGenMsg() throws Exception { public void testSendIpv4NfGenMsg() throws Exception {
startOffloadHardwareInterface(OFFLOAD_HAL_VERSION_1_0);
FileDescriptor writeSocket = new FileDescriptor(); FileDescriptor writeSocket = new FileDescriptor();
FileDescriptor readSocket = new FileDescriptor(); FileDescriptor readSocket = new FileDescriptor();
try { try {