diff --git a/framework/src/android/net/Network.java b/framework/src/android/net/Network.java index 53f171a017..bc8071277a 100644 --- a/framework/src/android/net/Network.java +++ b/framework/src/android/net/Network.java @@ -29,6 +29,7 @@ import android.system.Os; import android.system.OsConstants; import com.android.internal.annotations.GuardedBy; +import com.android.modules.utils.build.SdkLevel; import libcore.io.IoUtils; import libcore.net.http.Dns; @@ -102,12 +103,7 @@ public class Network implements Parcelable { // and permission checks are made by netd (attempts to bypass Private DNS // without appropriate permission are silently turned into vanilla DNS // requests). This only affects DNS queries made using this network object. - // - // It it not parceled to receivers because (a) it can be set or cleared at - // anytime and (b) receivers should be explicit about attempts to bypass - // Private DNS so that the intent of the code is easily determined and - // code search audits are possible. - private final transient boolean mPrivateDnsBypass; + private final boolean mPrivateDnsBypass; /** * @hide @@ -170,6 +166,18 @@ public class Network implements Parcelable { return new Network(netId, true); } + /** + * Obtain a Network object that respects the Private DNS settings when attempting + * to use {@link #getAllByName(String)}/{@link #getByName(String)} methods on the given + * instance for hostname resolution. + * + * @hide + */ + // TODO : @SystemApi if this becomes useful. + public @NonNull Network getPrivateDnsNonBypassingCopy() { + return new Network(netId, false); + } + /** * Get the unique id of the network. * @@ -497,31 +505,35 @@ public class Network implements Parcelable { } public void writeToParcel(Parcel dest, int flags) { dest.writeInt(netId); + if (SdkLevel.isAtLeastB()) { + dest.writeBoolean(mPrivateDnsBypass); + } else { + dest.writeBoolean(false); + } } public static final @android.annotation.NonNull Creator CREATOR = - new Creator() { - public Network createFromParcel(Parcel in) { - int netId = in.readInt(); + new Creator<>() { + public Network createFromParcel(Parcel in) { + final int netId = in.readInt(); + final boolean bypass = in.readBoolean(); + return new Network(netId, bypass); + } - return new Network(netId); - } - - public Network[] newArray(int size) { - return new Network[size]; - } - }; + public Network[] newArray(int size) { + return new Network[size]; + } + }; @Override public boolean equals(@Nullable Object obj) { - if (!(obj instanceof Network)) return false; - Network other = (Network)obj; + if (!(obj instanceof Network other)) return false; return this.netId == other.netId; } @Override public int hashCode() { - return netId * 11; + return netId; } @Override diff --git a/tests/common/java/android/net/NetworkTest.java b/tests/common/java/android/net/NetworkTest.java index 86d2463ce2..580beabe63 100644 --- a/tests/common/java/android/net/NetworkTest.java +++ b/tests/common/java/android/net/NetworkTest.java @@ -32,6 +32,7 @@ import com.android.testutils.ConnectivityModuleTest; import com.android.testutils.DevSdkIgnoreRule; import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter; import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; +import com.android.testutils.ParcelUtils; import org.junit.Rule; import org.junit.Test; @@ -200,4 +201,37 @@ public class NetworkTest { assertNotEquals(copy.netId, copy.getNetIdForResolv()); assertNotEquals(mNetwork.getNetIdForResolv(), copy.getNetIdForResolv()); } + + // Connectivity module was not supported until S + @Test @IgnoreUpTo(Build.VERSION_CODES.R) + @ConnectivityModuleTest + public void testGetNonPrivateDnsBypassingCopy() { + final Network bypass = mNetwork.getPrivateDnsBypassingCopy(); + final Network nonBypass = bypass.getPrivateDnsNonBypassingCopy(); + assertEquals(mNetwork.netId, nonBypass.netId); + assertEquals(nonBypass.netId, nonBypass.getNetIdForResolv()); + assertEquals(mNetwork.getNetIdForResolv(), nonBypass.getNetIdForResolv()); + assertNotEquals(mNetwork.getNetIdForResolv(), bypass.getNetIdForResolv()); + } + + // Only run this test on V and below + @Test @IgnoreAfter(Build.VERSION_CODES.VANILLA_ICE_CREAM) + @ConnectivityModuleTest + public void testParcelingRoundTripBeforeB() { + // Before B, the netID for resolv is not parceled. + final Network bypass = + ParcelUtils.parcelingRoundTrip(mNetwork.getPrivateDnsBypassingCopy()); + assertEquals(mNetwork.netId, bypass.netId); + assertEquals(mNetwork.getNetIdForResolv(), bypass.getNetIdForResolv()); + } + + // Only run this test on B and after + @Test @IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM) + @ConnectivityModuleTest + public void testParcelingRoundTripFromB() { + final Network bypass = + ParcelUtils.parcelingRoundTrip(mNetwork.getPrivateDnsBypassingCopy()); + assertEquals(mNetwork.netId, bypass.netId); + assertNotEquals(mNetwork.getNetIdForResolv(), bypass.getNetIdForResolv()); + } }