Merge "Local Tethering with ncm interface"
diff --git a/Tethering/Android.bp b/Tethering/Android.bp
index e441fb5..cf2b1f0 100644
--- a/Tethering/Android.bp
+++ b/Tethering/Android.bp
@@ -35,7 +35,7 @@
"framework-tethering",
"unsupportedappusage",
],
-
+ plugins: ["java_api_finder"],
manifest: "AndroidManifestBase.xml",
}
diff --git a/Tethering/src/android/net/ip/IpServer.java b/Tethering/src/android/net/ip/IpServer.java
index baee99a..57cc4dd 100644
--- a/Tethering/src/android/net/ip/IpServer.java
+++ b/Tethering/src/android/net/ip/IpServer.java
@@ -442,7 +442,8 @@
}
final Boolean setIfaceUp;
- if (mInterfaceType == TetheringManager.TETHERING_WIFI) {
+ if (mInterfaceType == TetheringManager.TETHERING_WIFI
+ || mInterfaceType == TetheringManager.TETHERING_WIFI_P2P) {
// The WiFi stack has ownership of the interface up/down state.
// It is unclear whether the Bluetooth or USB stacks will manage their own
// state.
diff --git a/Tethering/src/com/android/server/connectivity/tethering/Tethering.java b/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
index f4d0831..02ba17e 100644
--- a/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
+++ b/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
@@ -212,6 +212,7 @@
private Network mTetherUpstream;
private TetherStatesParcel mTetherStatesParcel;
private boolean mDataSaverEnabled = false;
+ private String mWifiP2pTetherInterface = null;
public Tethering(TetheringDependencies deps) {
mLog.mark("Tethering.constructed");
@@ -870,6 +871,11 @@
}
}
+ private boolean isGroupOwner(WifiP2pGroup group) {
+ return group != null && group.isGroupOwner()
+ && !TextUtils.isEmpty(group.getInterface());
+ }
+
private void handleWifiP2pAction(Intent intent) {
if (mConfig.isWifiP2pLegacyTetheringMode()) return;
@@ -882,24 +888,31 @@
Log.d(TAG, "WifiP2pAction: P2pInfo: " + p2pInfo + " Group: " + group);
}
- if (p2pInfo == null) return;
- // When a p2p group is disconnected, p2pInfo would be cleared.
- // group is still valid for detecting whether this device is group owner.
- if (group == null || !group.isGroupOwner()
- || TextUtils.isEmpty(group.getInterface())) return;
-
synchronized (Tethering.this.mPublicSync) {
- // Enter below only if this device is Group Owner with a valid interface.
- if (p2pInfo.groupFormed) {
- TetherState tetherState = mTetherStates.get(group.getInterface());
- if (tetherState == null
- || (tetherState.lastState != IpServer.STATE_TETHERED
- && tetherState.lastState != IpServer.STATE_LOCAL_ONLY)) {
- enableWifiIpServingLocked(group.getInterface(), IFACE_IP_MODE_LOCAL_ONLY);
- }
- } else {
- disableWifiP2pIpServingLocked(group.getInterface());
+ // if no group is formed, bring it down if needed.
+ if (p2pInfo == null || !p2pInfo.groupFormed) {
+ disableWifiP2pIpServingLockedIfNeeded(mWifiP2pTetherInterface);
+ mWifiP2pTetherInterface = null;
+ return;
}
+
+ // If there is a group but the device is not the owner, bail out.
+ if (!isGroupOwner(group)) return;
+
+ // If already serving from the correct interface, nothing to do.
+ if (group.getInterface().equals(mWifiP2pTetherInterface)) return;
+
+ // If already serving from another interface, turn it down first.
+ if (!TextUtils.isEmpty(mWifiP2pTetherInterface)) {
+ mLog.w("P2P tethered interface " + mWifiP2pTetherInterface
+ + "is different from current interface "
+ + group.getInterface() + ", re-tether it");
+ disableWifiP2pIpServingLockedIfNeeded(mWifiP2pTetherInterface);
+ }
+
+ // Finally bring up serving on the new interface
+ mWifiP2pTetherInterface = group.getInterface();
+ enableWifiIpServingLocked(mWifiP2pTetherInterface, IFACE_IP_MODE_LOCAL_ONLY);
}
}
@@ -998,7 +1011,9 @@
disableWifiIpServingLockedCommon(TETHERING_WIFI, ifname, apState);
}
- private void disableWifiP2pIpServingLocked(String ifname) {
+ private void disableWifiP2pIpServingLockedIfNeeded(String ifname) {
+ if (TextUtils.isEmpty(ifname)) return;
+
disableWifiIpServingLockedCommon(TETHERING_WIFI_P2P, ifname, /* dummy */ 0);
}
diff --git a/Tethering/tests/unit/src/android/net/ip/IpServerTest.java b/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
index 1f50b6b..f29ad78 100644
--- a/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
+++ b/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
@@ -273,7 +273,7 @@
dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_LOCAL_ONLY);
InOrder inOrder = inOrder(mCallback, mNetd);
inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg ->
- IFACE_NAME.equals(cfg.ifName) && assertContainsFlag(cfg.flags, IF_STATE_UP)));
+ IFACE_NAME.equals(cfg.ifName) && assertNotContainsFlag(cfg.flags, IF_STATE_UP)));
inOrder.verify(mNetd).tetherInterfaceAdd(IFACE_NAME);
inOrder.verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, IFACE_NAME);
inOrder.verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(IFACE_NAME),
@@ -547,4 +547,14 @@
fail("Missing flag: " + match);
return false;
}
+
+ private boolean assertNotContainsFlag(String[] flags, String match) {
+ for (String flag : flags) {
+ if (flag.equals(match)) {
+ fail("Unexpected flag: " + match);
+ return false;
+ }
+ }
+ return true;
+ }
}
diff --git a/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java b/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
index 8440562..4710287 100644
--- a/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
+++ b/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
@@ -513,13 +513,15 @@
private void sendWifiP2pConnectionChanged(
boolean isGroupFormed, boolean isGroupOwner, String ifname) {
+ WifiP2pGroup group = null;
WifiP2pInfo p2pInfo = new WifiP2pInfo();
p2pInfo.groupFormed = isGroupFormed;
- p2pInfo.isGroupOwner = isGroupOwner;
-
- WifiP2pGroup group = mock(WifiP2pGroup.class);
- when(group.isGroupOwner()).thenReturn(isGroupOwner);
- when(group.getInterface()).thenReturn(ifname);
+ if (isGroupFormed) {
+ p2pInfo.isGroupOwner = isGroupOwner;
+ group = mock(WifiP2pGroup.class);
+ when(group.isGroupOwner()).thenReturn(isGroupOwner);
+ when(group.getInterface()).thenReturn(ifname);
+ }
final Intent intent = mock(Intent.class);
when(intent.getAction()).thenReturn(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);