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

Commit 36337e9a authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Add API for CaptivePortalData" am: 144519f4 am: f3011f77

Change-Id: Ifed2e05d433dda40615af4b41d1f8cf4e9445de0
parents c6ac7503 f3011f77
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -4307,6 +4307,32 @@ package android.net {
    field public static final int APP_RETURN_WANTED_AS_IS = 2; // 0x2
  }
  public final class CaptivePortalData implements android.os.Parcelable {
    method public int describeContents();
    method public long getByteLimit();
    method public long getExpiryTimeMillis();
    method public long getRefreshTimeMillis();
    method @Nullable public android.net.Uri getUserPortalUrl();
    method @Nullable public android.net.Uri getVenueInfoUrl();
    method public boolean isCaptive();
    method public boolean isSessionExtendable();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.net.CaptivePortalData> CREATOR;
  }
  public static class CaptivePortalData.Builder {
    ctor public CaptivePortalData.Builder();
    ctor public CaptivePortalData.Builder(@Nullable android.net.CaptivePortalData);
    method @NonNull public android.net.CaptivePortalData build();
    method @NonNull public android.net.CaptivePortalData.Builder setBytesRemaining(long);
    method @NonNull public android.net.CaptivePortalData.Builder setCaptive(boolean);
    method @NonNull public android.net.CaptivePortalData.Builder setExpiryTime(long);
    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 setVenueInfoUrl(@Nullable android.net.Uri);
  }
  public class ConnectivityManager {
    method @NonNull @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createNattKeepalive(@NonNull android.net.Network, @NonNull android.os.ParcelFileDescriptor, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
    method @NonNull @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull java.net.Socket, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
@@ -4438,6 +4464,8 @@ package android.net {
    method @NonNull public java.util.List<java.lang.String> getAllInterfaceNames();
    method @NonNull public java.util.List<android.net.LinkAddress> getAllLinkAddresses();
    method @NonNull public java.util.List<android.net.RouteInfo> getAllRoutes();
    method @Nullable public android.net.Uri getCaptivePortalApiUrl();
    method @Nullable public android.net.CaptivePortalData getCaptivePortalData();
    method @NonNull public java.util.List<java.net.InetAddress> getPcscfServers();
    method @Nullable public String getTcpBufferSizes();
    method @NonNull public java.util.List<java.net.InetAddress> getValidatedPrivateDnsServers();
@@ -4451,9 +4479,12 @@ package android.net {
    method public boolean isIpv6Provisioned();
    method public boolean isProvisioned();
    method public boolean isReachable(@NonNull java.net.InetAddress);
    method @NonNull public android.net.LinkProperties makeSensitiveFieldsParcelingCopy();
    method public boolean removeDnsServer(@NonNull java.net.InetAddress);
    method public boolean removeLinkAddress(@NonNull android.net.LinkAddress);
    method public boolean removeRoute(@NonNull android.net.RouteInfo);
    method public void setCaptivePortalApiUrl(@Nullable android.net.Uri);
    method public void setCaptivePortalData(@Nullable android.net.CaptivePortalData);
    method public void setPcscfServers(@NonNull java.util.Collection<java.net.InetAddress>);
    method public void setPrivateDnsServerName(@Nullable String);
    method public void setTcpBufferSizes(@Nullable String);
+31 −0
Original line number Diff line number Diff line
@@ -1361,6 +1361,32 @@ package android.net {
    field public static final int APP_RETURN_WANTED_AS_IS = 2; // 0x2
  }

  public final class CaptivePortalData implements android.os.Parcelable {
    method public int describeContents();
    method public long getByteLimit();
    method public long getExpiryTimeMillis();
    method public long getRefreshTimeMillis();
    method @Nullable public android.net.Uri getUserPortalUrl();
    method @Nullable public android.net.Uri getVenueInfoUrl();
    method public boolean isCaptive();
    method public boolean isSessionExtendable();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.net.CaptivePortalData> CREATOR;
  }

  public static class CaptivePortalData.Builder {
    ctor public CaptivePortalData.Builder();
    ctor public CaptivePortalData.Builder(@Nullable android.net.CaptivePortalData);
    method @NonNull public android.net.CaptivePortalData build();
    method @NonNull public android.net.CaptivePortalData.Builder setBytesRemaining(long);
    method @NonNull public android.net.CaptivePortalData.Builder setCaptive(boolean);
    method @NonNull public android.net.CaptivePortalData.Builder setExpiryTime(long);
    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 setVenueInfoUrl(@Nullable android.net.Uri);
  }

  public class ConnectivityManager {
    method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(@NonNull android.net.Network, @NonNull android.os.Bundle);
    field public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC = "android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC";
@@ -1391,6 +1417,8 @@ package android.net {
    ctor public LinkProperties(@Nullable android.net.LinkProperties);
    method public boolean addDnsServer(@NonNull java.net.InetAddress);
    method public boolean addLinkAddress(@NonNull android.net.LinkAddress);
    method @Nullable public android.net.Uri getCaptivePortalApiUrl();
    method @Nullable public android.net.CaptivePortalData getCaptivePortalData();
    method @NonNull public java.util.List<java.net.InetAddress> getPcscfServers();
    method @Nullable public String getTcpBufferSizes();
    method @NonNull public java.util.List<java.net.InetAddress> getValidatedPrivateDnsServers();
@@ -1401,9 +1429,12 @@ package android.net {
    method public boolean isIpv6Provisioned();
    method public boolean isProvisioned();
    method public boolean isReachable(@NonNull java.net.InetAddress);
    method @NonNull public android.net.LinkProperties makeSensitiveFieldsParcelingCopy();
    method public boolean removeDnsServer(@NonNull java.net.InetAddress);
    method public boolean removeLinkAddress(@NonNull android.net.LinkAddress);
    method public boolean removeRoute(@NonNull android.net.RouteInfo);
    method public void setCaptivePortalApiUrl(@Nullable android.net.Uri);
    method public void setCaptivePortalData(@Nullable android.net.CaptivePortalData);
    method public void setPcscfServers(@NonNull java.util.Collection<java.net.InetAddress>);
    method public void setPrivateDnsServerName(@Nullable String);
    method public void setTcpBufferSizes(@Nullable String);
+19 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.net;

@JavaOnlyStableParcelable parcelable CaptivePortalData;
+281 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.net;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;

import java.util.Objects;

/**
 * Metadata sent by captive portals, see https://www.ietf.org/id/draft-ietf-capport-api-03.txt.
 * @hide
 */
@SystemApi
@TestApi
public final class CaptivePortalData implements Parcelable {
    private final long mRefreshTimeMillis;
    @Nullable
    private final Uri mUserPortalUrl;
    @Nullable
    private final Uri mVenueInfoUrl;
    private final boolean mIsSessionExtendable;
    private final long mByteLimit;
    private final long mExpiryTimeMillis;
    private final boolean mCaptive;

    private CaptivePortalData(long refreshTimeMillis, Uri userPortalUrl, Uri venueInfoUrl,
            boolean isSessionExtendable, long byteLimit, long expiryTimeMillis, boolean captive) {
        mRefreshTimeMillis = refreshTimeMillis;
        mUserPortalUrl = userPortalUrl;
        mVenueInfoUrl = venueInfoUrl;
        mIsSessionExtendable = isSessionExtendable;
        mByteLimit = byteLimit;
        mExpiryTimeMillis = expiryTimeMillis;
        mCaptive = captive;
    }

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

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeLong(mRefreshTimeMillis);
        dest.writeParcelable(mUserPortalUrl, 0);
        dest.writeParcelable(mVenueInfoUrl, 0);
        dest.writeBoolean(mIsSessionExtendable);
        dest.writeLong(mByteLimit);
        dest.writeLong(mExpiryTimeMillis);
        dest.writeBoolean(mCaptive);
    }

    /**
     * A builder to create new {@link CaptivePortalData}.
     */
    public static class Builder {
        private long mRefreshTime;
        private Uri mUserPortalUrl;
        private Uri mVenueInfoUrl;
        private boolean mIsSessionExtendable;
        private long mBytesRemaining = -1;
        private long mExpiryTime = -1;
        private boolean mCaptive;

        /**
         * Create an empty builder.
         */
        public Builder() {}

        /**
         * Create a builder copying all data from existing {@link CaptivePortalData}.
         */
        public Builder(@Nullable CaptivePortalData data) {
            if (data == null) return;
            setRefreshTime(data.mRefreshTimeMillis)
                    .setUserPortalUrl(data.mUserPortalUrl)
                    .setVenueInfoUrl(data.mVenueInfoUrl)
                    .setSessionExtendable(data.mIsSessionExtendable)
                    .setBytesRemaining(data.mByteLimit)
                    .setExpiryTime(data.mExpiryTimeMillis)
                    .setCaptive(data.mCaptive);
        }

        /**
         * Set the time at which data was last refreshed, as per {@link System#currentTimeMillis()}.
         */
        @NonNull
        public Builder setRefreshTime(long refreshTime) {
            mRefreshTime = refreshTime;
            return this;
        }

        /**
         * Set the URL to be used for users to login to the portal, if captive.
         */
        @NonNull
        public Builder setUserPortalUrl(@Nullable Uri userPortalUrl) {
            mUserPortalUrl = userPortalUrl;
            return this;
        }

        /**
         * Set the URL that can be used by users to view information about the network venue.
         */
        @NonNull
        public Builder setVenueInfoUrl(@Nullable Uri venueInfoUrl) {
            mVenueInfoUrl = venueInfoUrl;
            return this;
        }

        /**
         * Set whether the portal supports extending a user session on the portal URL page.
         */
        @NonNull
        public Builder setSessionExtendable(boolean sessionExtendable) {
            mIsSessionExtendable = sessionExtendable;
            return this;
        }

        /**
         * Set the number of bytes remaining on the network before the portal closes.
         */
        @NonNull
        public Builder setBytesRemaining(long bytesRemaining) {
            mBytesRemaining = bytesRemaining;
            return this;
        }

        /**
         * Set the time at the session will expire, as per {@link System#currentTimeMillis()}.
         */
        @NonNull
        public Builder setExpiryTime(long expiryTime) {
            mExpiryTime = expiryTime;
            return this;
        }

        /**
         * Set whether the network is captive (portal closed).
         */
        @NonNull
        public Builder setCaptive(boolean captive) {
            mCaptive = captive;
            return this;
        }

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

    /**
     * Get the time at which data was last refreshed, as per {@link System#currentTimeMillis()}.
     */
    public long getRefreshTimeMillis() {
        return mRefreshTimeMillis;
    }

    /**
     * Get the URL to be used for users to login to the portal, or extend their session if
     * {@link #isSessionExtendable()} is true.
     */
    @Nullable
    public Uri getUserPortalUrl() {
        return mUserPortalUrl;
    }

    /**
     * Get the URL that can be used by users to view information about the network venue.
     */
    @Nullable
    public Uri getVenueInfoUrl() {
        return mVenueInfoUrl;
    }

    /**
     * Indicates whether the user portal URL can be used to extend sessions, when the user is logged
     * in and the session has a time or byte limit.
     */
    public boolean isSessionExtendable() {
        return mIsSessionExtendable;
    }

    /**
     * Get the remaining bytes on the captive portal session, at the time {@link CaptivePortalData}
     * was refreshed. This may be different from the limit currently enforced by the portal.
     * @return The byte limit, or -1 if not set.
     */
    public long getByteLimit() {
        return mByteLimit;
    }

    /**
     * Get the time at the session will expire, as per {@link System#currentTimeMillis()}.
     * @return The expiry time, or -1 if unset.
     */
    public long getExpiryTimeMillis() {
        return mExpiryTimeMillis;
    }

    /**
     * Get whether the network is captive (portal closed).
     */
    public boolean isCaptive() {
        return mCaptive;
    }

    @NonNull
    public static final Creator<CaptivePortalData> CREATOR = new Creator<CaptivePortalData>() {
        @Override
        public CaptivePortalData createFromParcel(Parcel source) {
            return new CaptivePortalData(source);
        }

        @Override
        public CaptivePortalData[] newArray(int size) {
            return new CaptivePortalData[size];
        }
    };

    @Override
    public int hashCode() {
        return Objects.hash(mRefreshTimeMillis, mUserPortalUrl, mVenueInfoUrl,
                mIsSessionExtendable, mByteLimit, mExpiryTimeMillis, mCaptive);
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof CaptivePortalData)) return false;
        final CaptivePortalData other = (CaptivePortalData) obj;
        return mRefreshTimeMillis == other.mRefreshTimeMillis
                && Objects.equals(mUserPortalUrl, other.mUserPortalUrl)
                && Objects.equals(mVenueInfoUrl, other.mVenueInfoUrl)
                && mIsSessionExtendable == other.mIsSessionExtendable
                && mByteLimit == other.mByteLimit
                && mExpiryTimeMillis == other.mExpiryTimeMillis
                && mCaptive == other.mCaptive;
    }

    @Override
    public String toString() {
        return "CaptivePortalData {"
                + "refreshTime: " + mRefreshTimeMillis
                + ", userPortalUrl: " + mUserPortalUrl
                + ", venueInfoUrl: " + mVenueInfoUrl
                + ", isSessionExtendable: " + mIsSessionExtendable
                + ", byteLimit: " + mByteLimit
                + ", expiryTime: " + mExpiryTimeMillis
                + ", captive: " + mCaptive
                + "}";
    }
}
+148 −21
Original line number Diff line number Diff line
@@ -70,6 +70,14 @@ public final class LinkProperties implements Parcelable {
    private String mTcpBufferSizes;
    private IpPrefix mNat64Prefix;
    private boolean mWakeOnLanSupported;
    private Uri mCaptivePortalApiUrl;
    private CaptivePortalData mCaptivePortalData;

    /**
     * Indicates whether parceling should preserve fields that are set based on permissions of
     * the process receiving the {@link LinkProperties}.
     */
    private final transient boolean mParcelSensitiveFields;

    private static final int MIN_MTU    = 68;
    private static final int MIN_MTU_V6 = 1280;
@@ -174,6 +182,7 @@ public final class LinkProperties implements Parcelable {
     * Constructs a new {@code LinkProperties} with default values.
     */
    public LinkProperties() {
        mParcelSensitiveFields = false;
    }

    /**
@@ -182,7 +191,12 @@ public final class LinkProperties implements Parcelable {
    @SystemApi
    @TestApi
    public LinkProperties(@Nullable LinkProperties source) {
        if (source != null) {
        this(source, false /* parcelSensitiveFields */);
    }

    private LinkProperties(@Nullable LinkProperties source, boolean parcelSensitiveFields) {
        mParcelSensitiveFields = parcelSensitiveFields;
        if (source == null) return;
        mIfaceName = source.mIfaceName;
        mLinkAddresses.addAll(source.mLinkAddresses);
        mDnses.addAll(source.mDnses);
@@ -201,7 +215,8 @@ public final class LinkProperties implements Parcelable {
        mTcpBufferSizes = source.mTcpBufferSizes;
        mNat64Prefix = source.mNat64Prefix;
        mWakeOnLanSupported = source.mWakeOnLanSupported;
        }
        mCaptivePortalApiUrl = source.mCaptivePortalApiUrl;
        mCaptivePortalData = source.mCaptivePortalData;
    }

    /**
@@ -860,6 +875,11 @@ public final class LinkProperties implements Parcelable {
     * Clears this object to its initial state.
     */
    public void clear() {
        if (mParcelSensitiveFields) {
            throw new UnsupportedOperationException(
                    "Cannot clear LinkProperties when parcelSensitiveFields is set");
        }

        mIfaceName = null;
        mLinkAddresses.clear();
        mDnses.clear();
@@ -875,6 +895,8 @@ public final class LinkProperties implements Parcelable {
        mTcpBufferSizes = null;
        mNat64Prefix = null;
        mWakeOnLanSupported = false;
        mCaptivePortalApiUrl = null;
        mCaptivePortalData = null;
    }

    /**
@@ -945,6 +967,14 @@ public final class LinkProperties implements Parcelable {
            resultJoiner.add(mDhcpServerAddress.toString());
        }

        if (mCaptivePortalApiUrl != null) {
            resultJoiner.add("CaptivePortalApiUrl: " + mCaptivePortalApiUrl);
        }

        if (mCaptivePortalData != null) {
            resultJoiner.add("CaptivePortalData: " + mCaptivePortalData);
        }

        if (mTcpBufferSizes != null) {
            resultJoiner.add("TcpBufferSizes:");
            resultJoiner.add(mTcpBufferSizes);
@@ -1478,6 +1508,28 @@ public final class LinkProperties implements Parcelable {
        return isWakeOnLanSupported() == target.isWakeOnLanSupported();
    }

    /**
     * Compares this {@code LinkProperties}'s CaptivePortalApiUrl against the target.
     *
     * @param target LinkProperties to compare.
     * @return {@code true} if both are identical, {@code false} otherwise.
     * @hide
     */
    public boolean isIdenticalCaptivePortalApiUrl(LinkProperties target) {
        return Objects.equals(mCaptivePortalApiUrl, target.mCaptivePortalApiUrl);
    }

    /**
     * Compares this {@code LinkProperties}'s CaptivePortalData against the target.
     *
     * @param target LinkProperties to compare.
     * @return {@code true} if both are identical, {@code false} otherwise.
     * @hide
     */
    public boolean isIdenticalCaptivePortalData(LinkProperties target) {
        return Objects.equals(mCaptivePortalData, target.mCaptivePortalData);
    }

    /**
     * Set whether the network interface supports WakeOnLAN
     *
@@ -1498,6 +1550,73 @@ public final class LinkProperties implements Parcelable {
        return mWakeOnLanSupported;
    }

    /**
     * Set the URL of the captive portal API endpoint to get more information about the network.
     * @hide
     */
    @SystemApi
    @TestApi
    public void setCaptivePortalApiUrl(@Nullable Uri url) {
        mCaptivePortalApiUrl = url;
    }

    /**
     * Get the URL of the captive portal API endpoint to get more information about the network.
     *
     * <p>This is null unless the application has
     * {@link android.Manifest.permission.NETWORK_SETTINGS} or
     * {@link NetworkStack#PERMISSION_MAINLINE_NETWORK_STACK} permissions, and the network provided
     * the URL.
     * @hide
     */
    @SystemApi
    @TestApi
    @Nullable
    public Uri getCaptivePortalApiUrl() {
        return mCaptivePortalApiUrl;
    }

    /**
     * Set the CaptivePortalData obtained from the captive portal API (RFC7710bis).
     * @hide
     */
    @SystemApi
    @TestApi
    public void setCaptivePortalData(@Nullable CaptivePortalData data) {
        mCaptivePortalData = data;
    }

    /**
     * Get the CaptivePortalData obtained from the captive portal API (RFC7710bis).
     *
     * <p>This is null unless the application has
     * {@link android.Manifest.permission.NETWORK_SETTINGS} or
     * {@link NetworkStack#PERMISSION_MAINLINE_NETWORK_STACK} permissions.
     * @hide
     */
    @SystemApi
    @TestApi
    @Nullable
    public CaptivePortalData getCaptivePortalData() {
        return mCaptivePortalData;
    }

    /**
     * Create a copy of this {@link LinkProperties} that will preserve fields that were set
     * based on the permissions of the process that received this {@link LinkProperties}.
     *
     * <p>By default {@link LinkProperties} does not preserve such fields during parceling, as
     * they should not be shared outside of the process that receives them without appropriate
     * checks.
     * @hide
     */
    @SystemApi
    @TestApi
    @NonNull
    public LinkProperties makeSensitiveFieldsParcelingCopy() {
        return new LinkProperties(this, true /* parcelSensitiveFields */);
    }

    /**
     * Compares this {@code LinkProperties} instance against the target
     * LinkProperties in {@code obj}. Two LinkPropertieses are equal if
@@ -1537,7 +1656,9 @@ public final class LinkProperties implements Parcelable {
                && isIdenticalMtu(target)
                && isIdenticalTcpBufferSizes(target)
                && isIdenticalNat64Prefix(target)
                && isIdenticalWakeOnLan(target);
                && isIdenticalWakeOnLan(target)
                && isIdenticalCaptivePortalApiUrl(target)
                && isIdenticalCaptivePortalData(target);
    }

    /**
@@ -1655,7 +1776,8 @@ public final class LinkProperties implements Parcelable {
                + mPcscfs.size() * 67
                + ((null == mPrivateDnsServerName) ? 0 : mPrivateDnsServerName.hashCode())
                + Objects.hash(mNat64Prefix)
                + (mWakeOnLanSupported ? 71 : 0);
                + (mWakeOnLanSupported ? 71 : 0)
                + Objects.hash(mCaptivePortalApiUrl, mCaptivePortalData);
    }

    /**
@@ -1694,6 +1816,8 @@ public final class LinkProperties implements Parcelable {
        dest.writeList(stackedLinks);

        dest.writeBoolean(mWakeOnLanSupported);
        dest.writeParcelable(mParcelSensitiveFields ? mCaptivePortalApiUrl : null, 0);
        dest.writeParcelable(mParcelSensitiveFields ? mCaptivePortalData : null, 0);
    }

    private static void writeAddresses(@NonNull Parcel dest, @NonNull List<InetAddress> list) {
@@ -1785,6 +1909,9 @@ public final class LinkProperties implements Parcelable {
                    netProp.addStackedLink(stackedLink);
                }
                netProp.setWakeOnLanSupported(in.readBoolean());

                netProp.setCaptivePortalApiUrl(in.readParcelable(null));
                netProp.setCaptivePortalData(in.readParcelable(null));
                return netProp;
            }

Loading