Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 88baf235 authored by Hai Shalom's avatar Hai Shalom Committed by Gerrit Code Review
Browse files

Merge "Support for Venue URL and friendly name from Network agent"

parents 5b51530d ef5f5b1e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -5965,6 +5965,7 @@ package android.net {
    method public long getExpiryTimeMillis();
    method public long getRefreshTimeMillis();
    method @Nullable public android.net.Uri getUserPortalUrl();
    method @Nullable public String getVenueFriendlyName();
    method @Nullable public android.net.Uri getVenueInfoUrl();
    method public boolean isCaptive();
    method public boolean isSessionExtendable();
@@ -5982,6 +5983,7 @@ package android.net {
    method @NonNull public android.net.CaptivePortalData.Builder setRefreshTime(long);
    method @NonNull public android.net.CaptivePortalData.Builder setSessionExtendable(boolean);
    method @NonNull public android.net.CaptivePortalData.Builder setUserPortalUrl(@Nullable android.net.Uri);
    method @NonNull public android.net.CaptivePortalData.Builder setVenueFriendlyName(@Nullable String);
    method @NonNull public android.net.CaptivePortalData.Builder setVenueInfoUrl(@Nullable android.net.Uri);
  }
+32 −6
Original line number Diff line number Diff line
@@ -39,9 +39,11 @@ public final class CaptivePortalData implements Parcelable {
    private final long mByteLimit;
    private final long mExpiryTimeMillis;
    private final boolean mCaptive;
    private final String mVenueFriendlyName;

    private CaptivePortalData(long refreshTimeMillis, Uri userPortalUrl, Uri venueInfoUrl,
            boolean isSessionExtendable, long byteLimit, long expiryTimeMillis, boolean captive) {
            boolean isSessionExtendable, long byteLimit, long expiryTimeMillis, boolean captive,
            String venueFriendlyName) {
        mRefreshTimeMillis = refreshTimeMillis;
        mUserPortalUrl = userPortalUrl;
        mVenueInfoUrl = venueInfoUrl;
@@ -49,11 +51,12 @@ public final class CaptivePortalData implements Parcelable {
        mByteLimit = byteLimit;
        mExpiryTimeMillis = expiryTimeMillis;
        mCaptive = captive;
        mVenueFriendlyName = venueFriendlyName;
    }

    private CaptivePortalData(Parcel p) {
        this(p.readLong(), p.readParcelable(null), p.readParcelable(null), p.readBoolean(),
                p.readLong(), p.readLong(), p.readBoolean());
                p.readLong(), p.readLong(), p.readBoolean(), p.readString());
    }

    @Override
@@ -70,6 +73,7 @@ public final class CaptivePortalData implements Parcelable {
        dest.writeLong(mByteLimit);
        dest.writeLong(mExpiryTimeMillis);
        dest.writeBoolean(mCaptive);
        dest.writeString(mVenueFriendlyName);
    }

    /**
@@ -83,6 +87,7 @@ public final class CaptivePortalData implements Parcelable {
        private long mBytesRemaining = -1;
        private long mExpiryTime = -1;
        private boolean mCaptive;
        private String mVenueFriendlyName;

        /**
         * Create an empty builder.
@@ -100,7 +105,8 @@ public final class CaptivePortalData implements Parcelable {
                    .setSessionExtendable(data.mIsSessionExtendable)
                    .setBytesRemaining(data.mByteLimit)
                    .setExpiryTime(data.mExpiryTimeMillis)
                    .setCaptive(data.mCaptive);
                    .setCaptive(data.mCaptive)
                    .setVenueFriendlyName(data.mVenueFriendlyName);
        }

        /**
@@ -166,13 +172,23 @@ public final class CaptivePortalData implements Parcelable {
            return this;
        }

        /**
         * Set the venue friendly name.
         */
        @NonNull
        public Builder setVenueFriendlyName(@Nullable String venueFriendlyName) {
            mVenueFriendlyName = venueFriendlyName;
            return this;
        }

        /**
         * Create a new {@link CaptivePortalData}.
         */
        @NonNull
        public CaptivePortalData build() {
            return new CaptivePortalData(mRefreshTime, mUserPortalUrl, mVenueInfoUrl,
                    mIsSessionExtendable, mBytesRemaining, mExpiryTime, mCaptive);
                    mIsSessionExtendable, mBytesRemaining, mExpiryTime, mCaptive,
                    mVenueFriendlyName);
        }
    }

