Merge changes I2aedd1f1,I9bdf8d07
* changes:
gn2bp: Cancel -DANDROID if it's not specified
gn2bp: Added required include PATH
diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java
index 1f3fc11..c2cf92c 100644
--- a/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -477,17 +477,10 @@
wifiManager.registerSoftApCallback(mExecutor, softApCallback);
}
if (SdkLevel.isAtLeastT() && wifiManager != null) {
- try {
- // Although WifiManager#registerLocalOnlyHotspotSoftApCallback document that it need
- // NEARBY_WIFI_DEVICES permission, but actually a caller who have NETWORK_STACK
- // or MAINLINE_NETWORK_STACK permission would also able to use this API.
- wifiManager.registerLocalOnlyHotspotSoftApCallback(mExecutor, softApCallback);
- } catch (UnsupportedOperationException e) {
- // Since wifi module development in internal branch,
- // #registerLocalOnlyHotspotSoftApCallback currently doesn't supported in AOSP
- // before AOSP switch to Android T + 1.
- Log.wtf(TAG, "registerLocalOnlyHotspotSoftApCallback API is not supported");
- }
+ // Although WifiManager#registerLocalOnlyHotspotSoftApCallback document that it need
+ // NEARBY_WIFI_DEVICES permission, but actually a caller who have NETWORK_STACK
+ // or MAINLINE_NETWORK_STACK permission would also able to use this API.
+ wifiManager.registerLocalOnlyHotspotSoftApCallback(mExecutor, softApCallback);
}
startTrackDefaultNetwork();
diff --git a/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java b/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
index 8ef5d71..7ed4725 100644
--- a/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
+++ b/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
@@ -22,6 +22,7 @@
import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;
+import static android.provider.DeviceConfig.NAMESPACE_TETHERING;
import static com.android.net.module.util.DeviceConfigUtils.TETHERING_MODULE_NAME;
import static com.android.networkstack.apishim.ConstantsShim.KEY_CARRIER_SUPPORTS_TETHERING_BOOL;
@@ -194,7 +195,7 @@
isDunRequired = checkDunRequired(ctx);
final boolean forceAutomaticUpstream = !SdkLevel.isAtLeastS()
- && isFeatureEnabled(ctx, TETHER_FORCE_UPSTREAM_AUTOMATIC_VERSION);
+ && isConnectivityFeatureEnabled(ctx, TETHER_FORCE_UPSTREAM_AUTOMATIC_VERSION);
chooseUpstreamAutomatically = forceAutomaticUpstream || getResourceBoolean(
res, R.bool.config_tether_upstream_automatic, false /** defaultValue */);
preferredUpstreamIfaceTypes = getUpstreamIfaceTypes(res, isDunRequired);
@@ -565,9 +566,23 @@
return DeviceConfig.getProperty(NAMESPACE_CONNECTIVITY, name);
}
+ /**
+ * This is deprecated because connectivity namespace already be used for NetworkStack mainline
+ * module. Tethering should use its own namespace to roll out the feature flag.
+ * @deprecated new caller should use isTetheringFeatureEnabled instead.
+ */
+ @Deprecated
+ private boolean isConnectivityFeatureEnabled(Context ctx, String featureVersionFlag) {
+ return isFeatureEnabled(ctx, NAMESPACE_CONNECTIVITY, featureVersionFlag);
+ }
+
+ private boolean isTetheringFeatureEnabled(Context ctx, String featureVersionFlag) {
+ return isFeatureEnabled(ctx, NAMESPACE_TETHERING, featureVersionFlag);
+ }
+
@VisibleForTesting
- protected boolean isFeatureEnabled(Context ctx, String featureVersionFlag) {
- return DeviceConfigUtils.isFeatureEnabled(ctx, NAMESPACE_CONNECTIVITY, featureVersionFlag,
+ protected boolean isFeatureEnabled(Context ctx, String namespace, String featureVersionFlag) {
+ return DeviceConfigUtils.isFeatureEnabled(ctx, namespace, featureVersionFlag,
TETHERING_MODULE_NAME, false /* defaultEnabled */);
}
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/FakeTetheringConfiguration.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/FakeTetheringConfiguration.java
index 95ec38f..0d686ed 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/FakeTetheringConfiguration.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/FakeTetheringConfiguration.java
@@ -33,7 +33,7 @@
}
@Override
- protected boolean isFeatureEnabled(Context ctx, String featureVersionFlag) {
+ protected boolean isFeatureEnabled(Context ctx, String namespace, String featureVersionFlag) {
return false;
}
diff --git a/framework/api/module-lib-current.txt b/framework/api/module-lib-current.txt
index 073cca2..752c347 100644
--- a/framework/api/module-lib-current.txt
+++ b/framework/api/module-lib-current.txt
@@ -228,13 +228,9 @@
}
public final class VpnTransportInfo implements android.os.Parcelable android.net.TransportInfo {
- ctor public VpnTransportInfo(int, @Nullable String);
- method public int describeContents();
+ ctor @Deprecated public VpnTransportInfo(int, @Nullable String);
method @Nullable public String getSessionId();
- method public int getType();
method @NonNull public android.net.VpnTransportInfo makeCopy(long);
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.VpnTransportInfo> CREATOR;
}
}
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt
index 8b35197..c7872a0 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -511,6 +511,15 @@
field @NonNull public static final android.os.Parcelable.Creator<android.net.TcpKeepalivePacketData> CREATOR;
}
+ public final class VpnTransportInfo implements android.os.Parcelable android.net.TransportInfo {
+ ctor public VpnTransportInfo(int, @Nullable String, boolean);
+ method public int describeContents();
+ method public boolean getBypassable();
+ method public int getType();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.VpnTransportInfo> CREATOR;
+ }
+
}
package android.net.apf {
diff --git a/framework/src/android/net/VpnTransportInfo.java b/framework/src/android/net/VpnTransportInfo.java
index 4071c9a..ebad477 100644
--- a/framework/src/android/net/VpnTransportInfo.java
+++ b/framework/src/android/net/VpnTransportInfo.java
@@ -17,6 +17,7 @@
package android.net;
import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+import static android.annotation.SystemApi.Client.PRIVILEGED_APPS;
import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
import android.annotation.NonNull;
@@ -27,6 +28,10 @@
import android.os.Parcelable;
import android.text.TextUtils;
+import androidx.annotation.RequiresApi;
+
+import com.android.modules.utils.build.SdkLevel;
+
import java.util.Objects;
/**
@@ -37,7 +42,7 @@
*
* @hide
*/
-@SystemApi(client = MODULE_LIBRARIES)
+@SystemApi(client = PRIVILEGED_APPS)
public final class VpnTransportInfo implements TransportInfo, Parcelable {
/** Type of this VPN. */
private final int mType;
@@ -45,6 +50,13 @@
@Nullable
private final String mSessionId;
+ private final boolean mBypassable;
+
+ // TODO: Refer to Build.VERSION_CODES when it's available in every branch.
+ private static final int UPSIDE_DOWN_CAKE = 34;
+
+ /** @hide */
+ @SystemApi(client = MODULE_LIBRARIES)
@Override
public @RedactionType long getApplicableRedactions() {
return REDACT_FOR_NETWORK_SETTINGS;
@@ -52,21 +64,58 @@
/**
* Create a copy of a {@link VpnTransportInfo} with the sessionId redacted if necessary.
+ * @hide
*/
@NonNull
+ @SystemApi(client = MODULE_LIBRARIES)
public VpnTransportInfo makeCopy(@RedactionType long redactions) {
return new VpnTransportInfo(mType,
- ((redactions & REDACT_FOR_NETWORK_SETTINGS) != 0) ? null : mSessionId);
+ ((redactions & REDACT_FOR_NETWORK_SETTINGS) != 0) ? null : mSessionId, mBypassable);
}
+ /**
+ * @deprecated please use {@link VpnTransportInfo(int,String,boolean)} instead.
+ * @hide
+ */
+ @Deprecated
+ @SystemApi(client = MODULE_LIBRARIES)
public VpnTransportInfo(int type, @Nullable String sessionId) {
+ // When the module runs on older SDKs, |bypassable| will always be false since the old Vpn
+ // code will call this constructor. For Settings VPNs, this is always correct as they are
+ // never bypassable. For VpnManager and VpnService types, this may be wrong since both of
+ // them have a choice. However, on these SDKs VpnTransportInfo#getBypassable is not
+ // available anyway, so this should be harmless. False is a better choice than true here
+ // regardless because it is the default value for both VpnManager and VpnService if the app
+ // does not do anything about it.
+ this(type, sessionId, false /* bypassable */);
+ }
+
+ public VpnTransportInfo(int type, @Nullable String sessionId, boolean bypassable) {
this.mType = type;
this.mSessionId = sessionId;
+ this.mBypassable = bypassable;
+ }
+
+ /**
+ * Returns whether the VPN is allowing bypass.
+ *
+ * This method is not supported in SDK below U, and will throw
+ * {@code UnsupportedOperationException} if called.
+ */
+ @RequiresApi(UPSIDE_DOWN_CAKE)
+ public boolean getBypassable() {
+ if (!SdkLevel.isAtLeastU()) {
+ throw new UnsupportedOperationException("Not supported before U");
+ }
+
+ return mBypassable;
}
/**
* Returns the session Id of this VpnTransportInfo.
+ * @hide
*/
+ @SystemApi(client = MODULE_LIBRARIES)
@Nullable
public String getSessionId() {
return mSessionId;
@@ -84,17 +133,19 @@
if (!(o instanceof VpnTransportInfo)) return false;
VpnTransportInfo that = (VpnTransportInfo) o;
- return (this.mType == that.mType) && TextUtils.equals(this.mSessionId, that.mSessionId);
+ return (this.mType == that.mType) && TextUtils.equals(this.mSessionId, that.mSessionId)
+ && (this.mBypassable == that.mBypassable);
}
@Override
public int hashCode() {
- return Objects.hash(mType, mSessionId);
+ return Objects.hash(mType, mSessionId, mBypassable);
}
@Override
public String toString() {
- return String.format("VpnTransportInfo{type=%d, sessionId=%s}", mType, mSessionId);
+ return String.format("VpnTransportInfo{type=%d, sessionId=%s, bypassable=%b}",
+ mType, mSessionId, mBypassable);
}
@Override
@@ -106,12 +157,13 @@
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mType);
dest.writeString(mSessionId);
+ dest.writeBoolean(mBypassable);
}
public static final @NonNull Creator<VpnTransportInfo> CREATOR =
new Creator<VpnTransportInfo>() {
public VpnTransportInfo createFromParcel(Parcel in) {
- return new VpnTransportInfo(in.readInt(), in.readString());
+ return new VpnTransportInfo(in.readInt(), in.readString(), in.readBoolean());
}
public VpnTransportInfo[] newArray(int size) {
return new VpnTransportInfo[size];
diff --git a/service/Android.bp b/service/Android.bp
index 326f91b..691c1ad 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -178,7 +178,10 @@
"networkstack-client",
"PlatformProperties",
"service-connectivity-protos",
- "service-connectivity-stats-protos",
+ // TODO: Adding the stats protos currently affects test coverage.
+ // So remove the protos in ConnectivityService until all
+ // tests for proto apis are added.
+ //"service-connectivity-stats-protos",
"NetworkStackApiStableShims",
],
apex_available: [
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index fd219d2..f796ecc 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -2378,8 +2378,9 @@
super.expectAvailableCallbacks(network, false /* suspended */, true /* validated */,
BLOCKED_REASON_NONE, NETWORK_CALLBACK_TIMEOUT_MS);
}
- public void expectBlockedStatusCallback(Network network, int blockedStatus) {
- super.expectBlockedStatusCallback(blockedStatus, network, NETWORK_CALLBACK_TIMEOUT_MS);
+ public void eventuallyExpectBlockedStatusCallback(Network network, int blockedStatus) {
+ super.eventuallyExpect(CallbackEntry.BLOCKED_STATUS_INT, NETWORK_CALLBACK_TIMEOUT_MS,
+ (it) -> it.getNetwork().equals(network) && it.getBlocked() == blockedStatus);
}
public void onBlockedStatusChanged(Network network, int blockedReasons) {
getHistory().add(new CallbackEntry.BlockedStatusInt(network, blockedReasons));
@@ -2424,12 +2425,14 @@
final Range<Integer> otherUidRange = new Range<>(otherUid, otherUid);
setRequireVpnForUids(true, List.of(myUidRange));
- myUidCallback.expectBlockedStatusCallback(defaultNetwork, BLOCKED_REASON_LOCKDOWN_VPN);
+ myUidCallback.eventuallyExpectBlockedStatusCallback(defaultNetwork,
+ BLOCKED_REASON_LOCKDOWN_VPN);
otherUidCallback.assertNoBlockedStatusCallback();
setRequireVpnForUids(true, List.of(myUidRange, otherUidRange));
myUidCallback.assertNoBlockedStatusCallback();
- otherUidCallback.expectBlockedStatusCallback(defaultNetwork, BLOCKED_REASON_LOCKDOWN_VPN);
+ otherUidCallback.eventuallyExpectBlockedStatusCallback(defaultNetwork,
+ BLOCKED_REASON_LOCKDOWN_VPN);
// setRequireVpnForUids does no deduplication or refcounting. Removing myUidRange does not
// unblock myUid because it was added to the blocked ranges twice.
@@ -2438,8 +2441,8 @@
otherUidCallback.assertNoBlockedStatusCallback();
setRequireVpnForUids(false, List.of(myUidRange, otherUidRange));
- myUidCallback.expectBlockedStatusCallback(defaultNetwork, BLOCKED_REASON_NONE);
- otherUidCallback.expectBlockedStatusCallback(defaultNetwork, BLOCKED_REASON_NONE);
+ myUidCallback.eventuallyExpectBlockedStatusCallback(defaultNetwork, BLOCKED_REASON_NONE);
+ otherUidCallback.eventuallyExpectBlockedStatusCallback(defaultNetwork, BLOCKED_REASON_NONE);
myUidCallback.assertNoBlockedStatusCallback();
otherUidCallback.assertNoBlockedStatusCallback();
diff --git a/tests/cts/net/src/android/net/cts/TestUtils.java b/tests/cts/net/src/android/net/cts/TestUtils.java
index 001aa01..6180845 100644
--- a/tests/cts/net/src/android/net/cts/TestUtils.java
+++ b/tests/cts/net/src/android/net/cts/TestUtils.java
@@ -16,8 +16,6 @@
package android.net.cts;
-import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
-
import android.os.Build;
import com.android.modules.utils.build.SdkLevel;
@@ -37,11 +35,18 @@
}
/**
- * Whether to test T+ APIs. This requires a) that the test be running on an S+ device, and
+ * Whether to test T+ APIs. This requires a) that the test be running on an T+ device, and
* b) that the code be compiled against shims new enough to access these APIs.
*/
public static boolean shouldTestTApis() {
- // TODO: replace SC_V2 with Build.VERSION_CODES.S_V2 when it's available in mainline branch.
- return SdkLevel.isAtLeastT() && ConstantsShim.VERSION > SC_V2;
+ return SdkLevel.isAtLeastT() && ConstantsShim.VERSION > Build.VERSION_CODES.S_V2;
+ }
+
+ /**
+ * Whether to test U+ APIs. This requires a) that the test be running on an U+ device, and
+ * b) that the code be compiled against shims new enough to access these APIs.
+ */
+ public static boolean shouldTestUApis() {
+ return SdkLevel.isAtLeastU() && ConstantsShim.VERSION > Build.VERSION_CODES.TIRAMISU;
}
}
diff --git a/tests/unit/java/android/net/VpnTransportInfoTest.java b/tests/unit/java/android/net/VpnTransportInfoTest.java
index b4c7ac4..0510209 100644
--- a/tests/unit/java/android/net/VpnTransportInfoTest.java
+++ b/tests/unit/java/android/net/VpnTransportInfoTest.java
@@ -19,10 +19,13 @@
import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
import static android.net.NetworkCapabilities.REDACT_NONE;
+import static com.android.testutils.MiscAsserts.assertThrows;
import static com.android.testutils.ParcelUtils.assertParcelSane;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
import android.os.Build;
@@ -31,6 +34,7 @@
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRunner;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -38,36 +42,67 @@
@SmallTest
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
public class VpnTransportInfoTest {
+ @Rule
+ public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
@Test
public void testParceling() {
- VpnTransportInfo v = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, "12345");
- assertParcelSane(v, 2 /* fieldCount */);
+ final VpnTransportInfo v = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, "12345");
+ assertParcelSane(v, 3 /* fieldCount */);
+
+ final VpnTransportInfo v2 =
+ new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, "12345", true);
+ assertParcelSane(v2, 3 /* fieldCount */);
}
@Test
public void testEqualsAndHashCode() {
String session1 = "12345";
String session2 = "6789";
- VpnTransportInfo v11 = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, session1);
- VpnTransportInfo v12 = new VpnTransportInfo(VpnManager.TYPE_VPN_SERVICE, session1);
- VpnTransportInfo v13 = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, session1);
- VpnTransportInfo v14 = new VpnTransportInfo(VpnManager.TYPE_VPN_LEGACY, session1);
- VpnTransportInfo v15 = new VpnTransportInfo(VpnManager.TYPE_VPN_OEM, session1);
- VpnTransportInfo v21 = new VpnTransportInfo(VpnManager.TYPE_VPN_LEGACY, session2);
+ final VpnTransportInfo v11 = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, session1);
+ final VpnTransportInfo v12 = new VpnTransportInfo(VpnManager.TYPE_VPN_SERVICE, session1);
+ final VpnTransportInfo v13 = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, session1);
+ final VpnTransportInfo v14 = new VpnTransportInfo(VpnManager.TYPE_VPN_LEGACY, session1);
+ final VpnTransportInfo v15 = new VpnTransportInfo(VpnManager.TYPE_VPN_OEM, session1);
+ final VpnTransportInfo v16 = new VpnTransportInfo(VpnManager.TYPE_VPN_OEM, session1, true);
+ final VpnTransportInfo v17 = new VpnTransportInfo(VpnManager.TYPE_VPN_OEM, session1, true);
+ final VpnTransportInfo v21 = new VpnTransportInfo(VpnManager.TYPE_VPN_LEGACY, session2);
- VpnTransportInfo v31 = v11.makeCopy(REDACT_FOR_NETWORK_SETTINGS);
- VpnTransportInfo v32 = v13.makeCopy(REDACT_FOR_NETWORK_SETTINGS);
+ final VpnTransportInfo v31 = v11.makeCopy(REDACT_FOR_NETWORK_SETTINGS);
+ final VpnTransportInfo v32 = v13.makeCopy(REDACT_FOR_NETWORK_SETTINGS);
+ final VpnTransportInfo v33 = v16.makeCopy(REDACT_FOR_NETWORK_SETTINGS);
+ final VpnTransportInfo v34 = v17.makeCopy(REDACT_FOR_NETWORK_SETTINGS);
assertNotEquals(v11, v12);
assertNotEquals(v13, v14);
assertNotEquals(v14, v15);
assertNotEquals(v14, v21);
+ assertNotEquals(v15, v16);
assertEquals(v11, v13);
assertEquals(v31, v32);
+ assertEquals(v33, v34);
assertEquals(v11.hashCode(), v13.hashCode());
+ assertEquals(v16.hashCode(), v17.hashCode());
assertEquals(REDACT_FOR_NETWORK_SETTINGS, v32.getApplicableRedactions());
assertEquals(session1, v15.makeCopy(REDACT_NONE).getSessionId());
}
+
+ @DevSdkIgnoreRule.IgnoreAfter(Build.VERSION_CODES.TIRAMISU)
+ @Test
+ public void testGetBypassable_beforeU() {
+ final VpnTransportInfo v = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, "12345");
+ assertThrows(UnsupportedOperationException.class, () -> v.getBypassable());
+ }
+
+ @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
+ @Test
+ public void testGetBypassable_afterU() {
+ final VpnTransportInfo v = new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, "12345");
+ assertFalse(v.getBypassable());
+
+ final VpnTransportInfo v2 =
+ new VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, "12345", true);
+ assertTrue(v2.getBypassable());
+ }
}