Merge changes from topics "capport_dhcpresults", "nm_cb_capport" am: f202725395 am: 2c7a224e1b am: b7c9d205bf
Change-Id: Ie27e5dfd51b38194fa104cbd73f9bbe7c4395e0f
diff --git a/core/java/android/net/DhcpResults.java b/core/java/android/net/DhcpResults.java
index 059cd94..5ab0354 100644
--- a/core/java/android/net/DhcpResults.java
+++ b/core/java/android/net/DhcpResults.java
@@ -16,6 +16,7 @@
package android.net;
+import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.net.shared.InetAddressUtils;
import android.os.Parcel;
@@ -66,6 +67,9 @@
public String serverHostName;
+ @Nullable
+ public String captivePortalApiUrl;
+
public DhcpResults() {
super();
}
@@ -100,6 +104,7 @@
leaseDuration = source.leaseDuration;
mtu = source.mtu;
serverHostName = source.serverHostName;
+ captivePortalApiUrl = source.captivePortalApiUrl;
}
}
@@ -133,6 +138,7 @@
leaseDuration = 0;
mtu = 0;
serverHostName = null;
+ captivePortalApiUrl = null;
}
@Override
@@ -144,6 +150,9 @@
str.append(" lease ").append(leaseDuration).append(" seconds");
if (mtu != 0) str.append(" MTU ").append(mtu);
str.append(" Servername ").append(serverHostName);
+ if (captivePortalApiUrl != null) {
+ str.append(" CaptivePortalApiUrl ").append(captivePortalApiUrl);
+ }
return str.toString();
}
@@ -161,7 +170,8 @@
&& Objects.equals(vendorInfo, target.vendorInfo)
&& Objects.equals(serverHostName, target.serverHostName)
&& leaseDuration == target.leaseDuration
- && mtu == target.mtu;
+ && mtu == target.mtu
+ && Objects.equals(captivePortalApiUrl, target.captivePortalApiUrl);
}
/**
@@ -186,6 +196,7 @@
InetAddressUtils.parcelInetAddress(dest, serverAddress, flags);
dest.writeString(vendorInfo);
dest.writeString(serverHostName);
+ dest.writeString(captivePortalApiUrl);
}
@Override
@@ -201,6 +212,7 @@
dhcpResults.serverAddress = (Inet4Address) InetAddressUtils.unparcelInetAddress(in);
dhcpResults.vendorInfo = in.readString();
dhcpResults.serverHostName = in.readString();
+ dhcpResults.captivePortalApiUrl = in.readString();
return dhcpResults;
}
@@ -305,4 +317,12 @@
public void setMtu(int mtu) {
this.mtu = mtu;
}
+
+ public String getCaptivePortalApiUrl() {
+ return captivePortalApiUrl;
+ }
+
+ public void setCaptivePortalApiUrl(String url) {
+ captivePortalApiUrl = url;
+ }
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 926d075..60a30d3 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -64,6 +64,7 @@
import android.content.res.Configuration;
import android.database.ContentObserver;
import android.net.CaptivePortal;
+import android.net.CaptivePortalData;
import android.net.ConnectionInfo;
import android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
import android.net.ConnectivityDiagnosticsManager.DataStallReport;
@@ -546,6 +547,14 @@
public static final int EVENT_PROBE_STATUS_CHANGED = 46;
/**
+ * Event for NetworkMonitor to inform ConnectivityService that captive portal data has changed.
+ * arg1 = unused
+ * arg2 = netId
+ * obj = captive portal data
+ */
+ private static final int EVENT_CAPPORT_DATA_CHANGED = 47;
+
+ /**
* Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
* should be shown.
*/
@@ -2824,6 +2833,12 @@
updatePrivateDns(nai, (PrivateDnsConfig) msg.obj);
break;
}
+ case EVENT_CAPPORT_DATA_CHANGED: {
+ final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
+ if (nai == null) break;
+ handleCaptivePortalDataUpdate(nai, (CaptivePortalData) msg.obj);
+ break;
+ }
}
return true;
}
@@ -2991,6 +3006,13 @@
}
@Override
+ public void notifyCaptivePortalDataChanged(CaptivePortalData data) {
+ mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
+ EVENT_CAPPORT_DATA_CHANGED,
+ 0, mNetId, data));
+ }
+
+ @Override
public void showProvisioningNotification(String action, String packageName) {
final Intent intent = new Intent(action);
intent.setPackage(packageName);
@@ -3118,6 +3140,13 @@
handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
}
+ private void handleCaptivePortalDataUpdate(@NonNull final NetworkAgentInfo nai,
+ @Nullable final CaptivePortalData data) {
+ nai.captivePortalData = data;
+ // CaptivePortalData will be merged into LinkProperties from NetworkAgentInfo
+ handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
+ }
+
/**
* Updates the linger state from the network requests inside the NAI.
* @param nai the agent info to update
@@ -5838,6 +5867,10 @@
updateWakeOnLan(newLp);
+ // Captive portal data is obtained from NetworkMonitor and stored in NetworkAgentInfo,
+ // it is not contained in LinkProperties sent from NetworkAgents so needs to be merged here.
+ newLp.setCaptivePortalData(networkAgent.captivePortalData);
+
// TODO - move this check to cover the whole function
if (!Objects.equals(newLp, oldLp)) {
synchronized (networkAgent) {
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 592be2f..4612cfd 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -21,6 +21,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.net.CaptivePortalData;
import android.net.IDnsResolver;
import android.net.INetd;
import android.net.INetworkMonitor;
@@ -167,6 +168,10 @@
// Set to true when partial connectivity was detected.
public boolean partialConnectivity;
+ // Captive portal info of the network, if any.
+ // Obtained by ConnectivityService and merged into NetworkAgent-provided information.
+ public CaptivePortalData captivePortalData;
+
// Networks are lingered when they become unneeded as a result of their NetworkRequests being
// satisfied by a higher-scoring network. so as to allow communication to wrap up before the
// network is taken down. This usually only happens to the default network. Lingering ends with
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 593d27d..2e59966 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -799,6 +799,14 @@
mProbesSucceeded = probesSucceeded;
}
+ void notifyCaptivePortalDataChanged(CaptivePortalData data) {
+ try {
+ mNmCallbacks.notifyCaptivePortalDataChanged(data);
+ } catch (RemoteException e) {
+ throw new AssertionError("This cannot happen", e);
+ }
+ }
+
public String waitForRedirectUrl() {
assertTrue(mNetworkStatusReceived.block(TIMEOUT_MS));
return mRedirectUrl;
@@ -1845,18 +1853,21 @@
final Uri capportUrl = Uri.parse("https://capport.example.com/api");
final CaptivePortalData capportData = new CaptivePortalData.Builder()
.setCaptive(true).build();
- newLp.setCaptivePortalApiUrl(capportUrl);
- newLp.setCaptivePortalData(capportData);
- mWiFiNetworkAgent.sendLinkProperties(newLp);
final Uri expectedCapportUrl = sanitized ? null : capportUrl;
- final CaptivePortalData expectedCapportData = sanitized ? null : capportData;
+ newLp.setCaptivePortalApiUrl(capportUrl);
+ mWiFiNetworkAgent.sendLinkProperties(newLp);
callback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp ->
- Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl())
- && Objects.equals(expectedCapportData, lp.getCaptivePortalData()));
+ Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl()));
defaultCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp ->
- Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl())
- && Objects.equals(expectedCapportData, lp.getCaptivePortalData()));
+ Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl()));
+
+ final CaptivePortalData expectedCapportData = sanitized ? null : capportData;
+ mWiFiNetworkAgent.notifyCaptivePortalDataChanged(capportData);
+ callback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp ->
+ Objects.equals(expectedCapportData, lp.getCaptivePortalData()));
+ defaultCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp ->
+ Objects.equals(expectedCapportData, lp.getCaptivePortalData()));
final LinkProperties lp = mCm.getLinkProperties(mWiFiNetworkAgent.getNetwork());
assertEquals(expectedCapportUrl, lp.getCaptivePortalApiUrl());
@@ -2810,6 +2821,40 @@
assertNoCallbacks(captivePortalCallback, validatedCallback);
}
+ @Test
+ public void testCaptivePortalApi() throws Exception {
+ mServiceContext.setPermission(
+ android.Manifest.permission.NETWORK_SETTINGS, PERMISSION_GRANTED);
+
+ final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
+ final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
+ .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
+ mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback);
+
+ mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
+ final String redirectUrl = "http://example.com/firstPath";
+
+ mWiFiNetworkAgent.connectWithCaptivePortal(redirectUrl, false /* isStrictMode */);
+ captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+
+ final CaptivePortalData testData = new CaptivePortalData.Builder()
+ .setUserPortalUrl(Uri.parse(redirectUrl))
+ .setBytesRemaining(12345L)
+ .build();
+
+ mWiFiNetworkAgent.notifyCaptivePortalDataChanged(testData);
+
+ captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent,
+ lp -> testData.equals(lp.getCaptivePortalData()));
+
+ final LinkProperties newLps = new LinkProperties();
+ newLps.setMtu(1234);
+ mWiFiNetworkAgent.sendLinkProperties(newLps);
+ // CaptivePortalData is not lost and unchanged when LPs are received from the NetworkAgent
+ captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent,
+ lp -> testData.equals(lp.getCaptivePortalData()) && lp.getMtu() == 1234);
+ }
+
private NetworkRequest.Builder newWifiRequestBuilder() {
return new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI);
}