@@ -232,6 +248,14 @@ public final class CaptivePortalData implements Parcelable {
        return mCaptive;
    }

    /**
     * Get the venue friendly name
     */
    @Nullable
    public String getVenueFriendlyName() {
        return mVenueFriendlyName;
    }

    @NonNull
    public static final Creator<CaptivePortalData> CREATOR = new Creator<CaptivePortalData>() {
        @Override
@@ -248,7 +272,7 @@ public final class CaptivePortalData implements Parcelable {
    @Override
    public int hashCode() {
        return Objects.hash(mRefreshTimeMillis, mUserPortalUrl, mVenueInfoUrl,
                mIsSessionExtendable, mByteLimit, mExpiryTimeMillis, mCaptive);
                mIsSessionExtendable, mByteLimit, mExpiryTimeMillis, mCaptive, mVenueFriendlyName);
    }

    @Override
@@ -261,7 +285,8 @@ public final class CaptivePortalData implements Parcelable {
                && mIsSessionExtendable == other.mIsSessionExtendable
                && mByteLimit == other.mByteLimit
                && mExpiryTimeMillis == other.mExpiryTimeMillis
                && mCaptive == other.mCaptive;
                && mCaptive == other.mCaptive
                && Objects.equals(mVenueFriendlyName, other.mVenueFriendlyName);
    }

    @Override
@@ -274,6 +299,7 @@ public final class CaptivePortalData implements Parcelable {
                + ", byteLimit: " + mByteLimit
                + ", expiryTime: " + mExpiryTimeMillis
                + ", captive: " + mCaptive
                + ", venueFriendlyName: " + mVenueFriendlyName
                + "}";
    }
}
+60 −6
Original line number Diff line number Diff line
@@ -2973,7 +2973,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
                case EVENT_CAPPORT_DATA_CHANGED: {
                    final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
                    if (nai == null) break;
                    handleCaptivePortalDataUpdate(nai, (CaptivePortalData) msg.obj);
                    handleCapportApiDataUpdate(nai, (CaptivePortalData) msg.obj);
                    break;
                }
            }
