Loading core/java/android/net/DhcpResults.java +21 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -66,6 +67,9 @@ public final class DhcpResults implements Parcelable { public String serverHostName; @Nullable public String captivePortalApiUrl; public DhcpResults() { super(); } Loading Loading @@ -100,6 +104,7 @@ public final class DhcpResults implements Parcelable { leaseDuration = source.leaseDuration; mtu = source.mtu; serverHostName = source.serverHostName; captivePortalApiUrl = source.captivePortalApiUrl; } } Loading Loading @@ -133,6 +138,7 @@ public final class DhcpResults implements Parcelable { leaseDuration = 0; mtu = 0; serverHostName = null; captivePortalApiUrl = null; } @Override Loading @@ -144,6 +150,9 @@ public final class DhcpResults implements Parcelable { 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(); } Loading @@ -161,7 +170,8 @@ public final class DhcpResults implements Parcelable { && Objects.equals(vendorInfo, target.vendorInfo) && Objects.equals(serverHostName, target.serverHostName) && leaseDuration == target.leaseDuration && mtu == target.mtu; && mtu == target.mtu && Objects.equals(captivePortalApiUrl, target.captivePortalApiUrl); } /** Loading @@ -186,6 +196,7 @@ public final class DhcpResults implements Parcelable { InetAddressUtils.parcelInetAddress(dest, serverAddress, flags); dest.writeString(vendorInfo); dest.writeString(serverHostName); dest.writeString(captivePortalApiUrl); } @Override Loading @@ -201,6 +212,7 @@ public final class DhcpResults implements Parcelable { dhcpResults.serverAddress = (Inet4Address) InetAddressUtils.unparcelInetAddress(in); dhcpResults.vendorInfo = in.readString(); dhcpResults.serverHostName = in.readString(); dhcpResults.captivePortalApiUrl = in.readString(); return dhcpResults; } Loading Loading @@ -305,4 +317,12 @@ public final class DhcpResults implements Parcelable { public void setMtu(int mtu) { this.mtu = mtu; } public String getCaptivePortalApiUrl() { return captivePortalApiUrl; } public void setCaptivePortalApiUrl(String url) { captivePortalApiUrl = url; } } services/core/java/com/android/server/ConnectivityService.java +33 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ import android.content.IntentFilter; 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; Loading Loading @@ -547,6 +548,14 @@ public class ConnectivityService extends IConnectivityManager.Stub */ 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. Loading Loading @@ -2814,6 +2823,12 @@ public class ConnectivityService extends IConnectivityManager.Stub 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; } Loading Loading @@ -2980,6 +2995,13 @@ public class ConnectivityService extends IConnectivityManager.Stub probesCompleted, probesSucceeded, new Integer(mNetId))); } @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); Loading Loading @@ -3108,6 +3130,13 @@ public class ConnectivityService extends IConnectivityManager.Stub 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 Loading Loading @@ -5838,6 +5867,10 @@ public class ConnectivityService extends IConnectivityManager.Stub 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) { Loading services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +5 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.net.NetworkCapabilities.transportNamesOf; 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; Loading Loading @@ -167,6 +168,10 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { // 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 Loading tests/net/java/com/android/server/ConnectivityServiceTest.java +51 −6 Original line number Diff line number Diff line Loading @@ -797,6 +797,14 @@ public class ConnectivityServiceTest { 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; Loading Loading @@ -1843,18 +1851,21 @@ public class ConnectivityServiceTest { final Uri capportUrl = Uri.parse("https://capport.example.com/api"); final CaptivePortalData capportData = new CaptivePortalData.Builder() .setCaptive(true).build(); final Uri expectedCapportUrl = sanitized ? null : capportUrl; newLp.setCaptivePortalApiUrl(capportUrl); newLp.setCaptivePortalData(capportData); mWiFiNetworkAgent.sendLinkProperties(newLp); callback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl())); defaultCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl())); final Uri expectedCapportUrl = sanitized ? null : capportUrl; final CaptivePortalData expectedCapportData = sanitized ? null : capportData; mWiFiNetworkAgent.notifyCaptivePortalDataChanged(capportData); callback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl()) && Objects.equals(expectedCapportData, lp.getCaptivePortalData())); Objects.equals(expectedCapportData, lp.getCaptivePortalData())); defaultCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl()) && Objects.equals(expectedCapportData, lp.getCaptivePortalData())); Objects.equals(expectedCapportData, lp.getCaptivePortalData())); final LinkProperties lp = mCm.getLinkProperties(mWiFiNetworkAgent.getNetwork()); assertEquals(expectedCapportUrl, lp.getCaptivePortalApiUrl()); Loading Loading @@ -2808,6 +2819,40 @@ public class ConnectivityServiceTest { 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); } Loading Loading
core/java/android/net/DhcpResults.java +21 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -66,6 +67,9 @@ public final class DhcpResults implements Parcelable { public String serverHostName; @Nullable public String captivePortalApiUrl; public DhcpResults() { super(); } Loading Loading @@ -100,6 +104,7 @@ public final class DhcpResults implements Parcelable { leaseDuration = source.leaseDuration; mtu = source.mtu; serverHostName = source.serverHostName; captivePortalApiUrl = source.captivePortalApiUrl; } } Loading Loading @@ -133,6 +138,7 @@ public final class DhcpResults implements Parcelable { leaseDuration = 0; mtu = 0; serverHostName = null; captivePortalApiUrl = null; } @Override Loading @@ -144,6 +150,9 @@ public final class DhcpResults implements Parcelable { 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(); } Loading @@ -161,7 +170,8 @@ public final class DhcpResults implements Parcelable { && Objects.equals(vendorInfo, target.vendorInfo) && Objects.equals(serverHostName, target.serverHostName) && leaseDuration == target.leaseDuration && mtu == target.mtu; && mtu == target.mtu && Objects.equals(captivePortalApiUrl, target.captivePortalApiUrl); } /** Loading @@ -186,6 +196,7 @@ public final class DhcpResults implements Parcelable { InetAddressUtils.parcelInetAddress(dest, serverAddress, flags); dest.writeString(vendorInfo); dest.writeString(serverHostName); dest.writeString(captivePortalApiUrl); } @Override Loading @@ -201,6 +212,7 @@ public final class DhcpResults implements Parcelable { dhcpResults.serverAddress = (Inet4Address) InetAddressUtils.unparcelInetAddress(in); dhcpResults.vendorInfo = in.readString(); dhcpResults.serverHostName = in.readString(); dhcpResults.captivePortalApiUrl = in.readString(); return dhcpResults; } Loading Loading @@ -305,4 +317,12 @@ public final class DhcpResults implements Parcelable { public void setMtu(int mtu) { this.mtu = mtu; } public String getCaptivePortalApiUrl() { return captivePortalApiUrl; } public void setCaptivePortalApiUrl(String url) { captivePortalApiUrl = url; } }
services/core/java/com/android/server/ConnectivityService.java +33 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ import android.content.IntentFilter; 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; Loading Loading @@ -547,6 +548,14 @@ public class ConnectivityService extends IConnectivityManager.Stub */ 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. Loading Loading @@ -2814,6 +2823,12 @@ public class ConnectivityService extends IConnectivityManager.Stub 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; } Loading Loading @@ -2980,6 +2995,13 @@ public class ConnectivityService extends IConnectivityManager.Stub probesCompleted, probesSucceeded, new Integer(mNetId))); } @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); Loading Loading @@ -3108,6 +3130,13 @@ public class ConnectivityService extends IConnectivityManager.Stub 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 Loading Loading @@ -5838,6 +5867,10 @@ public class ConnectivityService extends IConnectivityManager.Stub 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) { Loading
services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +5 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.net.NetworkCapabilities.transportNamesOf; 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; Loading Loading @@ -167,6 +168,10 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { // 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 Loading
tests/net/java/com/android/server/ConnectivityServiceTest.java +51 −6 Original line number Diff line number Diff line Loading @@ -797,6 +797,14 @@ public class ConnectivityServiceTest { 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; Loading Loading @@ -1843,18 +1851,21 @@ public class ConnectivityServiceTest { final Uri capportUrl = Uri.parse("https://capport.example.com/api"); final CaptivePortalData capportData = new CaptivePortalData.Builder() .setCaptive(true).build(); final Uri expectedCapportUrl = sanitized ? null : capportUrl; newLp.setCaptivePortalApiUrl(capportUrl); newLp.setCaptivePortalData(capportData); mWiFiNetworkAgent.sendLinkProperties(newLp); callback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl())); defaultCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl())); final Uri expectedCapportUrl = sanitized ? null : capportUrl; final CaptivePortalData expectedCapportData = sanitized ? null : capportData; mWiFiNetworkAgent.notifyCaptivePortalDataChanged(capportData); callback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl()) && Objects.equals(expectedCapportData, lp.getCaptivePortalData())); Objects.equals(expectedCapportData, lp.getCaptivePortalData())); defaultCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp -> Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl()) && Objects.equals(expectedCapportData, lp.getCaptivePortalData())); Objects.equals(expectedCapportData, lp.getCaptivePortalData())); final LinkProperties lp = mCm.getLinkProperties(mWiFiNetworkAgent.getNetwork()); assertEquals(expectedCapportUrl, lp.getCaptivePortalApiUrl()); Loading Loading @@ -2808,6 +2819,40 @@ public class ConnectivityServiceTest { 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); } Loading