diff options
3 files changed, 377 insertions, 0 deletions
diff --git a/core/java/android/net/vcn/VcnUnderlyingNetworkPriority.java b/core/java/android/net/vcn/VcnUnderlyingNetworkPriority.java new file mode 100644 index 000000000000..27750c659fc9 --- /dev/null +++ b/core/java/android/net/vcn/VcnUnderlyingNetworkPriority.java @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2021 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.vcn; + +import static com.android.internal.annotations.VisibleForTesting.Visibility; + +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.PersistableBundle; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.Preconditions; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.Objects; + +// TODO: Add documents +/** @hide */ +public abstract class VcnUnderlyingNetworkPriority { + /** @hide */ + protected static final int NETWORK_PRIORITY_TYPE_WIFI = 1; + /** @hide */ + protected static final int NETWORK_PRIORITY_TYPE_CELL = 2; + + /** Denotes that network quality needs to be OK */ + public static final int NETWORK_QUALITY_OK = 10000; + /** Denotes that any network quality is acceptable */ + public static final int NETWORK_QUALITY_ANY = Integer.MAX_VALUE; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({NETWORK_QUALITY_OK, NETWORK_QUALITY_ANY}) + public @interface NetworkQuality {} + + private static final String NETWORK_PRIORITY_TYPE_KEY = "mNetworkPriorityType"; + private final int mNetworkPriorityType; + + /** @hide */ + protected static final String NETWORK_QUALITY_KEY = "mNetworkQuality"; + private final int mNetworkQuality; + + /** @hide */ + protected static final String ALLOW_METERED_KEY = "mAllowMetered"; + private final boolean mAllowMetered; + + /** @hide */ + protected VcnUnderlyingNetworkPriority( + int networkPriorityType, int networkQuality, boolean allowMetered) { + mNetworkPriorityType = networkPriorityType; + mNetworkQuality = networkQuality; + mAllowMetered = allowMetered; + } + + private static void validateNetworkQuality(int networkQuality) { + Preconditions.checkArgument( + networkQuality == NETWORK_QUALITY_ANY || networkQuality == NETWORK_QUALITY_OK, + "Invalid networkQuality:" + networkQuality); + } + + /** @hide */ + protected void validate() { + validateNetworkQuality(mNetworkQuality); + } + + /** @hide */ + @NonNull + @VisibleForTesting(visibility = Visibility.PROTECTED) + public static VcnUnderlyingNetworkPriority fromPersistableBundle( + @NonNull PersistableBundle in) { + Objects.requireNonNull(in, "PersistableBundle is null"); + + final int networkPriorityType = in.getInt(NETWORK_PRIORITY_TYPE_KEY); + switch (networkPriorityType) { + case NETWORK_PRIORITY_TYPE_WIFI: + return VcnWifiUnderlyingNetworkPriority.fromPersistableBundle(in); + case NETWORK_PRIORITY_TYPE_CELL: + throw new UnsupportedOperationException("Not implemented"); + default: + throw new IllegalArgumentException( + "Invalid networkPriorityType:" + networkPriorityType); + } + } + + /** @hide */ + @NonNull + PersistableBundle toPersistableBundle() { + final PersistableBundle result = new PersistableBundle(); + + result.putInt(NETWORK_PRIORITY_TYPE_KEY, mNetworkPriorityType); + result.putInt(NETWORK_QUALITY_KEY, mNetworkQuality); + result.putBoolean(ALLOW_METERED_KEY, mAllowMetered); + + return result; + } + + @Override + public int hashCode() { + return Objects.hash(mNetworkPriorityType, mNetworkQuality, mAllowMetered); + } + + @Override + public boolean equals(@Nullable Object other) { + if (!(other instanceof VcnUnderlyingNetworkPriority)) { + return false; + } + + final VcnUnderlyingNetworkPriority rhs = (VcnUnderlyingNetworkPriority) other; + return mNetworkPriorityType == rhs.mNetworkPriorityType + && mNetworkQuality == rhs.mNetworkQuality + && mAllowMetered == rhs.mAllowMetered; + } + + /** Retrieve the required network quality. */ + @NetworkQuality + public int getNetworkQuality() { + return mNetworkQuality; + } + + /** Return if a metered network is allowed. */ + public boolean allowMetered() { + return mAllowMetered; + } + + /** + * This class is used to incrementally build VcnUnderlyingNetworkPriority objects. + * + * @param <T> The subclass to be built. + */ + public abstract static class Builder<T extends Builder<T>> { + /** @hide */ + protected int mNetworkQuality = NETWORK_QUALITY_ANY; + /** @hide */ + protected boolean mAllowMetered = false; + + /** @hide */ + protected Builder() {} + + /** + * Set the required network quality. + * + * @param networkQuality the required network quality. Defaults to NETWORK_QUALITY_ANY + */ + @NonNull + public T setNetworkQuality(@NetworkQuality int networkQuality) { + validateNetworkQuality(networkQuality); + + mNetworkQuality = networkQuality; + return self(); + } + + /** + * Set if a metered network is allowed. + * + * @param allowMetered the flag to indicate if a metered network is allowed, defaults to + * {@code false} + */ + @NonNull + public T setAllowMetered(boolean allowMetered) { + mAllowMetered = allowMetered; + return self(); + } + + /** @hide */ + abstract T self(); + } +} diff --git a/core/java/android/net/vcn/VcnWifiUnderlyingNetworkPriority.java b/core/java/android/net/vcn/VcnWifiUnderlyingNetworkPriority.java new file mode 100644 index 000000000000..fc7e7e2c4e41 --- /dev/null +++ b/core/java/android/net/vcn/VcnWifiUnderlyingNetworkPriority.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2021 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.vcn; + +import static com.android.internal.annotations.VisibleForTesting.Visibility; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.PersistableBundle; + +import com.android.internal.annotations.VisibleForTesting; + +import java.util.Objects; + +// TODO: Add documents +/** @hide */ +public final class VcnWifiUnderlyingNetworkPriority extends VcnUnderlyingNetworkPriority { + private static final String SSID_KEY = "mSsid"; + @Nullable private final String mSsid; + + private VcnWifiUnderlyingNetworkPriority( + int networkQuality, boolean allowMetered, String ssid) { + super(NETWORK_PRIORITY_TYPE_WIFI, networkQuality, allowMetered); + mSsid = ssid; + + validate(); + } + + /** @hide */ + @NonNull + @VisibleForTesting(visibility = Visibility.PROTECTED) + public static VcnWifiUnderlyingNetworkPriority fromPersistableBundle( + @NonNull PersistableBundle in) { + Objects.requireNonNull(in, "PersistableBundle is null"); + + final int networkQuality = in.getInt(NETWORK_QUALITY_KEY); + final boolean allowMetered = in.getBoolean(ALLOW_METERED_KEY); + final String ssid = in.getString(SSID_KEY); + return new VcnWifiUnderlyingNetworkPriority(networkQuality, allowMetered, ssid); + } + + /** @hide */ + @Override + @NonNull + @VisibleForTesting(visibility = Visibility.PROTECTED) + public PersistableBundle toPersistableBundle() { + final PersistableBundle result = super.toPersistableBundle(); + result.putString(SSID_KEY, mSsid); + return result; + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), mSsid); + } + + @Override + public boolean equals(@Nullable Object other) { + if (!super.equals(other)) { + return false; + } + + if (!(other instanceof VcnWifiUnderlyingNetworkPriority)) { + return false; + } + + final VcnWifiUnderlyingNetworkPriority rhs = (VcnWifiUnderlyingNetworkPriority) other; + return mSsid == rhs.mSsid; + } + + /** Retrieve the required SSID, or {@code null} if there is no requirement on SSID. */ + @Nullable + public String getSsid() { + return mSsid; + } + + /** This class is used to incrementally build VcnWifiUnderlyingNetworkPriority objects. */ + public static class Builder extends VcnUnderlyingNetworkPriority.Builder<Builder> { + @Nullable private String mSsid; + + /** Construct a Builder object. */ + public Builder() {} + + /** + * Set the required SSID. + * + * @param ssid the required SSID, or {@code null} if any SSID is acceptable. + */ + @NonNull + public Builder setSsid(@Nullable String ssid) { + mSsid = ssid; + return this; + } + + /** Build the VcnWifiUnderlyingNetworkPriority. */ + @NonNull + public VcnWifiUnderlyingNetworkPriority build() { + return new VcnWifiUnderlyingNetworkPriority(mNetworkQuality, mAllowMetered, mSsid); + } + + /** @hide */ + @Override + Builder self() { + return this; + } + } +} diff --git a/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkPriorityTest.java b/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkPriorityTest.java new file mode 100644 index 000000000000..69ffeadbffae --- /dev/null +++ b/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkPriorityTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2021 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.vcn; + +import static android.net.vcn.VcnUnderlyingNetworkPriority.NETWORK_QUALITY_ANY; +import static android.net.vcn.VcnUnderlyingNetworkPriority.NETWORK_QUALITY_OK; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.Test; + +public class VcnWifiUnderlyingNetworkPriorityTest { + private static final String SSID = "TestWifi"; + private static final int INVALID_NETWORK_QUALITY = -1; + + private static VcnWifiUnderlyingNetworkPriority getTestNetworkPriority() { + return new VcnWifiUnderlyingNetworkPriority.Builder() + .setNetworkQuality(NETWORK_QUALITY_OK) + .setAllowMetered(true /* allowMetered */) + .setSsid(SSID) + .build(); + } + + @Test + public void testBuilderAndGetters() { + final VcnWifiUnderlyingNetworkPriority networkPriority = getTestNetworkPriority(); + assertEquals(NETWORK_QUALITY_OK, networkPriority.getNetworkQuality()); + assertTrue(networkPriority.allowMetered()); + assertEquals(SSID, networkPriority.getSsid()); + } + + @Test + public void testBuilderAndGettersForDefaultValues() { + final VcnWifiUnderlyingNetworkPriority networkPriority = + new VcnWifiUnderlyingNetworkPriority.Builder().build(); + assertEquals(NETWORK_QUALITY_ANY, networkPriority.getNetworkQuality()); + assertFalse(networkPriority.allowMetered()); + assertNull(SSID, networkPriority.getSsid()); + } + + @Test + public void testBuildWithInvalidNetworkQuality() { + try { + new VcnWifiUnderlyingNetworkPriority.Builder() + .setNetworkQuality(INVALID_NETWORK_QUALITY); + fail("Expected to fail due to the invalid network quality"); + } catch (Exception expected) { + } + } + + @Test + public void testPersistableBundle() { + final VcnWifiUnderlyingNetworkPriority networkPriority = getTestNetworkPriority(); + assertEquals( + networkPriority, + VcnUnderlyingNetworkPriority.fromPersistableBundle( + networkPriority.toPersistableBundle())); + } +} |