Merge "Support setting upstream parameters."
This commit is contained in:
@@ -20,10 +20,15 @@ import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED;
|
|||||||
|
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
|
import android.net.RouteInfo;
|
||||||
import android.net.util.SharedLog;
|
import android.net.util.SharedLog;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
|
||||||
|
import java.net.Inet4Address;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class to encapsulate the business logic of programming the tethering
|
* A class to encapsulate the business logic of programming the tethering
|
||||||
* hardware offload interface.
|
* hardware offload interface.
|
||||||
@@ -92,8 +97,12 @@ public class OffloadController {
|
|||||||
public void setUpstreamLinkProperties(LinkProperties lp) {
|
public void setUpstreamLinkProperties(LinkProperties lp) {
|
||||||
if (!started()) return;
|
if (!started()) return;
|
||||||
|
|
||||||
// TODO: setUpstreamParameters().
|
mUpstreamLinkProperties = (lp != null) ? new LinkProperties(lp) : null;
|
||||||
mUpstreamLinkProperties = lp;
|
// TODO: examine return code and decide what to do if programming
|
||||||
|
// upstream parameters fails (probably just wait for a subsequent
|
||||||
|
// onOffloadEvent() callback to tell us offload is available again and
|
||||||
|
// then reapply all state).
|
||||||
|
pushUpstreamParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: public void addDownStream(...)
|
// TODO: public void addDownStream(...)
|
||||||
@@ -106,4 +115,40 @@ public class OffloadController {
|
|||||||
private boolean started() {
|
private boolean started() {
|
||||||
return mConfigInitialized && mControlInitialized;
|
return mConfigInitialized && mControlInitialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean pushUpstreamParameters() {
|
||||||
|
if (mUpstreamLinkProperties == null) {
|
||||||
|
return mHwInterface.setUpstreamParameters(null, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// A stacked interface cannot be an upstream for hardware offload.
|
||||||
|
// Consequently, we examine only the primary interface name, look at
|
||||||
|
// getAddresses() rather than getAllAddresses(), and check getRoutes()
|
||||||
|
// rather than getAllRoutes().
|
||||||
|
final String iface = mUpstreamLinkProperties.getInterfaceName();
|
||||||
|
final ArrayList<String> v6gateways = new ArrayList<>();
|
||||||
|
String v4addr = null;
|
||||||
|
String v4gateway = null;
|
||||||
|
|
||||||
|
for (InetAddress ip : mUpstreamLinkProperties.getAddresses()) {
|
||||||
|
if (ip instanceof Inet4Address) {
|
||||||
|
v4addr = ip.getHostAddress();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the gateway addresses of all default routes of either address family.
|
||||||
|
for (RouteInfo ri : mUpstreamLinkProperties.getRoutes()) {
|
||||||
|
if (!ri.hasGateway()) continue;
|
||||||
|
|
||||||
|
final String gateway = ri.getGateway().getHostAddress();
|
||||||
|
if (ri.isIPv4Default()) {
|
||||||
|
v4gateway = gateway;
|
||||||
|
} else if (ri.isIPv6Default()) {
|
||||||
|
v6gateways.add(gateway);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mHwInterface.setUpstreamParameters(iface, v4addr, v4gateway, v6gateways);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ import android.os.Handler;
|
|||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.net.util.SharedLog;
|
import android.net.util.SharedLog;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Capture tethering dependencies, for injection.
|
* Capture tethering dependencies, for injection.
|
||||||
@@ -103,6 +105,25 @@ public class OffloadHardwareInterface {
|
|||||||
mControlCallback = null;
|
mControlCallback = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean setUpstreamParameters(
|
||||||
|
String iface, String v4addr, String v4gateway, ArrayList<String> v6gws) {
|
||||||
|
final CbResults results = new CbResults();
|
||||||
|
try {
|
||||||
|
mOffloadControl.setUpstreamParameters(
|
||||||
|
iface, v4addr, v4gateway, v6gws,
|
||||||
|
(boolean success, String errMsg) -> {
|
||||||
|
results.success = success;
|
||||||
|
results.errMsg = errMsg;
|
||||||
|
});
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
mLog.e("failed to setUpstreamParameters: " + e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!results.success) mLog.e("setUpstreamParameters failed: " + results.errMsg);
|
||||||
|
return results.success;
|
||||||
|
}
|
||||||
|
|
||||||
private static class TetheringOffloadCallback extends ITetheringOffloadCallback.Stub {
|
private static class TetheringOffloadCallback extends ITetheringOffloadCallback.Stub {
|
||||||
public final Handler handler;
|
public final Handler handler;
|
||||||
public final ControlCallback controlCb;
|
public final ControlCallback controlCb;
|
||||||
|
|||||||
@@ -17,15 +17,22 @@
|
|||||||
package com.android.server.connectivity.tethering;
|
package com.android.server.connectivity.tethering;
|
||||||
|
|
||||||
import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED;
|
import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import static org.mockito.Matchers.any;
|
import static org.mockito.Matchers.any;
|
||||||
import static org.mockito.Matchers.anyObject;
|
import static org.mockito.Matchers.anyObject;
|
||||||
|
import static org.mockito.Matchers.eq;
|
||||||
import static org.mockito.Mockito.inOrder;
|
import static org.mockito.Mockito.inOrder;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.reset;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.net.LinkAddress;
|
||||||
|
import android.net.LinkProperties;
|
||||||
|
import android.net.RouteInfo;
|
||||||
import android.net.util.SharedLog;
|
import android.net.util.SharedLog;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.provider.Settings.SettingNotFoundException;
|
import android.provider.Settings.SettingNotFoundException;
|
||||||
@@ -35,9 +42,13 @@ import android.support.test.runner.AndroidJUnit4;
|
|||||||
import android.test.mock.MockContentResolver;
|
import android.test.mock.MockContentResolver;
|
||||||
import com.android.internal.util.test.FakeSettingsProvider;
|
import com.android.internal.util.test.FakeSettingsProvider;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.InOrder;
|
import org.mockito.InOrder;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
@@ -49,6 +60,7 @@ public class OffloadControllerTest {
|
|||||||
|
|
||||||
@Mock private OffloadHardwareInterface mHardware;
|
@Mock private OffloadHardwareInterface mHardware;
|
||||||
@Mock private Context mContext;
|
@Mock private Context mContext;
|
||||||
|
final ArgumentCaptor<ArrayList> mStringArrayCaptor = ArgumentCaptor.forClass(ArrayList.class);
|
||||||
private MockContentResolver mContentResolver;
|
private MockContentResolver mContentResolver;
|
||||||
|
|
||||||
@Before public void setUp() throws Exception {
|
@Before public void setUp() throws Exception {
|
||||||
@@ -114,4 +126,87 @@ public class OffloadControllerTest {
|
|||||||
inOrder.verify(mHardware, never()).initOffloadControl(anyObject());
|
inOrder.verify(mHardware, never()).initOffloadControl(anyObject());
|
||||||
inOrder.verifyNoMoreInteractions();
|
inOrder.verifyNoMoreInteractions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetUpstreamLinkPropertiesWorking() throws Exception {
|
||||||
|
setupFunctioningHardwareInterface();
|
||||||
|
final OffloadController offload =
|
||||||
|
new OffloadController(null, mHardware, mContentResolver, new SharedLog("test"));
|
||||||
|
offload.start();
|
||||||
|
|
||||||
|
final InOrder inOrder = inOrder(mHardware);
|
||||||
|
inOrder.verify(mHardware, times(1)).initOffloadConfig();
|
||||||
|
inOrder.verify(mHardware, times(1)).initOffloadControl(
|
||||||
|
any(OffloadHardwareInterface.ControlCallback.class));
|
||||||
|
inOrder.verifyNoMoreInteractions();
|
||||||
|
|
||||||
|
offload.setUpstreamLinkProperties(null);
|
||||||
|
inOrder.verify(mHardware, times(1)).setUpstreamParameters(
|
||||||
|
eq(null), eq(null), eq(null), eq(null));
|
||||||
|
inOrder.verifyNoMoreInteractions();
|
||||||
|
reset(mHardware);
|
||||||
|
|
||||||
|
final LinkProperties lp = new LinkProperties();
|
||||||
|
|
||||||
|
final String testIfName = "rmnet_data17";
|
||||||
|
lp.setInterfaceName(testIfName);
|
||||||
|
offload.setUpstreamLinkProperties(lp);
|
||||||
|
inOrder.verify(mHardware, times(1)).setUpstreamParameters(
|
||||||
|
eq(testIfName), eq(null), eq(null), mStringArrayCaptor.capture());
|
||||||
|
assertTrue(mStringArrayCaptor.getValue().isEmpty());
|
||||||
|
inOrder.verifyNoMoreInteractions();
|
||||||
|
|
||||||
|
final String ipv4Addr = "192.0.2.5";
|
||||||
|
final String linkAddr = ipv4Addr + "/24";
|
||||||
|
lp.addLinkAddress(new LinkAddress(linkAddr));
|
||||||
|
offload.setUpstreamLinkProperties(lp);
|
||||||
|
inOrder.verify(mHardware, times(1)).setUpstreamParameters(
|
||||||
|
eq(testIfName), eq(ipv4Addr), eq(null), mStringArrayCaptor.capture());
|
||||||
|
assertTrue(mStringArrayCaptor.getValue().isEmpty());
|
||||||
|
inOrder.verifyNoMoreInteractions();
|
||||||
|
|
||||||
|
final String ipv4Gateway = "192.0.2.1";
|
||||||
|
lp.addRoute(new RouteInfo(InetAddress.getByName(ipv4Gateway)));
|
||||||
|
offload.setUpstreamLinkProperties(lp);
|
||||||
|
inOrder.verify(mHardware, times(1)).setUpstreamParameters(
|
||||||
|
eq(testIfName), eq(ipv4Addr), eq(ipv4Gateway), mStringArrayCaptor.capture());
|
||||||
|
assertTrue(mStringArrayCaptor.getValue().isEmpty());
|
||||||
|
inOrder.verifyNoMoreInteractions();
|
||||||
|
|
||||||
|
final String ipv6Gw1 = "fe80::cafe";
|
||||||
|
lp.addRoute(new RouteInfo(InetAddress.getByName(ipv6Gw1)));
|
||||||
|
offload.setUpstreamLinkProperties(lp);
|
||||||
|
inOrder.verify(mHardware, times(1)).setUpstreamParameters(
|
||||||
|
eq(testIfName), eq(ipv4Addr), eq(ipv4Gateway), mStringArrayCaptor.capture());
|
||||||
|
ArrayList<String> v6gws = mStringArrayCaptor.getValue();
|
||||||
|
assertEquals(1, v6gws.size());
|
||||||
|
assertTrue(v6gws.contains(ipv6Gw1));
|
||||||
|
inOrder.verifyNoMoreInteractions();
|
||||||
|
|
||||||
|
final String ipv6Gw2 = "fe80::d00d";
|
||||||
|
lp.addRoute(new RouteInfo(InetAddress.getByName(ipv6Gw2)));
|
||||||
|
offload.setUpstreamLinkProperties(lp);
|
||||||
|
inOrder.verify(mHardware, times(1)).setUpstreamParameters(
|
||||||
|
eq(testIfName), eq(ipv4Addr), eq(ipv4Gateway), mStringArrayCaptor.capture());
|
||||||
|
v6gws = mStringArrayCaptor.getValue();
|
||||||
|
assertEquals(2, v6gws.size());
|
||||||
|
assertTrue(v6gws.contains(ipv6Gw1));
|
||||||
|
assertTrue(v6gws.contains(ipv6Gw2));
|
||||||
|
inOrder.verifyNoMoreInteractions();
|
||||||
|
|
||||||
|
final LinkProperties stacked = new LinkProperties();
|
||||||
|
stacked.setInterfaceName("stacked");
|
||||||
|
stacked.addLinkAddress(new LinkAddress("192.0.2.129/25"));
|
||||||
|
stacked.addRoute(new RouteInfo(InetAddress.getByName("192.0.2.254")));
|
||||||
|
stacked.addRoute(new RouteInfo(InetAddress.getByName("fe80::bad:f00")));
|
||||||
|
assertTrue(lp.addStackedLink(stacked));
|
||||||
|
offload.setUpstreamLinkProperties(lp);
|
||||||
|
inOrder.verify(mHardware, times(1)).setUpstreamParameters(
|
||||||
|
eq(testIfName), eq(ipv4Addr), eq(ipv4Gateway), mStringArrayCaptor.capture());
|
||||||
|
v6gws = mStringArrayCaptor.getValue();
|
||||||
|
assertEquals(2, v6gws.size());
|
||||||
|
assertTrue(v6gws.contains(ipv6Gw1));
|
||||||
|
assertTrue(v6gws.contains(ipv6Gw2));
|
||||||
|
inOrder.verifyNoMoreInteractions();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user