@@ -3311,9 +3311,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
        handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
    }

    private void handleCaptivePortalDataUpdate(@NonNull final NetworkAgentInfo nai,
    private void handleCapportApiDataUpdate(@NonNull final NetworkAgentInfo nai,
            @Nullable final CaptivePortalData data) {
        nai.captivePortalData = data;
        nai.capportApiData = data;
        // CaptivePortalData will be merged into LinkProperties from NetworkAgentInfo
        handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
    }
@@ -6123,6 +6123,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
    private void processLinkPropertiesFromAgent(NetworkAgentInfo nai, LinkProperties lp) {
        lp.ensureDirectlyConnectedRoutes();
        nai.clatd.setNat64PrefixFromRa(lp.getNat64Prefix());
        nai.networkAgentPortalData = lp.getCaptivePortalData();
    }

    private void updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties newLp,
@@ -6166,9 +6167,11 @@ 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);
        // Captive portal data is obtained from NetworkMonitor and stored in NetworkAgentInfo.
        // It is not always contained in the LinkProperties sent from NetworkAgents, and if it
        // does, it needs to be merged here.
        newLp.setCaptivePortalData(mergeCaptivePortalData(networkAgent.networkAgentPortalData,
                networkAgent.capportApiData));

        // TODO - move this check to cover the whole function
        if (!Objects.equals(newLp, oldLp)) {
@@ -6188,6 +6191,57 @@ public class ConnectivityService extends IConnectivityManager.Stub
        mKeepaliveTracker.handleCheckKeepalivesStillValid(networkAgent);
    }

    /**
     * @param naData captive portal data from NetworkAgent
     * @param apiData captive portal data from capport API
     */
    @Nullable
    private CaptivePortalData mergeCaptivePortalData(CaptivePortalData naData,
            CaptivePortalData apiData) {
        if (naData == null || apiData == null) {
            return naData == null ? apiData : naData;
        }
        final CaptivePortalData.Builder captivePortalBuilder =
                new CaptivePortalData.Builder(naData);

        if (apiData.isCaptive()) {
            captivePortalBuilder.setCaptive(true);
        }
        if (apiData.isSessionExtendable()) {
            captivePortalBuilder.setSessionExtendable(true);
        }
        if (apiData.getExpiryTimeMillis() >= 0 || apiData.getByteLimit() >= 0) {
            // Expiry time, bytes remaining, refresh time all need to come from the same source,
            // otherwise data would be inconsistent. Prefer the capport API info if present,
            // as it can generally be refreshed more often.
            captivePortalBuilder.setExpiryTime(apiData.getExpiryTimeMillis());
            captivePortalBuilder.setBytesRemaining(apiData.getByteLimit());
            captivePortalBuilder.setRefreshTime(apiData.getRefreshTimeMillis());
        } else if (naData.getExpiryTimeMillis() < 0 && naData.getByteLimit() < 0) {
            // No source has time / bytes remaining information: surface the newest refresh time
            // for other fields
            captivePortalBuilder.setRefreshTime(
                    Math.max(naData.getRefreshTimeMillis(), apiData.getRefreshTimeMillis()));
        }

        // Prioritize the user portal URL from the network agent.
        if (apiData.getUserPortalUrl() != null && (naData.getUserPortalUrl() == null
                || TextUtils.isEmpty(naData.getUserPortalUrl().toSafeString()))) {
            captivePortalBuilder.setUserPortalUrl(apiData.getUserPortalUrl());
        }
        // Prioritize the venue information URL from the network agent.
        if (apiData.getVenueInfoUrl() != null && (naData.getVenueInfoUrl() == null
                || TextUtils.isEmpty(naData.getVenueInfoUrl().toSafeString()))) {
            captivePortalBuilder.setVenueInfoUrl(apiData.getVenueInfoUrl());

            // Note that venue friendly name can only come from the network agent because it is not
            // in use in RFC8908. However, if using the Capport venue URL, make sure that the
            // friendly name is not set from the network agent.
            captivePortalBuilder.setVenueFriendlyName(null);
        }
        return captivePortalBuilder.build();
    }

    private void wakeupModifyInterface(String iface, NetworkCapabilities caps, boolean add) {
        // Marks are only available on WiFi interfaces. Checking for
        // marks on unsupported interfaces is harmless.
+7 −2
Original line number Diff line number Diff line
@@ -189,13 +189,18 @@ 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.
    // Captive portal info of the network from RFC8908, if any.
    // Obtained by ConnectivityService and merged into NetworkAgent-provided information.
    public CaptivePortalData captivePortalData;
    public CaptivePortalData capportApiData;

    // The UID of the remote entity that created this Network.
    public final int creatorUid;

    // Network agent portal info of the network, if any. This information is provided from
    // non-RFC8908 sources, such as Wi-Fi Passpoint, which can provide information such as Venue
    // URL, Terms & Conditions URL, and network friendly name.
    public CaptivePortalData networkAgentPortalData;

    // 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
+9 −1
Original line number Diff line number Diff line
@@ -41,13 +41,14 @@ class CaptivePortalDataTest {
            .setBytesRemaining(456L)
            .setExpiryTime(789L)
            .setCaptive(true)
            .setVenueFriendlyName("venue friendly name")
            .build()

    private fun makeBuilder() = CaptivePortalData.Builder(data)

    @Test
    fun testParcelUnparcel() {
        assertParcelSane(data, fieldCount = 7)
        assertParcelSane(data, fieldCount = 8)

        assertParcelingIsLossless(makeBuilder().setUserPortalUrl(null).build())
        assertParcelingIsLossless(makeBuilder().setVenueInfoUrl(null).build())
@@ -66,6 +67,8 @@ class CaptivePortalDataTest {
        assertNotEqualsAfterChange { it.setBytesRemaining(789L) }
        assertNotEqualsAfterChange { it.setExpiryTime(12L) }
        assertNotEqualsAfterChange { it.setCaptive(false) }
        assertNotEqualsAfterChange { it.setVenueFriendlyName("another friendly name") }
        assertNotEqualsAfterChange { it.setVenueFriendlyName(null) }
    }

    @Test
@@ -108,6 +111,11 @@ class CaptivePortalDataTest {
        assertFalse(makeBuilder().setCaptive(false).build().isCaptive)
    }

    @Test
    fun testVenueFriendlyName() {
        assertEquals("venue friendly name", data.venueFriendlyName)
    }

    private fun CaptivePortalData.mutate(mutator: (CaptivePortalData.Builder) -> Unit) =
            CaptivePortalData.Builder(this).apply { mutator(this) }.build()

Loading