diff options
212 files changed, 1907 insertions, 628 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java index 26010ef6d55c..bdab7d084a2a 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java @@ -545,7 +545,7 @@ public final class JobStore { out.attribute(null, "net-capabilities", Long.toString( BitUtils.packBits(network.getCapabilities()))); out.attribute(null, "net-unwanted-capabilities", Long.toString( - BitUtils.packBits(network.getUnwantedCapabilities()))); + BitUtils.packBits(network.getForbiddenCapabilities()))); out.attribute(null, "net-transport-types", Long.toString( BitUtils.packBits(network.getTransportTypes()))); @@ -968,22 +968,22 @@ public final class JobStore { String val; final String netCapabilities = parser.getAttributeValue(null, "net-capabilities"); - final String netUnwantedCapabilities = parser.getAttributeValue( + final String netforbiddenCapabilities = parser.getAttributeValue( null, "net-unwanted-capabilities"); final String netTransportTypes = parser.getAttributeValue(null, "net-transport-types"); if (netCapabilities != null && netTransportTypes != null) { final NetworkRequest.Builder builder = new NetworkRequest.Builder() .clearCapabilities(); - final long unwantedCapabilities = netUnwantedCapabilities != null - ? Long.parseLong(netUnwantedCapabilities) - : BitUtils.packBits(builder.build().getUnwantedCapabilities()); + final long forbiddenCapabilities = netforbiddenCapabilities != null + ? Long.parseLong(netforbiddenCapabilities) + : BitUtils.packBits(builder.build().getForbiddenCapabilities()); // We're okay throwing NFE here; caught by caller for (int capability : BitUtils.unpackBits(Long.parseLong(netCapabilities))) { builder.addCapability(capability); } - for (int unwantedCapability : BitUtils.unpackBits( - Long.parseLong(netUnwantedCapabilities))) { - builder.addUnwantedCapability(unwantedCapability); + for (int forbiddenCapability : BitUtils.unpackBits( + Long.parseLong(netforbiddenCapabilities))) { + builder.addForbiddenCapability(forbiddenCapability); } for (int transport : BitUtils.unpackBits(Long.parseLong(netTransportTypes))) { builder.addTransportType(transport); diff --git a/apex/media/Android.bp b/apex/media/Android.bp index 308741a6733d..a75f1aed4ade 100644 --- a/apex/media/Android.bp +++ b/apex/media/Android.bp @@ -24,3 +24,10 @@ package { // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_base_license"], } + +sdk { + name: "media-module-sdk", + java_sdk_libs: [ + "framework-media", + ], +} diff --git a/api/Android.bp b/api/Android.bp index 2df31ecb7715..5b2d97f11378 100644 --- a/api/Android.bp +++ b/api/Android.bp @@ -24,12 +24,17 @@ package { default_applicable_licenses: ["frameworks_base_license"], } +metalava_cmd = "$(location metalava)" +// Silence reflection warnings. See b/168689341 +metalava_cmd += " -J--add-opens=java.base/java.util=ALL-UNNAMED " +metalava_cmd += " --no-banner --format=v2 " + genrule { name: "current-api-xml", tools: ["metalava"], srcs: [":frameworks-base-api-current.txt"], out: ["current.api"], - cmd: "$(location metalava) --no-banner -convert2xmlnostrip $(in) $(out)", + cmd: metalava_cmd + "-convert2xmlnostrip $(in) $(out)", visibility: ["//visibility:public"], } @@ -52,7 +57,7 @@ genrule { ], out: ["current.txt"], tools: ["metalava"], - cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)", + cmd: metalava_cmd + "$(in) --api $(out)", dists: [ { targets: ["droidcore"], @@ -77,7 +82,7 @@ genrule { ], out: ["stdout.txt"], tools: ["metalava"], - cmd: "$(location metalava) --no-banner --format=v2 " + + cmd: metalava_cmd + "--check-compatibility:api:released $(location :android.api.public.latest) " + "--baseline:compatibility:released $(location :android-incompatibilities.api.public.latest) " + "$(location :frameworks-base-api-current.txt) " + @@ -126,7 +131,7 @@ genrule { ], out: ["removed.txt"], tools: ["metalava"], - cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)", + cmd: metalava_cmd + "$(in) --api $(out)", dists: [ { targets: ["droidcore"], @@ -157,7 +162,7 @@ genrule { ], out: ["system-current.txt"], tools: ["metalava"], - cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)", + cmd: metalava_cmd + "$(in) --api $(out)", dists: [ { targets: ["droidcore"], @@ -183,7 +188,7 @@ genrule { ], out: ["stdout.txt"], tools: ["metalava"], - cmd: "$(location metalava) --no-banner --format=v2 " + + cmd: metalava_cmd + "--check-compatibility:api:released $(location :android.api.system.latest) " + "--check-compatibility:base $(location :frameworks-base-api-current.txt) " + "--baseline:compatibility:released $(location :android-incompatibilities.api.system.latest) " + @@ -207,7 +212,7 @@ genrule { ], out: ["system-removed.txt"], tools: ["metalava"], - cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)", + cmd: metalava_cmd + "$(in) --api $(out)", dists: [ { targets: ["droidcore"], @@ -239,7 +244,7 @@ genrule { ], out: ["module-lib-current.txt"], tools: ["metalava"], - cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)", + cmd: metalava_cmd + "$(in) --api $(out)", dists: [ { targets: ["droidcore"], @@ -264,7 +269,7 @@ genrule { ], out: ["stdout.txt"], tools: ["metalava"], - cmd: "$(location metalava) --no-banner --format=v2 " + + cmd: metalava_cmd + "--check-compatibility:api:released $(location :android.api.module-lib.latest) " + // Note: having "public" be the base of module-lib is not perfect -- it should // ideally be a merged public+system), but this will help when migrating from @@ -291,7 +296,7 @@ genrule { ], out: ["module-lib-removed.txt"], tools: ["metalava"], - cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)", + cmd: metalava_cmd + "$(in) --api $(out)", dists: [ { targets: ["droidcore"], @@ -331,7 +336,7 @@ genrule { ], out: ["system-server-current.txt"], tools: ["metalava"], - cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)", + cmd: metalava_cmd + "$(in) --api $(out)", dists: [ { targets: ["droidcore"], @@ -354,7 +359,7 @@ genrule { ], out: ["system-server-removed.txt"], tools: ["metalava"], - cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)", + cmd: metalava_cmd + "$(in) --api $(out)", dists: [ { targets: ["droidcore"], diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 81b9428d162a..3b759a2f69d0 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -537,6 +537,10 @@ package android.content.pm { field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.ProviderInfoList> CREATOR; } + public final class SharedLibraryInfo implements android.os.Parcelable { + method @NonNull public java.util.List<java.lang.String> getAllCodePaths(); + } + public final class ShortcutInfo implements android.os.Parcelable { method public boolean isVisibleToPublisher(); } diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java index 3c20dcac8ca3..a74c663a9ce7 100644 --- a/core/java/android/bluetooth/le/ScanFilter.java +++ b/core/java/android/bluetooth/le/ScanFilter.java @@ -587,6 +587,10 @@ public final class ScanFilter implements Parcelable { * @throws IllegalArgumentException If the {@code deviceAddress} is invalid. */ public Builder setDeviceAddress(String deviceAddress) { + if (deviceAddress == null) { + mDeviceAddress = deviceAddress; + return this; + } return setDeviceAddress(deviceAddress, BluetoothDevice.ADDRESS_TYPE_PUBLIC); } diff --git a/core/java/android/content/pm/SharedLibraryInfo.java b/core/java/android/content/pm/SharedLibraryInfo.java index da2a3d885fc6..933a0c9ba341 100644 --- a/core/java/android/content/pm/SharedLibraryInfo.java +++ b/core/java/android/content/pm/SharedLibraryInfo.java @@ -20,6 +20,7 @@ import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; @@ -29,6 +30,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Objects; /** * This class provides information for a shared library. There are @@ -177,7 +179,8 @@ public final class SharedLibraryInfo implements Parcelable { * * @hide */ - public List<String> getAllCodePaths() { + @TestApi + public @NonNull List<String> getAllCodePaths() { if (getPath() != null) { // Builtin library. ArrayList<String> list = new ArrayList<>(); @@ -185,7 +188,7 @@ public final class SharedLibraryInfo implements Parcelable { return list; } else { // Static or dynamic library. - return mCodePaths; + return Objects.requireNonNull(mCodePaths); } } diff --git a/core/java/android/hardware/hdmi/OWNERS b/core/java/android/hardware/hdmi/OWNERS index 16c15e387bab..60d43fd077d0 100644 --- a/core/java/android/hardware/hdmi/OWNERS +++ b/core/java/android/hardware/hdmi/OWNERS @@ -4,3 +4,4 @@ include /services/core/java/com/android/server/display/OWNERS marvinramin@google.com nchalko@google.com +lcnathalie@google.com diff --git a/core/java/android/net/vcn/VcnConfig.java b/core/java/android/net/vcn/VcnConfig.java index d41c0b4fbdb3..caab15251f58 100644 --- a/core/java/android/net/vcn/VcnConfig.java +++ b/core/java/android/net/vcn/VcnConfig.java @@ -52,12 +52,17 @@ public final class VcnConfig implements Parcelable { private static final String GATEWAY_CONNECTION_CONFIGS_KEY = "mGatewayConnectionConfigs"; @NonNull private final Set<VcnGatewayConnectionConfig> mGatewayConnectionConfigs; + private static final String IS_TEST_MODE_PROFILE_KEY = "mIsTestModeProfile"; + private final boolean mIsTestModeProfile; + private VcnConfig( @NonNull String packageName, - @NonNull Set<VcnGatewayConnectionConfig> gatewayConnectionConfigs) { + @NonNull Set<VcnGatewayConnectionConfig> gatewayConnectionConfigs, + boolean isTestModeProfile) { mPackageName = packageName; mGatewayConnectionConfigs = Collections.unmodifiableSet(new ArraySet<>(gatewayConnectionConfigs)); + mIsTestModeProfile = isTestModeProfile; validate(); } @@ -77,6 +82,7 @@ public final class VcnConfig implements Parcelable { new ArraySet<>( PersistableBundleUtils.toList( gatewayConnectionConfigsBundle, VcnGatewayConnectionConfig::new)); + mIsTestModeProfile = in.getBoolean(IS_TEST_MODE_PROFILE_KEY); validate(); } @@ -104,6 +110,15 @@ public final class VcnConfig implements Parcelable { } /** + * Returns whether or not this VcnConfig is restricted to test networks. + * + * @hide + */ + public boolean isTestModeProfile() { + return mIsTestModeProfile; + } + + /** * Serializes this object to a PersistableBundle. * * @hide @@ -119,13 +134,14 @@ public final class VcnConfig implements Parcelable { new ArrayList<>(mGatewayConnectionConfigs), VcnGatewayConnectionConfig::toPersistableBundle); result.putPersistableBundle(GATEWAY_CONNECTION_CONFIGS_KEY, gatewayConnectionConfigsBundle); + result.putBoolean(IS_TEST_MODE_PROFILE_KEY, mIsTestModeProfile); return result; } @Override public int hashCode() { - return Objects.hash(mPackageName, mGatewayConnectionConfigs); + return Objects.hash(mPackageName, mGatewayConnectionConfigs, mIsTestModeProfile); } @Override @@ -136,7 +152,8 @@ public final class VcnConfig implements Parcelable { final VcnConfig rhs = (VcnConfig) other; return mPackageName.equals(rhs.mPackageName) - && mGatewayConnectionConfigs.equals(rhs.mGatewayConnectionConfigs); + && mGatewayConnectionConfigs.equals(rhs.mGatewayConnectionConfigs) + && mIsTestModeProfile == rhs.mIsTestModeProfile; } // Parcelable methods @@ -172,6 +189,8 @@ public final class VcnConfig implements Parcelable { @NonNull private final Set<VcnGatewayConnectionConfig> mGatewayConnectionConfigs = new ArraySet<>(); + private boolean mIsTestModeProfile = false; + public Builder(@NonNull Context context) { Objects.requireNonNull(context, "context was null"); @@ -207,13 +226,29 @@ public final class VcnConfig implements Parcelable { } /** + * Restricts this VcnConfig to matching with test networks (only). + * + * <p>This method is for testing only, and must not be used by apps. Calling {@link + * VcnManager#setVcnConfig(ParcelUuid, VcnConfig)} with a VcnConfig where test-network usage + * is enabled will require the MANAGE_TEST_NETWORKS permission. + * + * @return this {@link Builder} instance, for chaining + * @hide + */ + @NonNull + public Builder setIsTestModeProfile() { + mIsTestModeProfile = true; + return this; + } + + /** * Builds and validates the VcnConfig. * * @return an immutable VcnConfig instance */ @NonNull public VcnConfig build() { - return new VcnConfig(mPackageName, mGatewayConnectionConfigs); + return new VcnConfig(mPackageName, mGatewayConnectionConfigs, mIsTestModeProfile); } } } diff --git a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java index be308d01d98a..2df3e6c7ecd6 100644 --- a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java +++ b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java @@ -15,6 +15,8 @@ */ package android.net.vcn; +import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_MOBIKE; + import static com.android.internal.annotations.VisibleForTesting.Visibility; import android.annotation.IntDef; @@ -433,6 +435,8 @@ public final class VcnGatewayConnectionConfig { * distinguish between VcnGatewayConnectionConfigs configured on a single {@link * VcnConfig}. This will be used as the identifier in VcnStatusCallback invocations. * @param tunnelConnectionParams the IKE tunnel connection configuration + * @throws IllegalArgumentException if the provided IkeTunnelConnectionParams is not + * configured to support MOBIKE * @see IkeTunnelConnectionParams * @see VcnManager.VcnStatusCallback#onGatewayConnectionError */ @@ -441,6 +445,10 @@ public final class VcnGatewayConnectionConfig { @NonNull IkeTunnelConnectionParams tunnelConnectionParams) { Objects.requireNonNull(gatewayConnectionName, "gatewayConnectionName was null"); Objects.requireNonNull(tunnelConnectionParams, "tunnelConnectionParams was null"); + if (!tunnelConnectionParams.getIkeSessionParams().hasIkeOption(IKE_OPTION_MOBIKE)) { + throw new IllegalArgumentException( + "MOBIKE must be configured for the provided IkeSessionParams"); + } mGatewayConnectionName = gatewayConnectionName; mTunnelConnectionParams = tunnelConnectionParams; diff --git a/core/java/android/net/vcn/VcnTransportInfo.java b/core/java/android/net/vcn/VcnTransportInfo.java index 0e9ccf144c2e..1f1818420b56 100644 --- a/core/java/android/net/vcn/VcnTransportInfo.java +++ b/core/java/android/net/vcn/VcnTransportInfo.java @@ -16,23 +16,17 @@ package android.net.vcn; -import static android.net.NetworkCapabilities.REDACT_ALL; -import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS; +import static android.net.NetworkCapabilities.REDACT_NONE; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; -import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE; - import android.annotation.NonNull; import android.annotation.Nullable; -import android.net.NetworkCapabilities; import android.net.TransportInfo; import android.net.wifi.WifiInfo; import android.os.Parcel; import android.os.Parcelable; import android.telephony.SubscriptionManager; -import com.android.internal.annotations.VisibleForTesting; - import java.util.Objects; /** @@ -55,32 +49,17 @@ public class VcnTransportInfo implements TransportInfo, Parcelable { @Nullable private final WifiInfo mWifiInfo; private final int mSubId; - /** - * The redaction scheme to use when parcelling. - * - * <p>The TransportInfo/NetworkCapabilities redaction mechanisms rely on redaction being - * performed at parcelling time. This means that the redaction scheme must be stored for later - * use. - * - * <p>Since the redaction scheme itself is not parcelled, this field is listed as a transient. - * - * <p>Defaults to REDACT_ALL when constructed using public constructors, or creating from - * parcels. - */ - private final transient long mRedactions; - public VcnTransportInfo(@NonNull WifiInfo wifiInfo) { - this(wifiInfo, INVALID_SUBSCRIPTION_ID, REDACT_ALL); + this(wifiInfo, INVALID_SUBSCRIPTION_ID); } public VcnTransportInfo(int subId) { - this(null /* wifiInfo */, subId, REDACT_ALL); + this(null /* wifiInfo */, subId); } - private VcnTransportInfo(@Nullable WifiInfo wifiInfo, int subId, long redactions) { + private VcnTransportInfo(@Nullable WifiInfo wifiInfo, int subId) { mWifiInfo = wifiInfo; mSubId = subId; - mRedactions = redactions; } /** @@ -102,25 +81,14 @@ public class VcnTransportInfo implements TransportInfo, Parcelable { * SubscriptionManager#INVALID_SUBSCRIPTION_ID}. * * @return the Subscription ID if a cellular underlying Network is present, else {@link - * android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID}. + * android.telephony.SubscriptionManager#INVALID_SUBSCRIPTION_ID}. */ public int getSubId() { return mSubId; } - /** - * Gets the redaction scheme - * - * @hide - */ - @VisibleForTesting(visibility = PRIVATE) - public long getRedaction() { - return mRedactions; - } - @Override public int hashCode() { - // mRedactions not hashed, as it is a transient, for control of parcelling return Objects.hash(mWifiInfo, mSubId); } @@ -128,8 +96,6 @@ public class VcnTransportInfo implements TransportInfo, Parcelable { public boolean equals(Object o) { if (!(o instanceof VcnTransportInfo)) return false; final VcnTransportInfo that = (VcnTransportInfo) o; - - // mRedactions not compared, as it is a transient, for control of parcelling return Objects.equals(mWifiInfo, that.mWifiInfo) && mSubId == that.mSubId; } @@ -143,31 +109,19 @@ public class VcnTransportInfo implements TransportInfo, Parcelable { @NonNull public TransportInfo makeCopy(long redactions) { return new VcnTransportInfo( - mWifiInfo == null ? null : mWifiInfo.makeCopy(redactions), mSubId, redactions); + (mWifiInfo == null) ? null : mWifiInfo.makeCopy(redactions), mSubId); } @Override public long getApplicableRedactions() { - long redactions = REDACT_FOR_NETWORK_SETTINGS; - - // Add additional wifi redactions if necessary - if (mWifiInfo != null) { - redactions |= mWifiInfo.getApplicableRedactions(); - } - - return redactions; - } - - private boolean shouldParcelNetworkSettingsFields() { - return (mRedactions & NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS) == 0; + return (mWifiInfo == null) ? REDACT_NONE : mWifiInfo.getApplicableRedactions(); } /** {@inheritDoc} */ @Override public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeInt(shouldParcelNetworkSettingsFields() ? mSubId : INVALID_SUBSCRIPTION_ID); - dest.writeParcelable( - shouldParcelNetworkSettingsFields() ? (Parcelable) mWifiInfo : null, flags); + dest.writeInt(mSubId); + dest.writeParcelable(mWifiInfo, flags); } @Override @@ -181,17 +135,7 @@ public class VcnTransportInfo implements TransportInfo, Parcelable { public VcnTransportInfo createFromParcel(Parcel in) { final int subId = in.readInt(); final WifiInfo wifiInfo = in.readParcelable(null); - - // If all fields are their null values, return null TransportInfo to avoid - // leaking information about this being a VCN Network (instead of macro - // cellular, etc) - if (wifiInfo == null && subId == INVALID_SUBSCRIPTION_ID) { - return null; - } - - // Prevent further forwarding by redacting everything in future parcels from - // this VcnTransportInfo - return new VcnTransportInfo(wifiInfo, subId, REDACT_ALL); + return new VcnTransportInfo(wifiInfo, subId); } public VcnTransportInfo[] newArray(int size) { diff --git a/core/java/com/android/internal/os/BinderLatencyBuckets.java b/core/java/com/android/internal/os/BinderLatencyBuckets.java new file mode 100644 index 000000000000..bdee4ca8a6b8 --- /dev/null +++ b/core/java/com/android/internal/os/BinderLatencyBuckets.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2017 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 com.android.internal.os; + +import android.util.Slog; + +import com.android.internal.annotations.VisibleForTesting; + +import java.util.ArrayList; +import java.util.Collections; + +/** + * Generates the bucket thresholds (with a custom logarithmic scale) for a histogram to store + * latency samples in. + */ +public class BinderLatencyBuckets { + private static final String TAG = "BinderLatencyBuckets"; + private ArrayList<Integer> mBuckets; + + /** + * @param bucketCount the number of buckets the histogram should have + * @param firstBucketSize the size of the first bucket (used to avoid excessive small buckets) + * @param scaleFactor the rate in which each consecutive bucket increases (before rounding) + */ + public BinderLatencyBuckets(int bucketCount, int firstBucketSize, float scaleFactor) { + mBuckets = new ArrayList<>(bucketCount - 1); + mBuckets.add(firstBucketSize); + + // Last value and the target are disjoint as we never want to create buckets smaller than 1. + double lastTarget = firstBucketSize; + int lastValue = firstBucketSize; + + // First bucket is already created and the last bucket is anything greater than the final + // bucket in the list, so create 'bucketCount' - 2 buckets. + for (int i = 1; i < bucketCount - 1; i++) { + // Increase the target bucket limit value by the scale factor. + double nextTarget = lastTarget * scaleFactor; + + if (nextTarget > Integer.MAX_VALUE || lastValue == Integer.MAX_VALUE) { + // Do not throw an exception here as this should not affect binder calls. + Slog.w(TAG, "Attempted to create a bucket larger than maxint"); + return; + } + + if ((int) nextTarget > lastValue) { + // Convert the target bucket limit value to an integer. + mBuckets.add((int) nextTarget); + lastValue = (int) nextTarget; + } else { + // Avoid creating redundant buckets, so bucket size should be 1 at a minimum. + mBuckets.add(lastValue + 1); + lastValue = lastValue + 1; + } + lastTarget = nextTarget; + } + } + + /** Gets the bucket index to insert the provided sample in. */ + public int sampleToBucket(int sample) { + if (sample > mBuckets.get(mBuckets.size() - 1)) { + return mBuckets.size(); + } + + // Binary search returns the element index if it is contained in the list - in this case the + // correct bucket is the index after as we use [minValue, maxValue) for bucket boundaries. + // Otherwise, it returns (-(insertion point) - 1), where insertion point is the point where + // to insert the element so that the array remains sorted - in this case the bucket index + // is the insertion point. + int searchResult = Collections.binarySearch(mBuckets, sample); + return searchResult < 0 ? -(1 + searchResult) : searchResult + 1; + } + + @VisibleForTesting + public ArrayList<Integer> getBuckets() { + return mBuckets; + } +} diff --git a/core/java/com/android/internal/os/BinderLatencyObserver.java b/core/java/com/android/internal/os/BinderLatencyObserver.java index 92b495284de2..59cc66d79bce 100644 --- a/core/java/com/android/internal/os/BinderLatencyObserver.java +++ b/core/java/com/android/internal/os/BinderLatencyObserver.java @@ -26,7 +26,6 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.BinderInternal.CallSession; -import java.util.ArrayList; import java.util.Random; /** Collects statistics about Binder call latency per calling API and method. */ @@ -34,18 +33,25 @@ public class BinderLatencyObserver { private static final String TAG = "BinderLatencyObserver"; public static final int PERIODIC_SAMPLING_INTERVAL_DEFAULT = 10; - // This is not the final data structure - we will eventually store latency histograms instead of - // raw samples as it is much more memory / disk space efficient. - // TODO(b/179999191): change this to store the histogram. - // TODO(b/179999191): pre allocate the array size so we would not have to resize this. + // Histogram buckets parameters. + public static final int BUCKET_COUNT_DEFAULT = 100; + public static final int FIRST_BUCKET_SIZE_DEFAULT = 5; + public static final float BUCKET_SCALE_FACTOR_DEFAULT = 1.125f; + @GuardedBy("mLock") - private final ArrayMap<LatencyDims, ArrayList<Long>> mLatencySamples = new ArrayMap<>(); + private final ArrayMap<LatencyDims, int[]> mLatencyHistograms = new ArrayMap<>(); private final Object mLock = new Object(); // Sampling period to control how often to track CPU usage. 1 means all calls, 100 means ~1 out // of 100 requests. private int mPeriodicSamplingInterval = PERIODIC_SAMPLING_INTERVAL_DEFAULT; + + private int mBucketCount = BUCKET_COUNT_DEFAULT; + private int mFirstBucketSize = FIRST_BUCKET_SIZE_DEFAULT; + private float mBucketScaleFactor = BUCKET_SCALE_FACTOR_DEFAULT; + private final Random mRandom; + private BinderLatencyBuckets mLatencyBuckets; /** Injector for {@link BinderLatencyObserver}. */ public static class Injector { @@ -56,6 +62,8 @@ public class BinderLatencyObserver { public BinderLatencyObserver(Injector injector) { mRandom = injector.getRandomGenerator(); + mLatencyBuckets = new BinderLatencyBuckets( + mBucketCount, mFirstBucketSize, mBucketScaleFactor); } /** Should be called when a Binder call completes, will store latency data. */ @@ -67,12 +75,21 @@ public class BinderLatencyObserver { LatencyDims dims = new LatencyDims(s.binderClass, s.transactionCode); long callDuration = getElapsedRealtimeMicro() - s.timeStarted; + // Find the bucket this sample should go to. + int bucketIdx = mLatencyBuckets.sampleToBucket( + callDuration > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) callDuration); + synchronized (mLock) { - if (!mLatencySamples.containsKey(dims)) { - mLatencySamples.put(dims, new ArrayList<Long>()); + int[] buckets = mLatencyHistograms.get(dims); + if (buckets == null) { + buckets = new int[mBucketCount]; + mLatencyHistograms.put(dims, buckets); } - mLatencySamples.get(dims).add(callDuration); + // Increment the correct bucket. + if (buckets[bucketIdx] < Integer.MAX_VALUE) { + buckets[bucketIdx] += 1; + } } } @@ -100,10 +117,26 @@ public class BinderLatencyObserver { } } + /** Updates the histogram buckets parameters. */ + public void setHistogramBucketsParams( + int bucketCount, int firstBucketSize, float bucketScaleFactor) { + synchronized (mLock) { + if (bucketCount != mBucketCount || firstBucketSize != mFirstBucketSize + || bucketScaleFactor != mBucketScaleFactor) { + mBucketCount = bucketCount; + mFirstBucketSize = firstBucketSize; + mBucketScaleFactor = bucketScaleFactor; + mLatencyBuckets = new BinderLatencyBuckets( + mBucketCount, mFirstBucketSize, mBucketScaleFactor); + reset(); + } + } + } + /** Resets the sample collection. */ public void reset() { synchronized (mLock) { - mLatencySamples.clear(); + mLatencyHistograms.clear(); } } @@ -151,7 +184,7 @@ public class BinderLatencyObserver { } @VisibleForTesting - public ArrayMap<LatencyDims, ArrayList<Long>> getLatencySamples() { - return mLatencySamples; + public ArrayMap<LatencyDims, int[]> getLatencyHistograms() { + return mLatencyHistograms; } } diff --git a/core/jni/Android.bp b/core/jni/Android.bp index afd19b63bc71..382acc062d62 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -149,7 +149,6 @@ cc_library_shared { "android_os_VintfRuntimeInfo.cpp", "android_os_incremental_IncrementalManager.cpp", "android_net_LocalSocketImpl.cpp", - "android_net_NetworkUtils.cpp", "android_service_DataLoaderService.cpp", "android_util_AssetManager.cpp", "android_util_Binder.cpp", @@ -216,6 +215,7 @@ cc_library_shared { static_libs: [ "libasync_safe", + "libconnectivityframeworkutils", "libbinderthreadstateutils", "libdmabufinfo", "libgif", diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 357f427b428c..4a57448ed668 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -398,6 +398,8 @@ <protected-broadcast android:name="android.net.wifi.p2p.action.WIFI_P2P_PERSISTENT_GROUPS_CHANGED" /> <protected-broadcast android:name="android.net.conn.TETHER_STATE_CHANGED" /> <protected-broadcast android:name="android.net.conn.INET_CONDITION_ACTION" /> + <!-- This broadcast is no longer sent in S but it should stay protected to avoid third party + apps broadcasting this and confusing old system apps that may not have been updated. --> <protected-broadcast android:name="android.net.conn.NETWORK_CONDITIONS_MEASURED" /> <protected-broadcast android:name="android.net.ConnectivityService.action.PKT_CNT_SAMPLE_INTERVAL_ELAPSED" /> diff --git a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java index 1156120217aa..cec62164e57a 100644 --- a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java @@ -764,7 +764,7 @@ public class BinderCallsStatsTest { bcs.elapsedTime += 20; bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID); - assertEquals(1, bcs.getLatencyObserver().getLatencySamples().size()); + assertEquals(1, bcs.getLatencyObserver().getLatencyHistograms().size()); } @Test @@ -778,7 +778,7 @@ public class BinderCallsStatsTest { bcs.elapsedTime += 20; bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID); - assertEquals(0, bcs.getLatencyObserver().getLatencySamples().size()); + assertEquals(0, bcs.getLatencyObserver().getLatencyHistograms().size()); } class TestBinderCallsStats extends BinderCallsStats { diff --git a/core/tests/coretests/src/com/android/internal/os/BinderLatencyBucketsTest.java b/core/tests/coretests/src/com/android/internal/os/BinderLatencyBucketsTest.java new file mode 100644 index 000000000000..00443a967c79 --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/os/BinderLatencyBucketsTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2018 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 com.android.internal.os; + +import static com.google.common.truth.Truth.assertThat; + +import static org.junit.Assert.assertEquals; + +import android.platform.test.annotations.Presubmit; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@SmallTest +@RunWith(AndroidJUnit4.class) +@Presubmit +public class BinderLatencyBucketsTest { + @Test + public void testBucketThresholds() { + BinderLatencyBuckets latencyBuckets = new BinderLatencyBuckets(10, 2, 1.45f); + assertThat(latencyBuckets.getBuckets()) + .containsExactly(2, 3, 4, 6, 8, 12, 18, 26, 39) + .inOrder(); + } + + @Test + public void testSampleAssignment() { + BinderLatencyBuckets latencyBuckets = new BinderLatencyBuckets(10, 2, 1.45f); + assertEquals(0, latencyBuckets.sampleToBucket(0)); + assertEquals(0, latencyBuckets.sampleToBucket(1)); + assertEquals(1, latencyBuckets.sampleToBucket(2)); + assertEquals(2, latencyBuckets.sampleToBucket(3)); + assertEquals(3, latencyBuckets.sampleToBucket(4)); + assertEquals(5, latencyBuckets.sampleToBucket(9)); + assertEquals(6, latencyBuckets.sampleToBucket(13)); + assertEquals(7, latencyBuckets.sampleToBucket(25)); + assertEquals(9, latencyBuckets.sampleToBucket(100)); + } + + @Test + public void testMaxIntBuckets() { + BinderLatencyBuckets latencyBuckets = new BinderLatencyBuckets(5, Integer.MAX_VALUE / 2, 2); + assertThat(latencyBuckets.getBuckets()) + .containsExactly(Integer.MAX_VALUE / 2, Integer.MAX_VALUE - 1) + .inOrder(); + + assertEquals(0, latencyBuckets.sampleToBucket(0)); + assertEquals(0, latencyBuckets.sampleToBucket(Integer.MAX_VALUE / 2 - 1)); + assertEquals(1, latencyBuckets.sampleToBucket(Integer.MAX_VALUE - 2)); + assertEquals(2, latencyBuckets.sampleToBucket(Integer.MAX_VALUE)); + } +} diff --git a/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java b/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java index 36915a205ee0..f65fb9583d6c 100644 --- a/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java @@ -33,7 +33,6 @@ import com.android.internal.os.BinderLatencyObserver.LatencyDims; import org.junit.Test; import org.junit.runner.RunWith; -import java.util.ArrayList; import java.util.Arrays; import java.util.Random; @@ -44,6 +43,7 @@ public class BinderLatencyObserverTest { @Test public void testLatencyCollectionWithMultipleClasses() { TestBinderLatencyObserver blo = new TestBinderLatencyObserver(); + blo.setHistogramBucketsParams(5, 5, 1.125f); Binder binder = new Binder(); CallSession callSession = new CallSession(); @@ -51,20 +51,24 @@ public class BinderLatencyObserverTest { callSession.transactionCode = 1; blo.callEnded(callSession); blo.callEnded(callSession); + blo.callEnded(callSession); callSession.transactionCode = 2; blo.callEnded(callSession); + blo.callEnded(callSession); - ArrayMap<LatencyDims, ArrayList<Long>> latencySamples = blo.getLatencySamples(); - assertEquals(2, latencySamples.keySet().size()); - assertThat(latencySamples.get(new LatencyDims(binder.getClass(), 1))) - .containsExactlyElementsIn(Arrays.asList(1L, 2L)); - assertThat(latencySamples.get(new LatencyDims(binder.getClass(), 2))).containsExactly(3L); + ArrayMap<LatencyDims, int[]> latencyHistograms = blo.getLatencyHistograms(); + assertEquals(2, latencyHistograms.keySet().size()); + assertThat(latencyHistograms.get(new LatencyDims(binder.getClass(), 1))) + .asList().containsExactly(2, 0, 1, 0, 0).inOrder(); + assertThat(latencyHistograms.get(new LatencyDims(binder.getClass(), 2))) + .asList().containsExactly(0, 0, 0, 0, 2).inOrder(); } @Test public void testSampling() { TestBinderLatencyObserver blo = new TestBinderLatencyObserver(); blo.setSamplingInterval(2); + blo.setHistogramBucketsParams(5, 5, 1.125f); Binder binder = new Binder(); CallSession callSession = new CallSession(); @@ -74,17 +78,58 @@ public class BinderLatencyObserverTest { callSession.transactionCode = 2; blo.callEnded(callSession); - ArrayMap<LatencyDims, ArrayList<Long>> latencySamples = blo.getLatencySamples(); - assertEquals(1, latencySamples.size()); - LatencyDims dims = latencySamples.keySet().iterator().next(); + ArrayMap<LatencyDims, int[]> latencyHistograms = blo.getLatencyHistograms(); + assertEquals(1, latencyHistograms.size()); + LatencyDims dims = latencyHistograms.keySet().iterator().next(); assertEquals(binder.getClass(), dims.getBinderClass()); assertEquals(1, dims.getTransactionCode()); - ArrayList<Long> values = latencySamples.get(dims); - assertThat(values).containsExactly(1L); + assertThat(latencyHistograms.get(dims)).asList().containsExactly(1, 0, 0, 0, 0).inOrder(); + } + + @Test + public void testTooCallLengthOverflow() { + TestBinderLatencyObserver blo = new TestBinderLatencyObserver(); + blo.setElapsedTime(2L + (long) Integer.MAX_VALUE); + blo.setHistogramBucketsParams(5, 5, 1.125f); + + Binder binder = new Binder(); + CallSession callSession = new CallSession(); + callSession.binderClass = binder.getClass(); + callSession.transactionCode = 1; + blo.callEnded(callSession); + + // The long call should be capped to maxint (to not overflow) and placed in the last bucket. + assertThat(blo.getLatencyHistograms() + .get(new LatencyDims(binder.getClass(), 1))) + .asList().containsExactly(0, 0, 0, 0, 1) + .inOrder(); + } + + @Test + public void testHistogramBucketOverflow() { + TestBinderLatencyObserver blo = new TestBinderLatencyObserver(); + blo.setHistogramBucketsParams(3, 5, 1.125f); + + Binder binder = new Binder(); + CallSession callSession = new CallSession(); + callSession.binderClass = binder.getClass(); + callSession.transactionCode = 1; + blo.callEnded(callSession); + + LatencyDims dims = new LatencyDims(binder.getClass(), 1); + // Fill the buckets with maxint. + Arrays.fill(blo.getLatencyHistograms().get(dims), Integer.MAX_VALUE); + assertThat(blo.getLatencyHistograms().get(dims)) + .asList().containsExactly(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE); + // Try to add another sample. + blo.callEnded(callSession); + // Make sure the buckets don't overflow. + assertThat(blo.getLatencyHistograms().get(dims)) + .asList().containsExactly(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE); } public static class TestBinderLatencyObserver extends BinderLatencyObserver { - private long mElapsedTimeCallCount = 0; + private long mElapsedTime = 0; TestBinderLatencyObserver() { // Make random generator not random. @@ -104,7 +149,12 @@ public class BinderLatencyObserverTest { @Override protected long getElapsedRealtimeMicro() { - return ++mElapsedTimeCallCount; + mElapsedTime += 2; + return mElapsedTime; + } + + public void setElapsedTime(long time) { + mElapsedTime = time; } } } diff --git a/keystore/java/android/security/KeyStore2.java b/keystore/java/android/security/KeyStore2.java index df579bba9dc2..1034847b761b 100644 --- a/keystore/java/android/security/KeyStore2.java +++ b/keystore/java/android/security/KeyStore2.java @@ -19,6 +19,7 @@ package android.security; import android.annotation.NonNull; import android.compat.annotation.ChangeId; import android.compat.annotation.Disabled; +import android.os.Binder; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceSpecificException; @@ -140,6 +141,7 @@ public class KeyStore2 { if (mBinder == null || retryLookup) { mBinder = IKeystoreService.Stub.asInterface(ServiceManager .getService(KEYSTORE2_SERVICE_NAME)); + Binder.allowBlocking(mBinder.asBinder()); } return mBinder; } diff --git a/keystore/java/android/security/KeyStoreOperation.java b/keystore/java/android/security/KeyStoreOperation.java index a6552dddc630..e6c1ea827118 100644 --- a/keystore/java/android/security/KeyStoreOperation.java +++ b/keystore/java/android/security/KeyStoreOperation.java @@ -18,6 +18,7 @@ package android.security; import android.annotation.NonNull; import android.hardware.security.keymint.KeyParameter; +import android.os.Binder; import android.os.RemoteException; import android.os.ServiceSpecificException; import android.security.keymaster.KeymasterDefs; @@ -39,6 +40,7 @@ public class KeyStoreOperation { Long challenge, KeyParameter[] parameters ) { + Binder.allowBlocking(operation.asBinder()); this.mOperation = operation; this.mChallenge = challenge; this.mParameters = parameters; diff --git a/keystore/java/android/security/KeyStoreSecurityLevel.java b/keystore/java/android/security/KeyStoreSecurityLevel.java index d188b6525579..b85dd742cc49 100644 --- a/keystore/java/android/security/KeyStoreSecurityLevel.java +++ b/keystore/java/android/security/KeyStoreSecurityLevel.java @@ -19,6 +19,7 @@ package android.security; import android.annotation.NonNull; import android.app.compat.CompatChanges; import android.hardware.security.keymint.KeyParameter; +import android.os.Binder; import android.os.RemoteException; import android.os.ServiceSpecificException; import android.security.keystore.BackendBusyException; @@ -45,6 +46,7 @@ public class KeyStoreSecurityLevel { private final IKeystoreSecurityLevel mSecurityLevel; public KeyStoreSecurityLevel(IKeystoreSecurityLevel securityLevel) { + Binder.allowBlocking(securityLevel.asBinder()); this.mSecurityLevel = securityLevel; } diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java index 3e2fb94f0387..f3cfcf18dec1 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java @@ -41,6 +41,8 @@ import android.system.keystore2.KeyMetadata; import android.system.keystore2.ResponseCode; import android.util.Log; +import com.android.internal.annotations.VisibleForTesting; + import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; @@ -974,7 +976,6 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { } private Set<String> getUniqueAliases() { - try { final KeyDescriptor[] keys = mKeyStore.list( getTargetDomain(), @@ -987,7 +988,7 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { return aliases; } catch (android.security.KeyStoreException e) { Log.e(TAG, "Failed to list keystore entries.", e); - return null; + return new HashSet<>(); } } @@ -1099,6 +1100,17 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { return caAlias; } + /** + * Used by Tests to initialize with a fake KeyStore2. + * @hide + * @param keystore + */ + @VisibleForTesting + public void initForTesting(KeyStore2 keystore) { + mKeyStore = keystore; + mNamespace = KeyProperties.NAMESPACE_APPLICATION; + } + @Override public void engineStore(OutputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException { diff --git a/keystore/tests/Android.bp b/keystore/tests/Android.bp index 2315a8568c64..7de45233494b 100644 --- a/keystore/tests/Android.bp +++ b/keystore/tests/Android.bp @@ -28,6 +28,7 @@ android_test { static_libs: [ "androidx.test.rules", "hamcrest-library", + "mockito-target-minus-junit4", ], platform_apis: true, libs: ["android.test.runner"], diff --git a/keystore/tests/src/android/security/ParcelableKeyGenParameterSpecTest.java b/keystore/tests/src/android/security/ParcelableKeyGenParameterSpecTest.java index b7d72fce6eba..2ae61ab3b38d 100644 --- a/keystore/tests/src/android/security/ParcelableKeyGenParameterSpecTest.java +++ b/keystore/tests/src/android/security/ParcelableKeyGenParameterSpecTest.java @@ -43,7 +43,6 @@ public final class ParcelableKeyGenParameterSpecTest { static final String ALIAS = "keystore-alias"; static final String ANOTHER_ALIAS = "another-keystore-alias"; static final int KEY_PURPOSES = KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY; - static final int UID = 1230; static final int KEYSIZE = 2048; static final X500Principal SUBJECT = new X500Principal("CN=subject"); static final BigInteger SERIAL = new BigInteger("1234567890"); @@ -61,7 +60,7 @@ public final class ParcelableKeyGenParameterSpecTest { public static KeyGenParameterSpec configureDefaultSpec() { return new KeyGenParameterSpec.Builder(ALIAS, KEY_PURPOSES) - .setUid(UID) + .setNamespace(KeyProperties.NAMESPACE_WIFI) .setKeySize(KEYSIZE) .setCertificateSubject(SUBJECT) .setCertificateSerialNumber(SERIAL) @@ -88,10 +87,11 @@ public final class ParcelableKeyGenParameterSpecTest { .build(); } - public static void validateSpecValues(KeyGenParameterSpec spec, int uid, String alias) { + public static void validateSpecValues(KeyGenParameterSpec spec, + @KeyProperties.Namespace int namespace, String alias) { assertThat(spec.getKeystoreAlias(), is(alias)); assertThat(spec.getPurposes(), is(KEY_PURPOSES)); - assertThat(spec.getUid(), is(uid)); + assertThat(spec.getNamespace(), is(namespace)); assertThat(spec.getKeySize(), is(KEYSIZE)); assertThat(spec.getCertificateSubject(), is(SUBJECT)); assertThat(spec.getCertificateSerialNumber(), is(SERIAL)); @@ -134,7 +134,7 @@ public final class ParcelableKeyGenParameterSpecTest { Parcel parcel = parcelForReading(spec); ParcelableKeyGenParameterSpec fromParcel = ParcelableKeyGenParameterSpec.CREATOR.createFromParcel(parcel); - validateSpecValues(fromParcel.getSpec(), UID, ALIAS); + validateSpecValues(fromParcel.getSpec(), KeyProperties.NAMESPACE_WIFI, ALIAS); assertThat(parcel.dataAvail(), is(0)); } diff --git a/keystore/tests/src/android/security/keystore/KeyGenParameterSpecTest.java b/keystore/tests/src/android/security/keystore/KeyGenParameterSpecTest.java index b2edfd05d13f..ddbb1d8c097c 100644 --- a/keystore/tests/src/android/security/keystore/KeyGenParameterSpecTest.java +++ b/keystore/tests/src/android/security/keystore/KeyGenParameterSpecTest.java @@ -21,8 +21,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import android.security.ParcelableKeyGenParameterSpecTest; -import android.security.keystore.KeyGenParameterSpec; -import android.security.keystore.KeyProperties; import androidx.test.runner.AndroidJUnit4; @@ -41,7 +39,7 @@ public final class KeyGenParameterSpecTest { KeyGenParameterSpec copiedSpec = new KeyGenParameterSpec.Builder(spec).build(); ParcelableKeyGenParameterSpecTest.validateSpecValues( - copiedSpec, spec.getUid(), spec.getKeystoreAlias()); + copiedSpec, spec.getNamespace(), spec.getKeystoreAlias()); } @Test diff --git a/keystore/tests/src/android/security/keystore2/AndroidKeyStoreSpiTest.java b/keystore/tests/src/android/security/keystore2/AndroidKeyStoreSpiTest.java new file mode 100644 index 000000000000..1bd3069f483a --- /dev/null +++ b/keystore/tests/src/android/security/keystore2/AndroidKeyStoreSpiTest.java @@ -0,0 +1,55 @@ +/* + * 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.security.keystore2; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.anyLong; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.security.KeyStore2; +import android.security.KeyStoreException; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +public class AndroidKeyStoreSpiTest { + + @Mock + private KeyStore2 mKeystore2; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void testEngineAliasesReturnsEmptySetOnKeyStoreError() throws Exception { + when(mKeystore2.list(anyInt(), anyLong())) + .thenThrow(new KeyStoreException(6, "Some Error")); + AndroidKeyStoreSpi spi = new AndroidKeyStoreSpi(); + spi.initForTesting(mKeystore2); + + assertThat("Empty collection expected", !spi.engineAliases().hasMoreElements()); + + verify(mKeystore2).list(anyInt(), anyLong()); + } + +} diff --git a/packages/Connectivity/framework/Android.bp b/packages/Connectivity/framework/Android.bp index 017ff51f366d..657d5a3d2eae 100644 --- a/packages/Connectivity/framework/Android.bp +++ b/packages/Connectivity/framework/Android.bp @@ -25,6 +25,7 @@ package { java_library { name: "framework-connectivity-protos", + sdk_version: "module_current", proto: { type: "nano", }, @@ -82,8 +83,7 @@ java_sdk_library { name: "framework-connectivity", api_only: true, defaults: ["framework-module-defaults"], - // TODO: build against module API - platform_apis: true, + installable: true, srcs: [ ":framework-connectivity-sources", ], @@ -100,18 +100,56 @@ java_sdk_library { libs: [ "unsupportedappusage", ], - permitted_packages: ["android.net", "com.android.connectivity.aidl"], + permitted_packages: ["android.net"], +} + +cc_defaults { + name: "libframework-connectivity-defaults", + cflags: [ + "-Wall", + "-Werror", + "-Wno-unused-parameter", + "-Wthread-safety", + ], + shared_libs: [ + "libbase", + "liblog", + "libnativehelper", + "libnetd_client", + ], + header_libs: [ + "dnsproxyd_protocol_headers", + ], +} + +cc_library_static { + name: "libconnectivityframeworkutils", + defaults: ["libframework-connectivity-defaults"], + srcs: [ + "jni/android_net_NetworkUtils.cpp", + ], + apex_available: [ + "//apex_available:platform", + "com.android.tethering", + ], +} + +cc_library_shared { + name: "libframework-connectivity-jni", + defaults: ["libframework-connectivity-defaults"], + srcs: [ + "jni/onload.cpp", + ], + static_libs: ["libconnectivityframeworkutils"], + apex_available: [ + "//apex_available:platform", + "com.android.tethering", + ], } java_library { name: "framework-connectivity.impl", - // Instead of building against private API (framework.jar), - // build against core_platform + framework-minus-apex + module - // stub libs. This allows framework.jar to depend on this library, - // so it can be part of the private API until all clients have been migrated. - // TODO: just build against module_api, and remove this jar from - // the private API. - sdk_version: "core_platform", + sdk_version: "module_current", srcs: [ ":framework-connectivity-sources", ], @@ -122,12 +160,11 @@ java_library { ], }, libs: [ - "framework-minus-apex", - // TODO: just framework-tethering, framework-wifi when building against module_api - "framework-tethering.stubs.module_lib", - "framework-wifi.stubs.module_lib", + // TODO (b/183097033) remove once module_current includes core_current + "stable.core.platform.api.stubs", + "framework-tethering", + "framework-wifi", "unsupportedappusage", - "ServiceConnectivityResources", ], static_libs: [ "framework-connectivity-protos", @@ -136,5 +173,5 @@ java_library { jarjar_rules: "jarjar-rules.txt", apex_available: ["com.android.tethering"], installable: true, - permitted_packages: ["android.net", "com.android.connectivity.aidl"], + permitted_packages: ["android.net"], } diff --git a/packages/Connectivity/framework/api/module-lib-current.txt b/packages/Connectivity/framework/api/module-lib-current.txt index a8e2517a5e90..b219375aed70 100644 --- a/packages/Connectivity/framework/api/module-lib-current.txt +++ b/packages/Connectivity/framework/api/module-lib-current.txt @@ -10,7 +10,6 @@ package android.net { method @NonNull @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public java.util.List<android.net.NetworkStateSnapshot> getAllNetworkStateSnapshots(); method @Nullable public android.net.ProxyInfo getGlobalProxy(); method @NonNull public static android.util.Range<java.lang.Integer> getIpSecNetIdRange(); - method @NonNull public static String getPrivateDnsMode(@NonNull android.content.Context); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerDefaultNetworkCallbackForUid(int, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerSystemDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler); method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void requestBackgroundNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler); @@ -20,7 +19,6 @@ package android.net { method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setAvoidUnvalidated(@NonNull android.net.Network); method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setGlobalProxy(@Nullable android.net.ProxyInfo); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void setLegacyLockdownVpnEnabled(boolean); - method public static void setPrivateDnsMode(@NonNull android.content.Context, @NonNull String); method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setProfileNetworkPreference(@NonNull android.os.UserHandle, int, @Nullable java.util.concurrent.Executor, @Nullable Runnable); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void setRequireVpnForUids(boolean, @NonNull java.util.Collection<android.util.Range<java.lang.Integer>>); method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_TEST_NETWORKS, android.Manifest.permission.NETWORK_STACK}) public void simulateDataStall(int, long, @NonNull android.net.Network, @NonNull android.os.PersistableBundle); @@ -40,9 +38,6 @@ package android.net { field public static final int BLOCKED_REASON_LOCKDOWN_VPN = 16; // 0x10 field public static final int BLOCKED_REASON_NONE = 0; // 0x0 field public static final int BLOCKED_REASON_RESTRICTED_MODE = 8; // 0x8 - field public static final String PRIVATE_DNS_MODE_OFF = "off"; - field public static final String PRIVATE_DNS_MODE_OPPORTUNISTIC = "opportunistic"; - field public static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = "hostname"; field public static final int PROFILE_NETWORK_PREFERENCE_DEFAULT = 0; // 0x0 field public static final int PROFILE_NETWORK_PREFERENCE_ENTERPRISE = 1; // 0x1 } @@ -62,13 +57,15 @@ package android.net { method @Nullable public static android.net.ProxyInfo getGlobalProxy(@NonNull android.content.Context); method @NonNull public static java.time.Duration getMobileDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration); method public static boolean getMobileDataAlwaysOn(@NonNull android.content.Context, boolean); - method @Nullable public static String getMobileDataPreferredApps(@NonNull android.content.Context); + method @NonNull public static java.util.Set<java.lang.Integer> getMobileDataPreferredUids(@NonNull android.content.Context); method public static int getNetworkAvoidBadWifi(@NonNull android.content.Context); method @Nullable public static String getNetworkMeteredMultipathPreference(@NonNull android.content.Context); method public static int getNetworkSwitchNotificationMaximumDailyCount(@NonNull android.content.Context, int); method @NonNull public static java.time.Duration getNetworkSwitchNotificationRateDuration(@NonNull android.content.Context, @NonNull java.time.Duration); method @NonNull public static String getPrivateDnsDefaultMode(@NonNull android.content.Context); method @Nullable public static String getPrivateDnsHostname(@NonNull android.content.Context); + method public static int getPrivateDnsMode(@NonNull android.content.Context); + method @NonNull public static java.util.Set<java.lang.String> getRestrictedAllowedApps(@NonNull android.content.Context); method public static boolean getWifiAlwaysRequested(@NonNull android.content.Context, boolean); method @NonNull public static java.time.Duration getWifiDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration); method public static void setCaptivePortalHttpUrl(@NonNull android.content.Context, @Nullable String); @@ -80,13 +77,15 @@ package android.net { method public static void setGlobalProxy(@NonNull android.content.Context, @NonNull android.net.ProxyInfo); method public static void setMobileDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration); method public static void setMobileDataAlwaysOn(@NonNull android.content.Context, boolean); - method public static void setMobileDataPreferredApps(@NonNull android.content.Context, @Nullable String); + method public static void setMobileDataPreferredUids(@NonNull android.content.Context, @NonNull java.util.Set<java.lang.Integer>); method public static void setNetworkAvoidBadWifi(@NonNull android.content.Context, int); method public static void setNetworkMeteredMultipathPreference(@NonNull android.content.Context, @NonNull String); method public static void setNetworkSwitchNotificationMaximumDailyCount(@NonNull android.content.Context, @IntRange(from=0) int); method public static void setNetworkSwitchNotificationRateDuration(@NonNull android.content.Context, @NonNull java.time.Duration); - method public static void setPrivateDnsDefaultMode(@NonNull android.content.Context, @NonNull String); + method public static void setPrivateDnsDefaultMode(@NonNull android.content.Context, @NonNull int); method public static void setPrivateDnsHostname(@NonNull android.content.Context, @Nullable String); + method public static void setPrivateDnsMode(@NonNull android.content.Context, int); + method public static void setRestrictedAllowedApps(@NonNull android.content.Context, @NonNull java.util.Set<java.lang.String>); method public static void setWifiAlwaysRequested(@NonNull android.content.Context, boolean); method public static void setWifiDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration); field public static final int CAPTIVE_PORTAL_MODE_AVOID = 2; // 0x2 @@ -95,6 +94,9 @@ package android.net { field public static final int NETWORK_AVOID_BAD_WIFI_AVOID = 2; // 0x2 field public static final int NETWORK_AVOID_BAD_WIFI_IGNORE = 0; // 0x0 field public static final int NETWORK_AVOID_BAD_WIFI_PROMPT = 1; // 0x1 + field public static final int PRIVATE_DNS_MODE_OFF = 1; // 0x1 + field public static final int PRIVATE_DNS_MODE_OPPORTUNISTIC = 2; // 0x2 + field public static final int PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = 3; // 0x3 } public final class NetworkAgentConfig implements android.os.Parcelable { @@ -109,7 +111,7 @@ package android.net { public final class NetworkCapabilities implements android.os.Parcelable { method @Nullable public java.util.Set<android.util.Range<java.lang.Integer>> getUids(); - method public boolean hasUnwantedCapability(int); + method public boolean hasForbiddenCapability(int); field public static final long REDACT_ALL = -1L; // 0xffffffffffffffffL field public static final long REDACT_FOR_ACCESS_FINE_LOCATION = 1L; // 0x1L field public static final long REDACT_FOR_LOCAL_MAC_ADDRESS = 2L; // 0x2L @@ -123,13 +125,13 @@ package android.net { } public class NetworkRequest implements android.os.Parcelable { - method @NonNull public int[] getUnwantedCapabilities(); - method public boolean hasUnwantedCapability(int); + method @NonNull public int[] getForbiddenCapabilities(); + method public boolean hasForbiddenCapability(int); } public static class NetworkRequest.Builder { - method @NonNull public android.net.NetworkRequest.Builder addUnwantedCapability(int); - method @NonNull public android.net.NetworkRequest.Builder removeUnwantedCapability(int); + method @NonNull public android.net.NetworkRequest.Builder addForbiddenCapability(int); + method @NonNull public android.net.NetworkRequest.Builder removeForbiddenCapability(int); method @NonNull public android.net.NetworkRequest.Builder setUids(@Nullable java.util.Set<android.util.Range<java.lang.Integer>>); } diff --git a/core/jni/android_net_NetworkUtils.cpp b/packages/Connectivity/framework/jni/android_net_NetworkUtils.cpp index 1cee8955a7a2..48e262a6b19b 100644 --- a/core/jni/android_net_NetworkUtils.cpp +++ b/packages/Connectivity/framework/jni/android_net_NetworkUtils.cpp @@ -30,13 +30,13 @@ #include <DnsProxydProtocol.h> // NETID_USE_LOCAL_NAMESERVERS #include <cutils/properties.h> +#include <nativehelper/JNIHelp.h> #include <nativehelper/JNIPlatformHelp.h> #include <nativehelper/ScopedLocalRef.h> #include <utils/Log.h> #include <utils/misc.h> #include "NetdClient.h" -#include "core_jni_helpers.h" #include "jni.h" extern "C" { @@ -52,6 +52,19 @@ constexpr int MAXPACKETSIZE = 8 * 1024; // FrameworkListener limits the size of commands to 4096 bytes. constexpr int MAXCMDSIZE = 4096; +static inline jclass FindClassOrDie(JNIEnv* env, const char* class_name) { + jclass clazz = env->FindClass(class_name); + LOG_ALWAYS_FATAL_IF(clazz == NULL, "Unable to find class %s", class_name); + return clazz; +} + +template <typename T> +static inline T MakeGlobalRefOrDie(JNIEnv* env, T in) { + jobject res = env->NewGlobalRef(in); + LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to create global reference."); + return static_cast<T>(res); +} + static void android_net_utils_attachDropAllBPFFilter(JNIEnv *env, jobject clazz, jobject javaFd) { struct sock_filter filter_code[] = { @@ -254,8 +267,8 @@ static const JNINativeMethod gNetworkUtilMethods[] = { int register_android_net_NetworkUtils(JNIEnv* env) { - return RegisterMethodsOrDie(env, NETUTILS_PKG_NAME, gNetworkUtilMethods, - NELEM(gNetworkUtilMethods)); + return jniRegisterNativeMethods(env, NETUTILS_PKG_NAME, gNetworkUtilMethods, + NELEM(gNetworkUtilMethods)); } }; // namespace android diff --git a/packages/Connectivity/framework/jni/onload.cpp b/packages/Connectivity/framework/jni/onload.cpp new file mode 100644 index 000000000000..435f4343ed14 --- /dev/null +++ b/packages/Connectivity/framework/jni/onload.cpp @@ -0,0 +1,38 @@ +/* + * 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. + */ + +#include <nativehelper/JNIHelp.h> +#include <log/log.h> + +namespace android { + +int register_android_net_NetworkUtils(JNIEnv* env); + +extern "C" jint JNI_OnLoad(JavaVM* vm, void*) { + JNIEnv *env; + if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { + ALOGE("GetEnv failed"); + return JNI_ERR; + } + + if (register_android_net_NetworkUtils(env) < 0) { + return JNI_ERR; + } + + return JNI_VERSION_1_6; +} + +};
\ No newline at end of file diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java index 19764dd896b1..1a6b37bfdb42 100644 --- a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java +++ b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java @@ -16,8 +16,6 @@ package android.net; import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; -import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_DEFAULT_MODE; -import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE; import static android.net.NetworkRequest.Type.BACKGROUND_REQUEST; import static android.net.NetworkRequest.Type.LISTEN; import static android.net.NetworkRequest.Type.LISTEN_FOR_BEST; @@ -33,7 +31,6 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; -import android.annotation.StringDef; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; @@ -41,7 +38,6 @@ import android.app.PendingIntent; import android.app.admin.DevicePolicyManager; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; -import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.net.ConnectivityDiagnosticsManager.DataStallReport.DetectionMethod; @@ -70,7 +66,6 @@ import android.os.UserHandle; import android.provider.Settings; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; -import android.text.TextUtils; import android.util.ArrayMap; import android.util.Log; import android.util.Range; @@ -821,38 +816,6 @@ public class ConnectivityManager { public static final int NETID_UNSET = 0; /** - * Private DNS Mode values. - * - * The "private_dns_mode" global setting stores a String value which is - * expected to be one of the following. - */ - - /** - * @hide - */ - @SystemApi(client = MODULE_LIBRARIES) - public static final String PRIVATE_DNS_MODE_OFF = "off"; - /** - * @hide - */ - @SystemApi(client = MODULE_LIBRARIES) - public static final String PRIVATE_DNS_MODE_OPPORTUNISTIC = "opportunistic"; - /** - * @hide - */ - @SystemApi(client = MODULE_LIBRARIES) - public static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = "hostname"; - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @StringDef(value = { - PRIVATE_DNS_MODE_OFF, - PRIVATE_DNS_MODE_OPPORTUNISTIC, - PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, - }) - public @interface PrivateDnsMode {} - - /** * Flag to indicate that an app is not subject to any restrictions that could result in its * network access blocked. * @@ -3374,7 +3337,60 @@ public class ConnectivityManager { provider.setProviderId(NetworkProvider.ID_NONE); } + /** + * Register or update a network offer with ConnectivityService. + * + * ConnectivityService keeps track of offers made by the various providers and matches + * them to networking requests made by apps or the system. The provider supplies a score + * and the capabilities of the network it might be able to bring up ; these act as filters + * used by ConnectivityService to only send those requests that can be fulfilled by the + * provider. + * + * The provider is under no obligation to be able to bring up the network it offers at any + * given time. Instead, this mechanism is meant to limit requests received by providers + * to those they actually have a chance to fulfill, as providers don't have a way to compare + * the quality of the network satisfying a given request to their own offer. + * + * An offer can be updated by calling this again with the same callback object. This is + * similar to calling unofferNetwork and offerNetwork again, but will only update the + * provider with the changes caused by the changes in the offer. + * + * @param provider The provider making this offer. + * @param score The prospective score of the network. + * @param caps The prospective capabilities of the network. + * @param callback The callback to call when this offer is needed or unneeded. + * @hide + */ + @RequiresPermission(anyOf = { + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, + android.Manifest.permission.NETWORK_FACTORY}) + public void offerNetwork(@NonNull final NetworkProvider provider, + @NonNull final NetworkScore score, @NonNull final NetworkCapabilities caps, + @NonNull final INetworkOfferCallback callback) { + try { + mService.offerNetwork(Objects.requireNonNull(provider.getMessenger(), "null messenger"), + Objects.requireNonNull(score, "null score"), + Objects.requireNonNull(caps, "null caps"), + Objects.requireNonNull(callback, "null callback")); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** + * Withdraw a network offer made with {@link #offerNetwork}. + * + * @param callback The callback passed at registration time. This must be the same object + * that was passed to {@link #offerNetwork} + * @hide + */ + public void unofferNetwork(@NonNull final INetworkOfferCallback callback) { + try { + mService.unofferNetwork(Objects.requireNonNull(callback)); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } /** @hide exposed via the NetworkProvider class. */ @RequiresPermission(anyOf = { NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, @@ -5448,44 +5464,4 @@ public class ConnectivityManager { public static Range<Integer> getIpSecNetIdRange() { return new Range(TUN_INTF_NETID_START, TUN_INTF_NETID_START + TUN_INTF_NETID_RANGE - 1); } - - /** - * Get private DNS mode from settings. - * - * @param context The Context to query the private DNS mode from settings. - * @return A string of private DNS mode as one of the PRIVATE_DNS_MODE_* constants. - * - * @hide - */ - @SystemApi(client = MODULE_LIBRARIES) - @NonNull - @PrivateDnsMode - public static String getPrivateDnsMode(@NonNull Context context) { - final ContentResolver cr = context.getContentResolver(); - String mode = Settings.Global.getString(cr, PRIVATE_DNS_MODE); - if (TextUtils.isEmpty(mode)) mode = Settings.Global.getString(cr, PRIVATE_DNS_DEFAULT_MODE); - // If both PRIVATE_DNS_MODE and PRIVATE_DNS_DEFAULT_MODE are not set, choose - // PRIVATE_DNS_MODE_OPPORTUNISTIC as default mode. - if (TextUtils.isEmpty(mode)) mode = PRIVATE_DNS_MODE_OPPORTUNISTIC; - return mode; - } - - /** - * Set private DNS mode to settings. - * - * @param context The {@link Context} to set the private DNS mode. - * @param mode The private dns mode. This should be one of the PRIVATE_DNS_MODE_* constants. - * - * @hide - */ - @SystemApi(client = MODULE_LIBRARIES) - public static void setPrivateDnsMode(@NonNull Context context, - @NonNull @PrivateDnsMode String mode) { - if (!(mode == PRIVATE_DNS_MODE_OFF - || mode == PRIVATE_DNS_MODE_OPPORTUNISTIC - || mode == PRIVATE_DNS_MODE_PROVIDER_HOSTNAME)) { - throw new IllegalArgumentException("Invalid private dns mode"); - } - Settings.Global.putString(context.getContentResolver(), PRIVATE_DNS_MODE, mode); - } } diff --git a/packages/Connectivity/framework/src/android/net/ConnectivitySettingsManager.java b/packages/Connectivity/framework/src/android/net/ConnectivitySettingsManager.java index 9a00055e0079..07754e4af2ff 100644 --- a/packages/Connectivity/framework/src/android/net/ConnectivitySettingsManager.java +++ b/packages/Connectivity/framework/src/android/net/ConnectivitySettingsManager.java @@ -19,20 +19,20 @@ package android.net; import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_HANDOVER; import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_PERFORMANCE; import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_RELIABILITY; -import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF; -import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; -import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.content.ContentResolver; import android.content.Context; import android.net.ConnectivityManager.MultipathPreference; -import android.net.ConnectivityManager.PrivateDnsMode; +import android.os.Process; +import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; +import android.util.ArraySet; import android.util.Range; import com.android.net.module.util.ProxyUtils; @@ -41,6 +41,9 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.time.Duration; import java.util.List; +import java.util.Set; +import java.util.StringJoiner; +import java.util.regex.Pattern; /** * A manager class for connectivity module settings. @@ -333,12 +336,50 @@ public class ConnectivitySettingsManager { "network_metered_multipath_preference"; /** - * A list of apps that should go on cellular networks in preference even when higher-priority + * A list of uids that should go on cellular networks in preference even when higher-priority * networks are connected. * * @hide */ - public static final String MOBILE_DATA_PREFERRED_APPS = "mobile_data_preferred_apps"; + public static final String MOBILE_DATA_PREFERRED_UIDS = "mobile_data_preferred_uids"; + + /** + * One of the private DNS modes that indicates the private DNS mode is off. + */ + public static final int PRIVATE_DNS_MODE_OFF = 1; + + /** + * One of the private DNS modes that indicates the private DNS mode is automatic, which + * will try to use the current DNS as private DNS. + */ + public static final int PRIVATE_DNS_MODE_OPPORTUNISTIC = 2; + + /** + * One of the private DNS modes that indicates the private DNS mode is strict and the + * {@link #PRIVATE_DNS_SPECIFIER} is required, which will try to use the value of + * {@link #PRIVATE_DNS_SPECIFIER} as private DNS. + */ + public static final int PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = 3; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(value = { + PRIVATE_DNS_MODE_OFF, + PRIVATE_DNS_MODE_OPPORTUNISTIC, + PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, + }) + public @interface PrivateDnsMode {} + + private static final String PRIVATE_DNS_MODE_OFF_STRING = "off"; + private static final String PRIVATE_DNS_MODE_OPPORTUNISTIC_STRING = "opportunistic"; + private static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME_STRING = "hostname"; + + /** + * A list of apps that should be granted netd system permission for using restricted networks. + * + * @hide + */ + public static final String RESTRICTED_ALLOWED_APPS = "restricted_allowed_apps"; /** * Get mobile data activity timeout from {@link Settings}. @@ -689,6 +730,65 @@ public class ConnectivitySettingsManager { context.getContentResolver(), GLOBAL_HTTP_PROXY_PAC, "" /* value */); } + private static String getPrivateDnsModeAsString(@PrivateDnsMode int mode) { + switch (mode) { + case PRIVATE_DNS_MODE_OFF: + return PRIVATE_DNS_MODE_OFF_STRING; + case PRIVATE_DNS_MODE_OPPORTUNISTIC: + return PRIVATE_DNS_MODE_OPPORTUNISTIC_STRING; + case PRIVATE_DNS_MODE_PROVIDER_HOSTNAME: + return PRIVATE_DNS_MODE_PROVIDER_HOSTNAME_STRING; + default: + throw new IllegalArgumentException("Invalid private dns mode: " + mode); + } + } + + private static int getPrivateDnsModeAsInt(String mode) { + switch (mode) { + case "off": + return PRIVATE_DNS_MODE_OFF; + case "hostname": + return PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; + case "opportunistic": + return PRIVATE_DNS_MODE_OPPORTUNISTIC; + default: + throw new IllegalArgumentException("Invalid private dns mode: " + mode); + } + } + + /** + * Get private DNS mode from settings. + * + * @param context The Context to query the private DNS mode from settings. + * @return A string of private DNS mode. + */ + @PrivateDnsMode + public static int getPrivateDnsMode(@NonNull Context context) { + final ContentResolver cr = context.getContentResolver(); + String mode = Settings.Global.getString(cr, PRIVATE_DNS_MODE); + if (TextUtils.isEmpty(mode)) mode = Settings.Global.getString(cr, PRIVATE_DNS_DEFAULT_MODE); + // If both PRIVATE_DNS_MODE and PRIVATE_DNS_DEFAULT_MODE are not set, choose + // PRIVATE_DNS_MODE_OPPORTUNISTIC as default mode. + if (TextUtils.isEmpty(mode)) return PRIVATE_DNS_MODE_OPPORTUNISTIC; + return getPrivateDnsModeAsInt(mode); + } + + /** + * Set private DNS mode to settings. + * + * @param context The {@link Context} to set the private DNS mode. + * @param mode The private dns mode. This should be one of the PRIVATE_DNS_MODE_* constants. + */ + public static void setPrivateDnsMode(@NonNull Context context, @PrivateDnsMode int mode) { + if (!(mode == PRIVATE_DNS_MODE_OFF + || mode == PRIVATE_DNS_MODE_OPPORTUNISTIC + || mode == PRIVATE_DNS_MODE_PROVIDER_HOSTNAME)) { + throw new IllegalArgumentException("Invalid private dns mode: " + mode); + } + Settings.Global.putString(context.getContentResolver(), PRIVATE_DNS_MODE, + getPrivateDnsModeAsString(mode)); + } + /** * Get specific private dns provider name from {@link Settings}. * @@ -731,13 +831,14 @@ public class ConnectivitySettingsManager { * constants. */ public static void setPrivateDnsDefaultMode(@NonNull Context context, - @NonNull @PrivateDnsMode String mode) { + @NonNull @PrivateDnsMode int mode) { if (!(mode == PRIVATE_DNS_MODE_OFF || mode == PRIVATE_DNS_MODE_OPPORTUNISTIC || mode == PRIVATE_DNS_MODE_PROVIDER_HOSTNAME)) { throw new IllegalArgumentException("Invalid private dns mode"); } - Settings.Global.putString(context.getContentResolver(), PRIVATE_DNS_DEFAULT_MODE, mode); + Settings.Global.putString(context.getContentResolver(), PRIVATE_DNS_DEFAULT_MODE, + getPrivateDnsModeAsString(mode)); } /** @@ -903,27 +1004,88 @@ public class ConnectivitySettingsManager { } /** - * Get the list of apps(from {@link Settings}) that should go on cellular networks in preference + * Get the list of uids(from {@link Settings}) that should go on cellular networks in preference * even when higher-priority networks are connected. * * @param context The {@link Context} to query the setting. - * @return A list of apps that should go on cellular networks in preference even when + * @return A list of uids that should go on cellular networks in preference even when * higher-priority networks are connected or null if no setting value. */ - @Nullable - public static String getMobileDataPreferredApps(@NonNull Context context) { - return Settings.Secure.getString(context.getContentResolver(), MOBILE_DATA_PREFERRED_APPS); + @NonNull + public static Set<Integer> getMobileDataPreferredUids(@NonNull Context context) { + final String uidList = Settings.Secure.getString( + context.getContentResolver(), MOBILE_DATA_PREFERRED_UIDS); + final Set<Integer> uids = new ArraySet<>(); + if (TextUtils.isEmpty(uidList)) { + return uids; + } + for (String uid : uidList.split(";")) { + uids.add(Integer.valueOf(uid)); + } + return uids; } /** - * Set the list of apps(to {@link Settings}) that should go on cellular networks in preference + * Set the list of uids(to {@link Settings}) that should go on cellular networks in preference * even when higher-priority networks are connected. * * @param context The {@link Context} to set the setting. - * @param list A list of apps that should go on cellular networks in preference even when + * @param uidList A list of uids that should go on cellular networks in preference even when * higher-priority networks are connected. */ - public static void setMobileDataPreferredApps(@NonNull Context context, @Nullable String list) { - Settings.Secure.putString(context.getContentResolver(), MOBILE_DATA_PREFERRED_APPS, list); + public static void setMobileDataPreferredUids(@NonNull Context context, + @NonNull Set<Integer> uidList) { + final StringJoiner joiner = new StringJoiner(";"); + for (Integer uid : uidList) { + if (uid < 0 || UserHandle.getAppId(uid) > Process.LAST_APPLICATION_UID) { + throw new IllegalArgumentException("Invalid uid"); + } + joiner.add(uid.toString()); + } + Settings.Secure.putString( + context.getContentResolver(), MOBILE_DATA_PREFERRED_UIDS, joiner.toString()); + } + + /** + * Get the list of apps(from {@link Settings}) that should be granted netd system permission for + * using restricted networks. + * + * @param context The {@link Context} to query the setting. + * @return A list of apps that should be granted netd system permission for using restricted + * networks or null if no setting value. + */ + @NonNull + public static Set<String> getRestrictedAllowedApps(@NonNull Context context) { + final String appList = Settings.Secure.getString( + context.getContentResolver(), RESTRICTED_ALLOWED_APPS); + if (TextUtils.isEmpty(appList)) { + return new ArraySet<>(); + } + return new ArraySet<>(appList.split(";")); + } + + /** + * Set the list of apps(from {@link Settings}) that should be granted netd system permission for + * using restricted networks. + * + * Note: Please refer to android developer guidelines for valid app(package name). + * https://developer.android.com/guide/topics/manifest/manifest-element.html#package + * + * @param context The {@link Context} to set the setting. + * @param list A list of apps that should be granted netd system permission for using + * restricted networks. + */ + public static void setRestrictedAllowedApps(@NonNull Context context, + @NonNull Set<String> list) { + final Pattern appPattern = Pattern.compile("[a-zA-Z_0-9]+([.][a-zA-Z_0-9]+)*"); + final StringJoiner joiner = new StringJoiner(";"); + for (String app : list) { + if (!appPattern.matcher(app).matches()) { + throw new IllegalArgumentException("Invalid app(package name)"); + } + joiner.add(app); + } + Settings.Secure.putString( + context.getContentResolver(), RESTRICTED_ALLOWED_APPS, joiner.toString()); } } diff --git a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl index a7cb618f9790..d937c9cd78c0 100644 --- a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl +++ b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl @@ -23,6 +23,7 @@ import android.net.IConnectivityDiagnosticsCallback; import android.net.INetworkAgent; import android.net.IOnCompleteListener; import android.net.INetworkActivityListener; +import android.net.INetworkOfferCallback; import android.net.IQosCallback; import android.net.ISocketKeepaliveCallback; import android.net.LinkProperties; @@ -221,4 +222,8 @@ interface IConnectivityManager in IOnCompleteListener listener); int getRestrictBackgroundStatusByCaller(); + + void offerNetwork(in Messenger messenger, in NetworkScore score, + in NetworkCapabilities caps, in INetworkOfferCallback callback); + void unofferNetwork(in INetworkOfferCallback callback); } diff --git a/packages/Connectivity/framework/src/android/net/INetworkOfferCallback.aidl b/packages/Connectivity/framework/src/android/net/INetworkOfferCallback.aidl new file mode 100644 index 000000000000..67d2d405dbed --- /dev/null +++ b/packages/Connectivity/framework/src/android/net/INetworkOfferCallback.aidl @@ -0,0 +1,62 @@ +/* + * 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; + +import android.net.NetworkRequest; + +/** + * A callback registered with connectivity by network providers together with + * a NetworkOffer. + * + * When the offer is needed to satisfy some application or system component, + * connectivity will call onOfferNeeded on this callback. When this happens, + * the provider should try and bring up the network. + * + * When the offer is no longer needed, for example because the application has + * withdrawn the request or if the request is being satisfied by a network + * that this offer will never be able to beat, connectivity calls + * onOfferUnneeded. When this happens, the provider should stop trying to + * bring up the network, or tear it down if it has already been brought up. + * + * When NetworkProvider#offerNetwork is called, the provider can expect to + * immediately receive all requests that can be fulfilled by that offer and + * are not already satisfied by a better network. It is possible no such + * request is currently outstanding, because no requests have been made that + * can be satisfied by this offer, or because all such requests are already + * satisfied by a better network. + * onOfferNeeded can be called at any time after registration and until the + * offer is withdrawn with NetworkProvider#unofferNetwork is called. This + * typically happens when a new network request is filed by an application, + * or when the network satisfying a request disconnects and this offer now + * stands a chance to be the best network for it. + * + * @hide + */ +oneway interface INetworkOfferCallback { + /** + * Informs the registrant that the offer is needed to fulfill this request. + * @param networkRequest the request to satisfy + * @param providerId the ID of the provider currently satisfying + * this request, or NetworkProvider.ID_NONE if none. + */ + void onOfferNeeded(in NetworkRequest networkRequest, int providerId); + + /** + * Informs the registrant that the offer is no longer needed to fulfill this request. + */ + void onOfferUnneeded(in NetworkRequest networkRequest); +} diff --git a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java index 950b1c769514..c19a906ecd70 100644 --- a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java +++ b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java @@ -139,19 +139,13 @@ public final class NetworkCapabilities implements Parcelable { */ private String mRequestorPackageName; - /** - * Indicates what fields should be redacted from this instance. - */ - private final @RedactionType long mRedactions; - public NetworkCapabilities() { - mRedactions = REDACT_ALL; clearAll(); mNetworkCapabilities = DEFAULT_CAPABILITIES; } public NetworkCapabilities(NetworkCapabilities nc) { - this(nc, REDACT_ALL); + this(nc, REDACT_NONE); } /** @@ -163,10 +157,12 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ public NetworkCapabilities(@Nullable NetworkCapabilities nc, @RedactionType long redactions) { - mRedactions = redactions; if (nc != null) { set(nc); } + if (mTransportInfo != null) { + mTransportInfo = nc.mTransportInfo.makeCopy(redactions); + } } /** @@ -175,15 +171,7 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ public void clearAll() { - // Ensures that the internal copies maintained by the connectivity stack does not set it to - // anything other than |REDACT_ALL|. - if (mRedactions != REDACT_ALL) { - // This is needed because the current redaction mechanism relies on redaction while - // parceling. - throw new UnsupportedOperationException( - "Cannot clear NetworkCapabilities when mRedactions is set"); - } - mNetworkCapabilities = mTransportTypes = mUnwantedNetworkCapabilities = 0; + mNetworkCapabilities = mTransportTypes = mForbiddenNetworkCapabilities = 0; mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED; mNetworkSpecifier = null; mTransportInfo = null; @@ -211,7 +199,7 @@ public final class NetworkCapabilities implements Parcelable { mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps; mNetworkSpecifier = nc.mNetworkSpecifier; if (nc.getTransportInfo() != null) { - setTransportInfo(nc.getTransportInfo().makeCopy(mRedactions)); + setTransportInfo(nc.getTransportInfo()); } else { setTransportInfo(null); } @@ -219,7 +207,7 @@ public final class NetworkCapabilities implements Parcelable { mUids = (nc.mUids == null) ? null : new ArraySet<>(nc.mUids); setAdministratorUids(nc.getAdministratorUids()); mOwnerUid = nc.mOwnerUid; - mUnwantedNetworkCapabilities = nc.mUnwantedNetworkCapabilities; + mForbiddenNetworkCapabilities = nc.mForbiddenNetworkCapabilities; mSSID = nc.mSSID; mPrivateDnsBroken = nc.mPrivateDnsBroken; mRequestorUid = nc.mRequestorUid; @@ -237,7 +225,7 @@ public final class NetworkCapabilities implements Parcelable { /** * If any capabilities specified here they must not exist in the matching Network. */ - private long mUnwantedNetworkCapabilities; + private long mForbiddenNetworkCapabilities; /** @hide */ @Retention(RetentionPolicy.SOURCE) @@ -586,21 +574,21 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ public @NonNull NetworkCapabilities addCapability(@NetCapability int capability) { - // If the given capability was previously added to the list of unwanted capabilities - // then the capability will also be removed from the list of unwanted capabilities. - // TODO: Consider adding unwanted capabilities to the public API and mention this + // If the given capability was previously added to the list of forbidden capabilities + // then the capability will also be removed from the list of forbidden capabilities. + // TODO: Consider adding forbidden capabilities to the public API and mention this // in the documentation. checkValidCapability(capability); mNetworkCapabilities |= 1L << capability; - // remove from unwanted capability list - mUnwantedNetworkCapabilities &= ~(1L << capability); + // remove from forbidden capability list + mForbiddenNetworkCapabilities &= ~(1L << capability); return this; } /** - * Adds the given capability to the list of unwanted capabilities of this + * Adds the given capability to the list of forbidden capabilities of this * {@code NetworkCapability} instance. Note that when searching for a network to - * satisfy a request, the network must not contain any capability from unwanted capability + * satisfy a request, the network must not contain any capability from forbidden capability * list. * <p> * If the capability was previously added to the list of required capabilities (for @@ -610,9 +598,9 @@ public final class NetworkCapabilities implements Parcelable { * @see #addCapability(int) * @hide */ - public void addUnwantedCapability(@NetCapability int capability) { + public void addForbiddenCapability(@NetCapability int capability) { checkValidCapability(capability); - mUnwantedNetworkCapabilities |= 1L << capability; + mForbiddenNetworkCapabilities |= 1L << capability; mNetworkCapabilities &= ~(1L << capability); // remove from requested capabilities } @@ -632,16 +620,16 @@ public final class NetworkCapabilities implements Parcelable { } /** - * Removes (if found) the given unwanted capability from this {@code NetworkCapability} - * instance that were added via addUnwantedCapability(int) or setCapabilities(int[], int[]). + * Removes (if found) the given forbidden capability from this {@code NetworkCapability} + * instance that were added via addForbiddenCapability(int) or setCapabilities(int[], int[]). * * @param capability the capability to be removed. * @return This NetworkCapabilities instance, to facilitate chaining. * @hide */ - public @NonNull NetworkCapabilities removeUnwantedCapability(@NetCapability int capability) { + public @NonNull NetworkCapabilities removeForbiddenCapability(@NetCapability int capability) { checkValidCapability(capability); - mUnwantedNetworkCapabilities &= ~(1L << capability); + mForbiddenNetworkCapabilities &= ~(1L << capability); return this; } @@ -670,13 +658,13 @@ public final class NetworkCapabilities implements Parcelable { } /** - * Gets all the unwanted capabilities set on this {@code NetworkCapability} instance. + * Gets all the forbidden capabilities set on this {@code NetworkCapability} instance. * - * @return an array of unwanted capability values for this instance. + * @return an array of forbidden capability values for this instance. * @hide */ - public @NetCapability int[] getUnwantedCapabilities() { - return NetworkCapabilitiesUtils.unpackBits(mUnwantedNetworkCapabilities); + public @NetCapability int[] getForbiddenCapabilities() { + return NetworkCapabilitiesUtils.unpackBits(mForbiddenNetworkCapabilities); } @@ -687,9 +675,9 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ public void setCapabilities(@NetCapability int[] capabilities, - @NetCapability int[] unwantedCapabilities) { + @NetCapability int[] forbiddenCapabilities) { mNetworkCapabilities = NetworkCapabilitiesUtils.packBits(capabilities); - mUnwantedNetworkCapabilities = NetworkCapabilitiesUtils.packBits(unwantedCapabilities); + mForbiddenNetworkCapabilities = NetworkCapabilitiesUtils.packBits(forbiddenCapabilities); } /** @@ -714,9 +702,9 @@ public final class NetworkCapabilities implements Parcelable { /** @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) - public boolean hasUnwantedCapability(@NetCapability int capability) { + public boolean hasForbiddenCapability(@NetCapability int capability) { return isValidCapability(capability) - && ((mUnwantedNetworkCapabilities & (1L << capability)) != 0); + && ((mForbiddenNetworkCapabilities & (1L << capability)) != 0); } /** @@ -746,14 +734,14 @@ public final class NetworkCapabilities implements Parcelable { private void combineNetCapabilities(@NonNull NetworkCapabilities nc) { final long wantedCaps = this.mNetworkCapabilities | nc.mNetworkCapabilities; - final long unwantedCaps = - this.mUnwantedNetworkCapabilities | nc.mUnwantedNetworkCapabilities; - if ((wantedCaps & unwantedCaps) != 0) { + final long forbiddenCaps = + this.mForbiddenNetworkCapabilities | nc.mForbiddenNetworkCapabilities; + if ((wantedCaps & forbiddenCaps) != 0) { throw new IllegalArgumentException( - "Cannot have the same capability in wanted and unwanted lists."); + "Cannot have the same capability in wanted and forbidden lists."); } this.mNetworkCapabilities = wantedCaps; - this.mUnwantedNetworkCapabilities = unwantedCaps; + this.mForbiddenNetworkCapabilities = forbiddenCaps; } /** @@ -764,7 +752,7 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ public @Nullable String describeFirstNonRequestableCapability() { - final long nonRequestable = (mNetworkCapabilities | mUnwantedNetworkCapabilities) + final long nonRequestable = (mNetworkCapabilities | mForbiddenNetworkCapabilities) & NON_REQUESTABLE_CAPABILITIES; if (nonRequestable != 0) { @@ -781,28 +769,28 @@ public final class NetworkCapabilities implements Parcelable { private boolean satisfiedByNetCapabilities(@NonNull NetworkCapabilities nc, boolean onlyImmutable) { long requestedCapabilities = mNetworkCapabilities; - long requestedUnwantedCapabilities = mUnwantedNetworkCapabilities; + long requestedForbiddenCapabilities = mForbiddenNetworkCapabilities; long providedCapabilities = nc.mNetworkCapabilities; if (onlyImmutable) { requestedCapabilities &= ~MUTABLE_CAPABILITIES; - requestedUnwantedCapabilities &= ~MUTABLE_CAPABILITIES; + requestedForbiddenCapabilities &= ~MUTABLE_CAPABILITIES; } return ((providedCapabilities & requestedCapabilities) == requestedCapabilities) - && ((requestedUnwantedCapabilities & providedCapabilities) == 0); + && ((requestedForbiddenCapabilities & providedCapabilities) == 0); } /** @hide */ public boolean equalsNetCapabilities(@NonNull NetworkCapabilities nc) { return (nc.mNetworkCapabilities == this.mNetworkCapabilities) - && (nc.mUnwantedNetworkCapabilities == this.mUnwantedNetworkCapabilities); + && (nc.mForbiddenNetworkCapabilities == this.mForbiddenNetworkCapabilities); } private boolean equalsNetCapabilitiesRequestable(@NonNull NetworkCapabilities that) { - return ((this.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) == - (that.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES)) - && ((this.mUnwantedNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) == - (that.mUnwantedNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES)); + return ((this.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) + == (that.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES)) + && ((this.mForbiddenNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) + == (that.mForbiddenNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES)); } /** @@ -830,8 +818,17 @@ public final class NetworkCapabilities implements Parcelable { final int[] originalAdministratorUids = getAdministratorUids(); final TransportInfo originalTransportInfo = getTransportInfo(); clearAll(); - mTransportTypes = (originalTransportTypes & TEST_NETWORKS_ALLOWED_TRANSPORTS) - | (1 << TRANSPORT_TEST); + if (0 != (originalCapabilities & NET_CAPABILITY_NOT_RESTRICTED)) { + // If the test network is not restricted, then it is only allowed to declare some + // specific transports. This is to minimize impact on running apps in case an app + // run from the shell creates a test a network. + mTransportTypes = + (originalTransportTypes & UNRESTRICTED_TEST_NETWORKS_ALLOWED_TRANSPORTS) + | (1 << TRANSPORT_TEST); + } else { + // If the test transport is restricted, then it may declare any transport. + mTransportTypes = (originalTransportTypes | (1 << TRANSPORT_TEST)); + } mNetworkCapabilities = originalCapabilities & TEST_NETWORKS_ALLOWED_CAPABILITIES; mNetworkSpecifier = originalSpecifier; mSignalStrength = originalSignalStrength; @@ -935,9 +932,10 @@ public final class NetworkCapabilities implements Parcelable { }; /** - * Allowed transports on a test network, in addition to TRANSPORT_TEST. + * Allowed transports on an unrestricted test network (in addition to TRANSPORT_TEST). */ - private static final int TEST_NETWORKS_ALLOWED_TRANSPORTS = 1 << TRANSPORT_TEST + private static final int UNRESTRICTED_TEST_NETWORKS_ALLOWED_TRANSPORTS = + 1 << TRANSPORT_TEST // Test ethernet networks can be created with EthernetManager#setIncludeTestInterfaces | 1 << TRANSPORT_ETHERNET // Test VPN networks can be created but their UID ranges must be empty. @@ -1718,7 +1716,7 @@ public final class NetworkCapabilities implements Parcelable { * Combine a set of Capabilities to this one. Useful for coming up with the complete set. * <p> * Note that this method may break an invariant of having a particular capability in either - * wanted or unwanted lists but never in both. Requests that have the same capability in + * wanted or forbidden lists but never in both. Requests that have the same capability in * both lists will never be satisfied. * @hide */ @@ -1859,8 +1857,8 @@ public final class NetworkCapabilities implements Parcelable { public int hashCode() { return (int) (mNetworkCapabilities & 0xFFFFFFFF) + ((int) (mNetworkCapabilities >> 32) * 3) - + ((int) (mUnwantedNetworkCapabilities & 0xFFFFFFFF) * 5) - + ((int) (mUnwantedNetworkCapabilities >> 32) * 7) + + ((int) (mForbiddenNetworkCapabilities & 0xFFFFFFFF) * 5) + + ((int) (mForbiddenNetworkCapabilities >> 32) * 7) + ((int) (mTransportTypes & 0xFFFFFFFF) * 11) + ((int) (mTransportTypes >> 32) * 13) + mLinkUpBandwidthKbps * 17 @@ -1895,7 +1893,7 @@ public final class NetworkCapabilities implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { dest.writeLong(mNetworkCapabilities); - dest.writeLong(mUnwantedNetworkCapabilities); + dest.writeLong(mForbiddenNetworkCapabilities); dest.writeLong(mTransportTypes); dest.writeInt(mLinkUpBandwidthKbps); dest.writeInt(mLinkDownBandwidthKbps); @@ -1919,7 +1917,7 @@ public final class NetworkCapabilities implements Parcelable { NetworkCapabilities netCap = new NetworkCapabilities(); netCap.mNetworkCapabilities = in.readLong(); - netCap.mUnwantedNetworkCapabilities = in.readLong(); + netCap.mForbiddenNetworkCapabilities = in.readLong(); netCap.mTransportTypes = in.readLong(); netCap.mLinkUpBandwidthKbps = in.readInt(); netCap.mLinkDownBandwidthKbps = in.readInt(); @@ -1973,9 +1971,9 @@ public final class NetworkCapabilities implements Parcelable { appendStringRepresentationOfBitMaskToStringBuilder(sb, mNetworkCapabilities, NetworkCapabilities::capabilityNameOf, "&"); } - if (0 != mUnwantedNetworkCapabilities) { - sb.append(" Unwanted: "); - appendStringRepresentationOfBitMaskToStringBuilder(sb, mUnwantedNetworkCapabilities, + if (0 != mForbiddenNetworkCapabilities) { + sb.append(" Forbidden: "); + appendStringRepresentationOfBitMaskToStringBuilder(sb, mForbiddenNetworkCapabilities, NetworkCapabilities::capabilityNameOf, "&"); } if (mLinkUpBandwidthKbps > 0) { diff --git a/packages/Connectivity/framework/src/android/net/NetworkProvider.java b/packages/Connectivity/framework/src/android/net/NetworkProvider.java index 14cb51c85d06..8f93047cf850 100644 --- a/packages/Connectivity/framework/src/android/net/NetworkProvider.java +++ b/packages/Connectivity/framework/src/android/net/NetworkProvider.java @@ -28,6 +28,11 @@ import android.os.Message; import android.os.Messenger; import android.util.Log; +import com.android.internal.annotations.GuardedBy; + +import java.util.ArrayList; +import java.util.concurrent.Executor; + /** * Base class for network providers such as telephony or Wi-Fi. NetworkProviders connect the device * to networks and makes them available to the core network stack by creating @@ -78,7 +83,9 @@ public class NetworkProvider { */ @SystemApi public NetworkProvider(@NonNull Context context, @NonNull Looper looper, @NonNull String name) { - Handler handler = new Handler(looper) { + // TODO (b/174636568) : this class should be able to cache an instance of + // ConnectivityManager so it doesn't have to fetch it again every time. + final Handler handler = new Handler(looper) { @Override public void handleMessage(Message m) { switch (m.what) { @@ -159,4 +166,148 @@ public class NetworkProvider { public void declareNetworkRequestUnfulfillable(@NonNull NetworkRequest request) { ConnectivityManager.from(mContext).declareNetworkRequestUnfulfillable(request); } + + /** @hide */ + // TODO : make @SystemApi when the impl is complete + public interface NetworkOfferCallback { + /** Called by the system when this offer is needed to satisfy some networking request. */ + void onOfferNeeded(@NonNull NetworkRequest request, int providerId); + /** Called by the system when this offer is no longer needed. */ + void onOfferUnneeded(@NonNull NetworkRequest request); + } + + private class NetworkOfferCallbackProxy extends INetworkOfferCallback.Stub { + @NonNull public final NetworkOfferCallback callback; + @NonNull private final Executor mExecutor; + + NetworkOfferCallbackProxy(@NonNull final NetworkOfferCallback callback, + @NonNull final Executor executor) { + this.callback = callback; + this.mExecutor = executor; + } + + @Override + public void onOfferNeeded(final @NonNull NetworkRequest request, + final int providerId) { + mExecutor.execute(() -> callback.onOfferNeeded(request, providerId)); + } + + @Override + public void onOfferUnneeded(final @NonNull NetworkRequest request) { + mExecutor.execute(() -> callback.onOfferUnneeded(request)); + } + } + + @GuardedBy("mProxies") + @NonNull private final ArrayList<NetworkOfferCallbackProxy> mProxies = new ArrayList<>(); + + // Returns the proxy associated with this callback, or null if none. + @Nullable + private NetworkOfferCallbackProxy findProxyForCallback(@NonNull final NetworkOfferCallback cb) { + synchronized (mProxies) { + for (final NetworkOfferCallbackProxy p : mProxies) { + if (p.callback == cb) return p; + } + } + return null; + } + + /** + * Register or update an offer for network with the passed caps and score. + * + * A NetworkProvider's job is to provide networks. This function is how a provider tells the + * connectivity stack what kind of network it may provide. The score and caps arguments act + * as filters that the connectivity stack uses to tell when the offer is necessary. When an + * offer might be advantageous over existing networks, the provider will receive a call to + * the associated callback's {@link NetworkOfferCallback#onOfferNeeded} method. The provider + * should then try to bring up this network. When an offer is no longer needed, the stack + * will inform the provider by calling {@link NetworkOfferCallback#onOfferUnneeded}. The + * provider should stop trying to bring up such a network, or disconnect it if it already has + * one. + * + * The stack determines what offers are needed according to what networks are currently + * available to the system, and what networking requests are made by applications. If an + * offer looks like it could be a better choice than any existing network for any particular + * request, that's when the stack decides the offer is needed. If the current networking + * requests are all satisfied by networks that this offer can't possibly be a better match + * for, that's when the offer is unneeded. An offer starts off as unneeded ; the provider + * should not try to bring up the network until {@link NetworkOfferCallback#onOfferNeeded} + * is called. + * + * Note that the offers are non-binding to the providers, in particular because providers + * often don't know if they will be able to bring up such a network at any given time. For + * example, no wireless network may be in range when the offer is needed. This is fine and + * expected ; the provider should simply continue to try to bring up the network and do so + * if/when it becomes possible. In the mean time, the stack will continue to satisfy requests + * with the best network currently available, or if none, keep the apps informed that no + * network can currently satisfy this request. When/if the provider can bring up the network, + * the connectivity stack will match it against requests, and inform interested apps of the + * availability of this network. This may, in turn, render the offer of some other provider + * unneeded if all requests it used to satisfy are now better served by this network. + * + * A network can become unneeded for a reason like the above : whether the provider managed + * to bring up the offered network after it became needed or not, some other provider may + * bring up a better network than this one, making this offer unneeded. A network may also + * become unneeded if the application making the request withdrew it (for example, after it + * is done transferring data, or if the user canceled an operation). + * + * The capabilities and score act as filters as to what requests the provider will see. + * They are not promises, but for best performance, the providers should strive to put + * as much known information as possible in the offer. For capabilities in particular, it + * should put all NetworkAgent-managed capabilities a network may have, even if it doesn't + * have them at first. This applies to INTERNET, for example ; if a provider thinks the + * network it can bring up for this offer may offer Internet access it should include the + * INTERNET bit. It's fine if the brought up network ends up not actually having INTERNET. + * + * TODO : in the future, to avoid possible infinite loops, there should be constraints on + * what can be put in capabilities of networks brought up for an offer. If a provider might + * bring up a network with or without INTERNET, then it should file two offers : this will + * let it know precisely what networks are needed, so it can avoid bringing up networks that + * won't actually satisfy requests and remove the risk for bring-up-bring-down loops. + * + * @hide + */ + // TODO : make @SystemApi when the impl is complete + @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) + public void offerNetwork(@NonNull final NetworkScore score, + @NonNull final NetworkCapabilities caps, @NonNull final Executor executor, + @NonNull final NetworkOfferCallback callback) { + NetworkOfferCallbackProxy proxy = null; + synchronized (mProxies) { + for (final NetworkOfferCallbackProxy existingProxy : mProxies) { + if (existingProxy.callback == callback) { + proxy = existingProxy; + break; + } + } + if (null == proxy) { + proxy = new NetworkOfferCallbackProxy(callback, executor); + mProxies.add(proxy); + } + } + mContext.getSystemService(ConnectivityManager.class).offerNetwork(this, score, caps, proxy); + } + + /** + * Withdraw a network offer previously made to the networking stack. + * + * If a provider can no longer provide a network they offered, it should call this method. + * An example of usage could be if the hardware necessary to bring up the network was turned + * off in UI by the user. Note that because offers are never binding, the provider might + * alternatively decide not to withdraw this offer and simply refuse to bring up the network + * even when it's needed. However, withdrawing the request is slightly more resource-efficient + * because the networking stack won't have to compare this offer to exiting networks to see + * if it could beat any of them, and may be advantageous to the provider's implementation that + * can rely on no longer receiving callbacks for a network that they can't bring up anyways. + * + * @hide + */ + // TODO : make @SystemApi when the impl is complete + @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) + public void unofferNetwork(final @NonNull NetworkOfferCallback callback) { + final NetworkOfferCallbackProxy proxy = findProxyForCallback(callback); + if (null == proxy) return; + mProxies.remove(proxy); + mContext.getSystemService(ConnectivityManager.class).unofferNetwork(proxy); + } } diff --git a/packages/Connectivity/framework/src/android/net/NetworkRequest.java b/packages/Connectivity/framework/src/android/net/NetworkRequest.java index 8c4f4193b50f..dd88c5a5c94e 100644 --- a/packages/Connectivity/framework/src/android/net/NetworkRequest.java +++ b/packages/Connectivity/framework/src/android/net/NetworkRequest.java @@ -311,7 +311,7 @@ public class NetworkRequest implements Parcelable { * * @see #addCapability(int) * - * @param capability The capability to add to unwanted capability list. + * @param capability The capability to add to forbidden capability list. * @return The builder to facilitate chaining. * * @hide @@ -319,15 +319,15 @@ public class NetworkRequest implements Parcelable { @NonNull @SuppressLint("MissingGetterMatchingBuilder") @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) - public Builder addUnwantedCapability(@NetworkCapabilities.NetCapability int capability) { - mNetworkCapabilities.addUnwantedCapability(capability); + public Builder addForbiddenCapability(@NetworkCapabilities.NetCapability int capability) { + mNetworkCapabilities.addForbiddenCapability(capability); return this; } /** - * Removes (if found) the given unwanted capability from this builder instance. + * Removes (if found) the given forbidden capability from this builder instance. * - * @param capability The unwanted capability to remove. + * @param capability The forbidden capability to remove. * @return The builder to facilitate chaining. * * @hide @@ -335,8 +335,9 @@ public class NetworkRequest implements Parcelable { @NonNull @SuppressLint("BuilderSetStyle") @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) - public Builder removeUnwantedCapability(@NetworkCapabilities.NetCapability int capability) { - mNetworkCapabilities.removeUnwantedCapability(capability); + public Builder removeForbiddenCapability( + @NetworkCapabilities.NetCapability int capability) { + mNetworkCapabilities.removeForbiddenCapability(capability); return this; } @@ -598,13 +599,13 @@ public class NetworkRequest implements Parcelable { } /** - * @see Builder#addUnwantedCapability(int) + * @see Builder#addForbiddenCapability(int) * * @hide */ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) - public boolean hasUnwantedCapability(@NetCapability int capability) { - return networkCapabilities.hasUnwantedCapability(capability); + public boolean hasForbiddenCapability(@NetCapability int capability) { + return networkCapabilities.hasForbiddenCapability(capability); } /** @@ -709,18 +710,18 @@ public class NetworkRequest implements Parcelable { } /** - * Gets all the unwanted capabilities set on this {@code NetworkRequest} instance. + * Gets all the forbidden capabilities set on this {@code NetworkRequest} instance. * - * @return an array of unwanted capability values for this instance. + * @return an array of forbidden capability values for this instance. * * @hide */ @NonNull @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) - public @NetCapability int[] getUnwantedCapabilities() { - // No need to make a defensive copy here as NC#getUnwantedCapabilities() already returns + public @NetCapability int[] getForbiddenCapabilities() { + // No need to make a defensive copy here as NC#getForbiddenCapabilities() already returns // a new array. - return networkCapabilities.getUnwantedCapabilities(); + return networkCapabilities.getForbiddenCapabilities(); } /** diff --git a/tests/net/OWNERS b/packages/Connectivity/tests/OWNERS index d3836d4c6c57..d3836d4c6c57 100644 --- a/tests/net/OWNERS +++ b/packages/Connectivity/tests/OWNERS diff --git a/tests/net/TEST_MAPPING b/packages/Connectivity/tests/TEST_MAPPING index 502f885ceb78..502f885ceb78 100644 --- a/tests/net/TEST_MAPPING +++ b/packages/Connectivity/tests/TEST_MAPPING diff --git a/tests/net/common/Android.bp b/packages/Connectivity/tests/common/Android.bp index babb81c5fa34..babb81c5fa34 100644 --- a/tests/net/common/Android.bp +++ b/packages/Connectivity/tests/common/Android.bp diff --git a/tests/net/common/java/ParseExceptionTest.kt b/packages/Connectivity/tests/common/java/ParseExceptionTest.kt index b702d61a9fe1..b702d61a9fe1 100644 --- a/tests/net/common/java/ParseExceptionTest.kt +++ b/packages/Connectivity/tests/common/java/ParseExceptionTest.kt diff --git a/tests/net/common/java/android/net/CaptivePortalDataTest.kt b/packages/Connectivity/tests/common/java/android/net/CaptivePortalDataTest.kt index 18a93319b271..18a93319b271 100644 --- a/tests/net/common/java/android/net/CaptivePortalDataTest.kt +++ b/packages/Connectivity/tests/common/java/android/net/CaptivePortalDataTest.kt diff --git a/tests/net/common/java/android/net/CaptivePortalTest.java b/packages/Connectivity/tests/common/java/android/net/CaptivePortalTest.java index 15d3398d43c0..15d3398d43c0 100644 --- a/tests/net/common/java/android/net/CaptivePortalTest.java +++ b/packages/Connectivity/tests/common/java/android/net/CaptivePortalTest.java diff --git a/tests/net/common/java/android/net/DependenciesTest.java b/packages/Connectivity/tests/common/java/android/net/DependenciesTest.java index ac1c28a45462..ac1c28a45462 100644 --- a/tests/net/common/java/android/net/DependenciesTest.java +++ b/packages/Connectivity/tests/common/java/android/net/DependenciesTest.java diff --git a/tests/net/common/java/android/net/DhcpInfoTest.java b/packages/Connectivity/tests/common/java/android/net/DhcpInfoTest.java index ab4726bab573..ab4726bab573 100644 --- a/tests/net/common/java/android/net/DhcpInfoTest.java +++ b/packages/Connectivity/tests/common/java/android/net/DhcpInfoTest.java diff --git a/tests/net/common/java/android/net/IpPrefixTest.java b/packages/Connectivity/tests/common/java/android/net/IpPrefixTest.java index 50ecb428359e..50ecb428359e 100644 --- a/tests/net/common/java/android/net/IpPrefixTest.java +++ b/packages/Connectivity/tests/common/java/android/net/IpPrefixTest.java diff --git a/tests/net/common/java/android/net/KeepalivePacketDataTest.kt b/packages/Connectivity/tests/common/java/android/net/KeepalivePacketDataTest.kt index f464ec6cf0e5..f464ec6cf0e5 100644 --- a/tests/net/common/java/android/net/KeepalivePacketDataTest.kt +++ b/packages/Connectivity/tests/common/java/android/net/KeepalivePacketDataTest.kt diff --git a/tests/net/common/java/android/net/LinkAddressTest.java b/packages/Connectivity/tests/common/java/android/net/LinkAddressTest.java index 2cf3cf9c11da..2cf3cf9c11da 100644 --- a/tests/net/common/java/android/net/LinkAddressTest.java +++ b/packages/Connectivity/tests/common/java/android/net/LinkAddressTest.java diff --git a/tests/net/common/java/android/net/LinkPropertiesTest.java b/packages/Connectivity/tests/common/java/android/net/LinkPropertiesTest.java index 550953d0612d..550953d0612d 100644 --- a/tests/net/common/java/android/net/LinkPropertiesTest.java +++ b/packages/Connectivity/tests/common/java/android/net/LinkPropertiesTest.java diff --git a/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt b/packages/Connectivity/tests/common/java/android/net/MatchAllNetworkSpecifierTest.kt index a5e44d59fcab..a5e44d59fcab 100644 --- a/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt +++ b/packages/Connectivity/tests/common/java/android/net/MatchAllNetworkSpecifierTest.kt diff --git a/tests/net/common/java/android/net/NattKeepalivePacketDataTest.kt b/packages/Connectivity/tests/common/java/android/net/NattKeepalivePacketDataTest.kt index 46f39dd016fd..46f39dd016fd 100644 --- a/tests/net/common/java/android/net/NattKeepalivePacketDataTest.kt +++ b/packages/Connectivity/tests/common/java/android/net/NattKeepalivePacketDataTest.kt diff --git a/tests/net/common/java/android/net/NetworkAgentConfigTest.kt b/packages/Connectivity/tests/common/java/android/net/NetworkAgentConfigTest.kt index 2b45b3d69ce9..2b45b3d69ce9 100644 --- a/tests/net/common/java/android/net/NetworkAgentConfigTest.kt +++ b/packages/Connectivity/tests/common/java/android/net/NetworkAgentConfigTest.kt diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/packages/Connectivity/tests/common/java/android/net/NetworkCapabilitiesTest.java index 33f2c67646e5..d74b802c8729 100644 --- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java +++ b/packages/Connectivity/tests/common/java/android/net/NetworkCapabilitiesTest.java @@ -340,7 +340,7 @@ public class NetworkCapabilitiesTest { private void testParcelSane(NetworkCapabilities cap) { if (isAtLeastS()) { - assertParcelSane(cap, 17); + assertParcelSane(cap, 16); } else if (isAtLeastR()) { assertParcelSane(cap, 15); } else { @@ -390,9 +390,11 @@ public class NetworkCapabilitiesTest { @Test public void testOemPaid() { NetworkCapabilities nc = new NetworkCapabilities(); - // By default OEM_PAID is neither in the unwanted or required lists and the network is not + // By default OEM_PAID is neither in the required or forbidden lists and the network is not // restricted. - assertFalse(nc.hasUnwantedCapability(NET_CAPABILITY_OEM_PAID)); + if (isAtLeastS()) { + assertFalse(nc.hasForbiddenCapability(NET_CAPABILITY_OEM_PAID)); + } assertFalse(nc.hasCapability(NET_CAPABILITY_OEM_PAID)); nc.maybeMarkCapabilitiesRestricted(); assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); @@ -417,9 +419,9 @@ public class NetworkCapabilitiesTest { @Test @IgnoreUpTo(Build.VERSION_CODES.R) public void testOemPrivate() { NetworkCapabilities nc = new NetworkCapabilities(); - // By default OEM_PRIVATE is neither in the unwanted or required lists and the network is + // By default OEM_PRIVATE is neither in the required or forbidden lists and the network is // not restricted. - assertFalse(nc.hasUnwantedCapability(NET_CAPABILITY_OEM_PRIVATE)); + assertFalse(nc.hasForbiddenCapability(NET_CAPABILITY_OEM_PRIVATE)); assertFalse(nc.hasCapability(NET_CAPABILITY_OEM_PRIVATE)); nc.maybeMarkCapabilitiesRestricted(); assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); @@ -441,8 +443,8 @@ public class NetworkCapabilitiesTest { assertFalse(nr.satisfiedByNetworkCapabilities(new NetworkCapabilities())); } - @Test - public void testUnwantedCapabilities() { + @Test @IgnoreUpTo(Build.VERSION_CODES.R) + public void testForbiddenCapabilities() { NetworkCapabilities network = new NetworkCapabilities(); NetworkCapabilities request = new NetworkCapabilities(); @@ -450,19 +452,19 @@ public class NetworkCapabilitiesTest { request.satisfiedByNetworkCapabilities(network)); // Requesting absence of capabilities that network doesn't have. Request should satisfy. - request.addUnwantedCapability(NET_CAPABILITY_WIFI_P2P); - request.addUnwantedCapability(NET_CAPABILITY_NOT_METERED); + request.addForbiddenCapability(NET_CAPABILITY_WIFI_P2P); + request.addForbiddenCapability(NET_CAPABILITY_NOT_METERED); assertTrue(request.satisfiedByNetworkCapabilities(network)); - assertArrayEquals(new int[] {NET_CAPABILITY_WIFI_P2P, + assertArrayEquals(new int[]{NET_CAPABILITY_WIFI_P2P, NET_CAPABILITY_NOT_METERED}, - request.getUnwantedCapabilities()); + request.getForbiddenCapabilities()); // This is a default capability, just want to make sure its there because we use it below. assertTrue(network.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); - // Verify that adding unwanted capability will effectively remove it from capability list. - request.addUnwantedCapability(NET_CAPABILITY_NOT_RESTRICTED); - assertTrue(request.hasUnwantedCapability(NET_CAPABILITY_NOT_RESTRICTED)); + // Verify that adding forbidden capability will effectively remove it from capability list. + request.addForbiddenCapability(NET_CAPABILITY_NOT_RESTRICTED); + assertTrue(request.hasForbiddenCapability(NET_CAPABILITY_NOT_RESTRICTED)); assertFalse(request.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); // Now this request won't be satisfied because network contains NOT_RESTRICTED. @@ -470,10 +472,10 @@ public class NetworkCapabilitiesTest { network.removeCapability(NET_CAPABILITY_NOT_RESTRICTED); assertTrue(request.satisfiedByNetworkCapabilities(network)); - // Verify that adding capability will effectively remove it from unwanted list + // Verify that adding capability will effectively remove it from forbidden list request.addCapability(NET_CAPABILITY_NOT_RESTRICTED); assertTrue(request.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)); - assertFalse(request.hasUnwantedCapability(NET_CAPABILITY_NOT_RESTRICTED)); + assertFalse(request.hasForbiddenCapability(NET_CAPABILITY_NOT_RESTRICTED)); assertFalse(request.satisfiedByNetworkCapabilities(network)); network.addCapability(NET_CAPABILITY_NOT_RESTRICTED); @@ -512,24 +514,20 @@ public class NetworkCapabilitiesTest { assertTrue(nc1.equalsNetCapabilities(nc2)); assertEquals(nc1, nc2); - nc1.addUnwantedCapability(NET_CAPABILITY_INTERNET); - assertFalse(nc1.equalsNetCapabilities(nc2)); - nc2.addUnwantedCapability(NET_CAPABILITY_INTERNET); - assertTrue(nc1.equalsNetCapabilities(nc2)); if (isAtLeastS()) { - // Remove a required capability doesn't affect unwanted capabilities. - // This is a behaviour change from S. - nc1.removeCapability(NET_CAPABILITY_INTERNET); - assertTrue(nc1.equalsNetCapabilities(nc2)); - - nc1.removeUnwantedCapability(NET_CAPABILITY_INTERNET); + nc1.addForbiddenCapability(NET_CAPABILITY_INTERNET); assertFalse(nc1.equalsNetCapabilities(nc2)); - nc2.removeUnwantedCapability(NET_CAPABILITY_INTERNET); + nc2.addForbiddenCapability(NET_CAPABILITY_INTERNET); assertTrue(nc1.equalsNetCapabilities(nc2)); - } else { + + // Remove a required capability doesn't affect forbidden capabilities. + // This is a behaviour change from R to S. nc1.removeCapability(NET_CAPABILITY_INTERNET); + assertTrue(nc1.equalsNetCapabilities(nc2)); + + nc1.removeForbiddenCapability(NET_CAPABILITY_INTERNET); assertFalse(nc1.equalsNetCapabilities(nc2)); - nc2.removeCapability(NET_CAPABILITY_INTERNET); + nc2.removeForbiddenCapability(NET_CAPABILITY_INTERNET); assertTrue(nc1.equalsNetCapabilities(nc2)); } } @@ -581,31 +579,25 @@ public class NetworkCapabilitiesTest { NetworkCapabilities nc1 = new NetworkCapabilities(); NetworkCapabilities nc2 = new NetworkCapabilities(); - nc1.addUnwantedCapability(NET_CAPABILITY_CAPTIVE_PORTAL); + if (isAtLeastS()) { + nc1.addForbiddenCapability(NET_CAPABILITY_CAPTIVE_PORTAL); + } nc1.addCapability(NET_CAPABILITY_NOT_ROAMING); assertNotEquals(nc1, nc2); nc2.combineCapabilities(nc1); assertEquals(nc1, nc2); assertTrue(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING)); - assertTrue(nc2.hasUnwantedCapability(NET_CAPABILITY_CAPTIVE_PORTAL)); - - // This will effectively move NOT_ROAMING capability from required to unwanted for nc1. - nc1.addUnwantedCapability(NET_CAPABILITY_NOT_ROAMING); + if (isAtLeastS()) { + assertTrue(nc2.hasForbiddenCapability(NET_CAPABILITY_CAPTIVE_PORTAL)); + } if (isAtLeastS()) { - // From S, it is not allowed to have the same capability in both wanted and - // unwanted list. + // This will effectively move NOT_ROAMING capability from required to forbidden for nc1. + nc1.addForbiddenCapability(NET_CAPABILITY_NOT_ROAMING); + // It is not allowed to have the same capability in both wanted and forbidden list. assertThrows(IllegalArgumentException.class, () -> nc2.combineCapabilities(nc1)); - // Remove unwanted capability to continue other tests. - nc1.removeUnwantedCapability(NET_CAPABILITY_NOT_ROAMING); - } else { - nc2.combineCapabilities(nc1); - // We will get this capability in both requested and unwanted lists thus this request - // will never be satisfied. - assertTrue(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING)); - assertTrue(nc2.hasUnwantedCapability(NET_CAPABILITY_NOT_ROAMING)); - // For R or below, remove unwanted capability via removeCapability. - nc1.removeCapability(NET_CAPABILITY_NOT_ROAMING); + // Remove forbidden capability to continue other tests. + nc1.removeForbiddenCapability(NET_CAPABILITY_NOT_ROAMING); } nc1.setSSID(TEST_SSID); @@ -683,14 +675,11 @@ public class NetworkCapabilitiesTest { public void testSetCapabilities() { final int[] REQUIRED_CAPABILITIES = new int[] { NET_CAPABILITY_INTERNET, NET_CAPABILITY_NOT_VPN }; - final int[] UNWANTED_CAPABILITIES = new int[] { - NET_CAPABILITY_NOT_RESTRICTED, NET_CAPABILITY_NOT_METERED - }; NetworkCapabilities nc1 = new NetworkCapabilities(); NetworkCapabilities nc2 = new NetworkCapabilities(); - nc1.setCapabilities(REQUIRED_CAPABILITIES, UNWANTED_CAPABILITIES); + nc1.setCapabilities(REQUIRED_CAPABILITIES); assertArrayEquals(REQUIRED_CAPABILITIES, nc1.getCapabilities()); // Verify that setting and adding capabilities leads to the same object state. @@ -698,10 +687,25 @@ public class NetworkCapabilitiesTest { for (int cap : REQUIRED_CAPABILITIES) { nc2.addCapability(cap); } - for (int cap : UNWANTED_CAPABILITIES) { - nc2.addUnwantedCapability(cap); - } assertEquals(nc1, nc2); + + if (isAtLeastS()) { + final int[] forbiddenCapabilities = new int[]{ + NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_NOT_RESTRICTED }; + + nc1.setCapabilities(REQUIRED_CAPABILITIES, forbiddenCapabilities); + assertArrayEquals(REQUIRED_CAPABILITIES, nc1.getCapabilities()); + assertArrayEquals(forbiddenCapabilities, nc1.getForbiddenCapabilities()); + + nc2.clearAll(); + for (int cap : REQUIRED_CAPABILITIES) { + nc2.addCapability(cap); + } + for (int cap : forbiddenCapabilities) { + nc2.addForbiddenCapability(cap); + } + assertEquals(nc1, nc2); + } } @Test @@ -769,23 +773,32 @@ public class NetworkCapabilitiesTest { NetworkCapabilities nc1 = new NetworkCapabilities(); NetworkCapabilities nc2 = new NetworkCapabilities(); - nc1.addUnwantedCapability(NET_CAPABILITY_CAPTIVE_PORTAL); + if (isAtLeastS()) { + nc1.addForbiddenCapability(NET_CAPABILITY_CAPTIVE_PORTAL); + } nc1.addCapability(NET_CAPABILITY_NOT_ROAMING); assertNotEquals(nc1, nc2); nc2.set(nc1); assertEquals(nc1, nc2); assertTrue(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING)); - assertTrue(nc2.hasUnwantedCapability(NET_CAPABILITY_CAPTIVE_PORTAL)); + if (isAtLeastS()) { + assertTrue(nc2.hasForbiddenCapability(NET_CAPABILITY_CAPTIVE_PORTAL)); + } - // This will effectively move NOT_ROAMING capability from required to unwanted for nc1. - nc1.addUnwantedCapability(NET_CAPABILITY_NOT_ROAMING); + if (isAtLeastS()) { + // This will effectively move NOT_ROAMING capability from required to forbidden for nc1. + nc1.addForbiddenCapability(NET_CAPABILITY_NOT_ROAMING); + } nc1.setSSID(TEST_SSID); nc2.set(nc1); assertEquals(nc1, nc2); - // Contrary to combineCapabilities, set() will have removed the NOT_ROAMING capability - // from nc2. - assertFalse(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING)); - assertTrue(nc2.hasUnwantedCapability(NET_CAPABILITY_NOT_ROAMING)); + if (isAtLeastS()) { + // Contrary to combineCapabilities, set() will have removed the NOT_ROAMING capability + // from nc2. + assertFalse(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING)); + assertTrue(nc2.hasForbiddenCapability(NET_CAPABILITY_NOT_ROAMING)); + } + if (isAtLeastR()) { assertTrue(TEST_SSID.equals(nc2.getSsid())); } diff --git a/tests/net/common/java/android/net/NetworkProviderTest.kt b/packages/Connectivity/tests/common/java/android/net/NetworkProviderTest.kt index 340e6f963137..340e6f963137 100644 --- a/tests/net/common/java/android/net/NetworkProviderTest.kt +++ b/packages/Connectivity/tests/common/java/android/net/NetworkProviderTest.kt diff --git a/tests/net/common/java/android/net/NetworkSpecifierTest.kt b/packages/Connectivity/tests/common/java/android/net/NetworkSpecifierTest.kt index f3409f53596f..f3409f53596f 100644 --- a/tests/net/common/java/android/net/NetworkSpecifierTest.kt +++ b/packages/Connectivity/tests/common/java/android/net/NetworkSpecifierTest.kt diff --git a/tests/net/common/java/android/net/NetworkStackTest.java b/packages/Connectivity/tests/common/java/android/net/NetworkStackTest.java index f8f9c72374ad..f8f9c72374ad 100644 --- a/tests/net/common/java/android/net/NetworkStackTest.java +++ b/packages/Connectivity/tests/common/java/android/net/NetworkStackTest.java diff --git a/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt b/packages/Connectivity/tests/common/java/android/net/NetworkStateSnapshotTest.kt index 0ca4d9551f39..0ca4d9551f39 100644 --- a/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt +++ b/packages/Connectivity/tests/common/java/android/net/NetworkStateSnapshotTest.kt diff --git a/tests/net/common/java/android/net/NetworkTest.java b/packages/Connectivity/tests/common/java/android/net/NetworkTest.java index 11d44b86bc50..11d44b86bc50 100644 --- a/tests/net/common/java/android/net/NetworkTest.java +++ b/packages/Connectivity/tests/common/java/android/net/NetworkTest.java diff --git a/tests/net/common/java/android/net/OemNetworkPreferencesTest.java b/packages/Connectivity/tests/common/java/android/net/OemNetworkPreferencesTest.java index fd29a9539de8..fd29a9539de8 100644 --- a/tests/net/common/java/android/net/OemNetworkPreferencesTest.java +++ b/packages/Connectivity/tests/common/java/android/net/OemNetworkPreferencesTest.java diff --git a/tests/net/common/java/android/net/RouteInfoTest.java b/packages/Connectivity/tests/common/java/android/net/RouteInfoTest.java index 71689f919726..71689f919726 100644 --- a/tests/net/common/java/android/net/RouteInfoTest.java +++ b/packages/Connectivity/tests/common/java/android/net/RouteInfoTest.java diff --git a/tests/net/common/java/android/net/StaticIpConfigurationTest.java b/packages/Connectivity/tests/common/java/android/net/StaticIpConfigurationTest.java index b5f23bf19a3c..b5f23bf19a3c 100644 --- a/tests/net/common/java/android/net/StaticIpConfigurationTest.java +++ b/packages/Connectivity/tests/common/java/android/net/StaticIpConfigurationTest.java diff --git a/tests/net/common/java/android/net/TcpKeepalivePacketDataTest.kt b/packages/Connectivity/tests/common/java/android/net/TcpKeepalivePacketDataTest.kt index 7a18bb08faa8..7a18bb08faa8 100644 --- a/tests/net/common/java/android/net/TcpKeepalivePacketDataTest.kt +++ b/packages/Connectivity/tests/common/java/android/net/TcpKeepalivePacketDataTest.kt diff --git a/tests/net/common/java/android/net/UidRangeTest.java b/packages/Connectivity/tests/common/java/android/net/UidRangeTest.java index 1b1c95431d6f..1b1c95431d6f 100644 --- a/tests/net/common/java/android/net/UidRangeTest.java +++ b/packages/Connectivity/tests/common/java/android/net/UidRangeTest.java diff --git a/tests/net/common/java/android/net/UnderlyingNetworkInfoTest.kt b/packages/Connectivity/tests/common/java/android/net/UnderlyingNetworkInfoTest.kt index 87cfb345e5e0..87cfb345e5e0 100644 --- a/tests/net/common/java/android/net/UnderlyingNetworkInfoTest.kt +++ b/packages/Connectivity/tests/common/java/android/net/UnderlyingNetworkInfoTest.kt diff --git a/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java b/packages/Connectivity/tests/common/java/android/net/apf/ApfCapabilitiesTest.java index d50406fd3a1c..d50406fd3a1c 100644 --- a/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java +++ b/packages/Connectivity/tests/common/java/android/net/apf/ApfCapabilitiesTest.java diff --git a/tests/net/common/java/android/net/metrics/ApfProgramEventTest.kt b/packages/Connectivity/tests/common/java/android/net/metrics/ApfProgramEventTest.kt index 0b7b74097cc6..0b7b74097cc6 100644 --- a/tests/net/common/java/android/net/metrics/ApfProgramEventTest.kt +++ b/packages/Connectivity/tests/common/java/android/net/metrics/ApfProgramEventTest.kt diff --git a/tests/net/common/java/android/net/metrics/ApfStatsTest.kt b/packages/Connectivity/tests/common/java/android/net/metrics/ApfStatsTest.kt index 46a8c8e5b509..46a8c8e5b509 100644 --- a/tests/net/common/java/android/net/metrics/ApfStatsTest.kt +++ b/packages/Connectivity/tests/common/java/android/net/metrics/ApfStatsTest.kt diff --git a/tests/net/common/java/android/net/metrics/DhcpClientEventTest.kt b/packages/Connectivity/tests/common/java/android/net/metrics/DhcpClientEventTest.kt index 8d7a9c405024..8d7a9c405024 100644 --- a/tests/net/common/java/android/net/metrics/DhcpClientEventTest.kt +++ b/packages/Connectivity/tests/common/java/android/net/metrics/DhcpClientEventTest.kt diff --git a/tests/net/common/java/android/net/metrics/DhcpErrorEventTest.kt b/packages/Connectivity/tests/common/java/android/net/metrics/DhcpErrorEventTest.kt index 236f72eafbdc..236f72eafbdc 100644 --- a/tests/net/common/java/android/net/metrics/DhcpErrorEventTest.kt +++ b/packages/Connectivity/tests/common/java/android/net/metrics/DhcpErrorEventTest.kt diff --git a/tests/net/common/java/android/net/metrics/IpConnectivityLogTest.java b/packages/Connectivity/tests/common/java/android/net/metrics/IpConnectivityLogTest.java index d4780d3a5d7b..d4780d3a5d7b 100644 --- a/tests/net/common/java/android/net/metrics/IpConnectivityLogTest.java +++ b/packages/Connectivity/tests/common/java/android/net/metrics/IpConnectivityLogTest.java diff --git a/tests/net/common/java/android/net/metrics/IpManagerEventTest.kt b/packages/Connectivity/tests/common/java/android/net/metrics/IpManagerEventTest.kt index 64be50837fc9..64be50837fc9 100644 --- a/tests/net/common/java/android/net/metrics/IpManagerEventTest.kt +++ b/packages/Connectivity/tests/common/java/android/net/metrics/IpManagerEventTest.kt diff --git a/tests/net/common/java/android/net/metrics/IpReachabilityEventTest.kt b/packages/Connectivity/tests/common/java/android/net/metrics/IpReachabilityEventTest.kt index 55b5e492dd47..55b5e492dd47 100644 --- a/tests/net/common/java/android/net/metrics/IpReachabilityEventTest.kt +++ b/packages/Connectivity/tests/common/java/android/net/metrics/IpReachabilityEventTest.kt diff --git a/tests/net/common/java/android/net/metrics/NetworkEventTest.kt b/packages/Connectivity/tests/common/java/android/net/metrics/NetworkEventTest.kt index 41430b03a1eb..41430b03a1eb 100644 --- a/tests/net/common/java/android/net/metrics/NetworkEventTest.kt +++ b/packages/Connectivity/tests/common/java/android/net/metrics/NetworkEventTest.kt diff --git a/tests/net/common/java/android/net/metrics/RaEventTest.kt b/packages/Connectivity/tests/common/java/android/net/metrics/RaEventTest.kt index d9b720332fbe..d9b720332fbe 100644 --- a/tests/net/common/java/android/net/metrics/RaEventTest.kt +++ b/packages/Connectivity/tests/common/java/android/net/metrics/RaEventTest.kt diff --git a/tests/net/common/java/android/net/metrics/ValidationProbeEventTest.kt b/packages/Connectivity/tests/common/java/android/net/metrics/ValidationProbeEventTest.kt index 51c0d41bf4d5..51c0d41bf4d5 100644 --- a/tests/net/common/java/android/net/metrics/ValidationProbeEventTest.kt +++ b/packages/Connectivity/tests/common/java/android/net/metrics/ValidationProbeEventTest.kt diff --git a/tests/net/common/java/android/net/netstats/NetworkStatsApiTest.kt b/packages/Connectivity/tests/common/java/android/net/netstats/NetworkStatsApiTest.kt index 7b22e45db90a..7b22e45db90a 100644 --- a/tests/net/common/java/android/net/netstats/NetworkStatsApiTest.kt +++ b/packages/Connectivity/tests/common/java/android/net/netstats/NetworkStatsApiTest.kt diff --git a/tests/net/common/java/android/net/util/SocketUtilsTest.kt b/packages/Connectivity/tests/common/java/android/net/util/SocketUtilsTest.kt index aaf97f36889b..aaf97f36889b 100644 --- a/tests/net/common/java/android/net/util/SocketUtilsTest.kt +++ b/packages/Connectivity/tests/common/java/android/net/util/SocketUtilsTest.kt diff --git a/tests/net/deflake/Android.bp b/packages/Connectivity/tests/deflake/Android.bp index 58ece37ef647..58ece37ef647 100644 --- a/tests/net/deflake/Android.bp +++ b/packages/Connectivity/tests/deflake/Android.bp diff --git a/tests/net/deflake/src/com/android/server/net/FrameworksNetDeflakeTest.kt b/packages/Connectivity/tests/deflake/src/com/android/server/net/FrameworksNetDeflakeTest.kt index 62855255fec2..62855255fec2 100644 --- a/tests/net/deflake/src/com/android/server/net/FrameworksNetDeflakeTest.kt +++ b/packages/Connectivity/tests/deflake/src/com/android/server/net/FrameworksNetDeflakeTest.kt diff --git a/tests/net/integration/Android.bp b/packages/Connectivity/tests/integration/Android.bp index 56f9df78c83e..56f9df78c83e 100644 --- a/tests/net/integration/Android.bp +++ b/packages/Connectivity/tests/integration/Android.bp diff --git a/tests/net/integration/AndroidManifest.xml b/packages/Connectivity/tests/integration/AndroidManifest.xml index 2e1368935759..2e1368935759 100644 --- a/tests/net/integration/AndroidManifest.xml +++ b/packages/Connectivity/tests/integration/AndroidManifest.xml diff --git a/tests/net/integration/res/values/config.xml b/packages/Connectivity/tests/integration/res/values/config.xml index 2c8046ffd781..2c8046ffd781 100644 --- a/tests/net/integration/res/values/config.xml +++ b/packages/Connectivity/tests/integration/res/values/config.xml diff --git a/tests/net/integration/src/android/net/TestNetworkStackClient.kt b/packages/Connectivity/tests/integration/src/android/net/TestNetworkStackClient.kt index 01eb514a1c81..01eb514a1c81 100644 --- a/tests/net/integration/src/android/net/TestNetworkStackClient.kt +++ b/packages/Connectivity/tests/integration/src/android/net/TestNetworkStackClient.kt diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt index b6e42743e2a3..b6e42743e2a3 100644 --- a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt +++ b/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/HttpResponse.aidl b/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/HttpResponse.aidl index 9a2bcfea7641..9a2bcfea7641 100644 --- a/tests/net/integration/src/com/android/server/net/integrationtests/HttpResponse.aidl +++ b/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/HttpResponse.aidl diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/HttpResponse.kt b/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/HttpResponse.kt index e2063138fef1..e2063138fef1 100644 --- a/tests/net/integration/src/com/android/server/net/integrationtests/HttpResponse.kt +++ b/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/HttpResponse.kt diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/INetworkStackInstrumentation.aidl b/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/INetworkStackInstrumentation.aidl index efc58add9cf5..efc58add9cf5 100644 --- a/tests/net/integration/src/com/android/server/net/integrationtests/INetworkStackInstrumentation.aidl +++ b/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/INetworkStackInstrumentation.aidl diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/NetworkStackInstrumentationService.kt b/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/NetworkStackInstrumentationService.kt index e807952cec11..e807952cec11 100644 --- a/tests/net/integration/src/com/android/server/net/integrationtests/NetworkStackInstrumentationService.kt +++ b/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/NetworkStackInstrumentationService.kt diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt b/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt index a44ad1e05259..eff66584d6c1 100644 --- a/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt +++ b/packages/Connectivity/tests/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt @@ -61,7 +61,6 @@ class TestNetworkStackService : Service() { private class NetworkMonitorDeps(private val privateDnsBypassNetwork: Network) : NetworkMonitor.Dependencies() { override fun getPrivateDnsBypassNetwork(network: Network?) = privateDnsBypassNetwork - override fun sendNetworkConditionsBroadcast(context: Context, broadcast: Intent) = Unit } private inner class TestNetworkStackConnector(context: Context) : NetworkStackConnector( @@ -98,4 +97,4 @@ class TestNetworkStackService : Service() { cb.onNetworkMonitorCreated(NetworkMonitorConnector(nm, TestPermissionChecker())) } } -}
\ No newline at end of file +} diff --git a/tests/net/integration/util/com/android/server/ConnectivityServiceTestUtils.kt b/packages/Connectivity/tests/integration/util/com/android/server/ConnectivityServiceTestUtils.kt index 165fd3728281..165fd3728281 100644 --- a/tests/net/integration/util/com/android/server/ConnectivityServiceTestUtils.kt +++ b/packages/Connectivity/tests/integration/util/com/android/server/ConnectivityServiceTestUtils.kt diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/packages/Connectivity/tests/integration/util/com/android/server/NetworkAgentWrapper.java index e2d43cbb8efd..e80955014fe7 100644 --- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java +++ b/packages/Connectivity/tests/integration/util/com/android/server/NetworkAgentWrapper.java @@ -370,4 +370,8 @@ public class NetworkAgentWrapper implements TestableNetworkCallback.HasNetwork { } } } + + public boolean isBypassableVpn() { + return mNetworkAgentConfig.isBypassableVpn(); + } } diff --git a/tests/net/integration/util/com/android/server/TestNetIdManager.kt b/packages/Connectivity/tests/integration/util/com/android/server/TestNetIdManager.kt index 938a694e8ba9..938a694e8ba9 100644 --- a/tests/net/integration/util/com/android/server/TestNetIdManager.kt +++ b/packages/Connectivity/tests/integration/util/com/android/server/TestNetIdManager.kt diff --git a/tests/net/smoketest/Android.bp b/packages/Connectivity/tests/smoketest/Android.bp index 1535f3ddcb38..1535f3ddcb38 100644 --- a/tests/net/smoketest/Android.bp +++ b/packages/Connectivity/tests/smoketest/Android.bp diff --git a/tests/net/smoketest/AndroidManifest.xml b/packages/Connectivity/tests/smoketest/AndroidManifest.xml index f1b9febb9f57..f1b9febb9f57 100644 --- a/tests/net/smoketest/AndroidManifest.xml +++ b/packages/Connectivity/tests/smoketest/AndroidManifest.xml diff --git a/tests/net/smoketest/AndroidTest.xml b/packages/Connectivity/tests/smoketest/AndroidTest.xml index ac366e4ac544..ac366e4ac544 100644 --- a/tests/net/smoketest/AndroidTest.xml +++ b/packages/Connectivity/tests/smoketest/AndroidTest.xml diff --git a/tests/net/smoketest/java/SmokeTest.java b/packages/Connectivity/tests/smoketest/java/SmokeTest.java index 7d6655fde15e..7d6655fde15e 100644 --- a/tests/net/smoketest/java/SmokeTest.java +++ b/packages/Connectivity/tests/smoketest/java/SmokeTest.java diff --git a/tests/net/Android.bp b/packages/Connectivity/tests/unit/Android.bp index e1a424f214a5..e1a424f214a5 100644 --- a/tests/net/Android.bp +++ b/packages/Connectivity/tests/unit/Android.bp diff --git a/tests/net/AndroidManifest.xml b/packages/Connectivity/tests/unit/AndroidManifest.xml index d08b2f8d40dd..d08b2f8d40dd 100644 --- a/tests/net/AndroidManifest.xml +++ b/packages/Connectivity/tests/unit/AndroidManifest.xml diff --git a/tests/net/AndroidTest.xml b/packages/Connectivity/tests/unit/AndroidTest.xml index 939ae493b280..939ae493b280 100644 --- a/tests/net/AndroidTest.xml +++ b/packages/Connectivity/tests/unit/AndroidTest.xml diff --git a/tests/net/jarjar-rules.txt b/packages/Connectivity/tests/unit/jarjar-rules.txt index ca8867206dda..ca8867206dda 100644 --- a/tests/net/jarjar-rules.txt +++ b/packages/Connectivity/tests/unit/jarjar-rules.txt diff --git a/tests/net/java/android/app/usage/NetworkStatsManagerTest.java b/packages/Connectivity/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java index 899295a019d2..899295a019d2 100644 --- a/tests/net/java/android/app/usage/NetworkStatsManagerTest.java +++ b/packages/Connectivity/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java diff --git a/tests/net/java/android/net/ConnectivityDiagnosticsManagerTest.java b/packages/Connectivity/tests/unit/java/android/net/ConnectivityDiagnosticsManagerTest.java index 06e9405a6a79..06e9405a6a79 100644 --- a/tests/net/java/android/net/ConnectivityDiagnosticsManagerTest.java +++ b/packages/Connectivity/tests/unit/java/android/net/ConnectivityDiagnosticsManagerTest.java diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/packages/Connectivity/tests/unit/java/android/net/ConnectivityManagerTest.java index 591e0cc3504e..591e0cc3504e 100644 --- a/tests/net/java/android/net/ConnectivityManagerTest.java +++ b/packages/Connectivity/tests/unit/java/android/net/ConnectivityManagerTest.java diff --git a/tests/net/java/android/net/Ikev2VpnProfileTest.java b/packages/Connectivity/tests/unit/java/android/net/Ikev2VpnProfileTest.java index 1abd39a32bdf..1abd39a32bdf 100644 --- a/tests/net/java/android/net/Ikev2VpnProfileTest.java +++ b/packages/Connectivity/tests/unit/java/android/net/Ikev2VpnProfileTest.java diff --git a/tests/net/java/android/net/IpMemoryStoreTest.java b/packages/Connectivity/tests/unit/java/android/net/IpMemoryStoreTest.java index 0b13800bc5c9..0b13800bc5c9 100644 --- a/tests/net/java/android/net/IpMemoryStoreTest.java +++ b/packages/Connectivity/tests/unit/java/android/net/IpMemoryStoreTest.java diff --git a/tests/net/java/android/net/IpSecAlgorithmTest.java b/packages/Connectivity/tests/unit/java/android/net/IpSecAlgorithmTest.java index 3a8d6004f66f..3a8d6004f66f 100644 --- a/tests/net/java/android/net/IpSecAlgorithmTest.java +++ b/packages/Connectivity/tests/unit/java/android/net/IpSecAlgorithmTest.java diff --git a/tests/net/java/android/net/IpSecConfigTest.java b/packages/Connectivity/tests/unit/java/android/net/IpSecConfigTest.java index 25e225ef303a..25e225ef303a 100644 --- a/tests/net/java/android/net/IpSecConfigTest.java +++ b/packages/Connectivity/tests/unit/java/android/net/IpSecConfigTest.java diff --git a/tests/net/java/android/net/IpSecManagerTest.java b/packages/Connectivity/tests/unit/java/android/net/IpSecManagerTest.java index 730e2d56bd78..730e2d56bd78 100644 --- a/tests/net/java/android/net/IpSecManagerTest.java +++ b/packages/Connectivity/tests/unit/java/android/net/IpSecManagerTest.java diff --git a/tests/net/java/android/net/IpSecTransformTest.java b/packages/Connectivity/tests/unit/java/android/net/IpSecTransformTest.java index 424f23dbbaf6..424f23dbbaf6 100644 --- a/tests/net/java/android/net/IpSecTransformTest.java +++ b/packages/Connectivity/tests/unit/java/android/net/IpSecTransformTest.java diff --git a/tests/net/java/android/net/KeepalivePacketDataUtilTest.java b/packages/Connectivity/tests/unit/java/android/net/KeepalivePacketDataUtilTest.java index fc739fbfac61..fc739fbfac61 100644 --- a/tests/net/java/android/net/KeepalivePacketDataUtilTest.java +++ b/packages/Connectivity/tests/unit/java/android/net/KeepalivePacketDataUtilTest.java diff --git a/tests/net/java/android/net/MacAddressTest.java b/packages/Connectivity/tests/unit/java/android/net/MacAddressTest.java index 6de31f6b4be1..6de31f6b4be1 100644 --- a/tests/net/java/android/net/MacAddressTest.java +++ b/packages/Connectivity/tests/unit/java/android/net/MacAddressTest.java diff --git a/tests/net/java/android/net/NetworkIdentityTest.kt b/packages/Connectivity/tests/unit/java/android/net/NetworkIdentityTest.kt index eb2b85c14578..eb2b85c14578 100644 --- a/tests/net/java/android/net/NetworkIdentityTest.kt +++ b/packages/Connectivity/tests/unit/java/android/net/NetworkIdentityTest.kt diff --git a/tests/net/java/android/net/NetworkStatsHistoryTest.java b/packages/Connectivity/tests/unit/java/android/net/NetworkStatsHistoryTest.java index 13558cd51c28..13558cd51c28 100644 --- a/tests/net/java/android/net/NetworkStatsHistoryTest.java +++ b/packages/Connectivity/tests/unit/java/android/net/NetworkStatsHistoryTest.java diff --git a/tests/net/java/android/net/NetworkStatsTest.java b/packages/Connectivity/tests/unit/java/android/net/NetworkStatsTest.java index 23d5a7e5d5f8..23d5a7e5d5f8 100644 --- a/tests/net/java/android/net/NetworkStatsTest.java +++ b/packages/Connectivity/tests/unit/java/android/net/NetworkStatsTest.java diff --git a/tests/net/java/android/net/NetworkTemplateTest.kt b/packages/Connectivity/tests/unit/java/android/net/NetworkTemplateTest.kt index ab6b2f409867..ab6b2f409867 100644 --- a/tests/net/java/android/net/NetworkTemplateTest.kt +++ b/packages/Connectivity/tests/unit/java/android/net/NetworkTemplateTest.kt diff --git a/tests/net/java/android/net/NetworkUtilsTest.java b/packages/Connectivity/tests/unit/java/android/net/NetworkUtilsTest.java index 7748288aeb05..7748288aeb05 100644 --- a/tests/net/java/android/net/NetworkUtilsTest.java +++ b/packages/Connectivity/tests/unit/java/android/net/NetworkUtilsTest.java diff --git a/tests/net/java/android/net/QosSocketFilterTest.java b/packages/Connectivity/tests/unit/java/android/net/QosSocketFilterTest.java index ad58960eaadd..ad58960eaadd 100644 --- a/tests/net/java/android/net/QosSocketFilterTest.java +++ b/packages/Connectivity/tests/unit/java/android/net/QosSocketFilterTest.java diff --git a/tests/net/java/android/net/TelephonyNetworkSpecifierTest.java b/packages/Connectivity/tests/unit/java/android/net/TelephonyNetworkSpecifierTest.java index 6714bb1abbe6..6714bb1abbe6 100644 --- a/tests/net/java/android/net/TelephonyNetworkSpecifierTest.java +++ b/packages/Connectivity/tests/unit/java/android/net/TelephonyNetworkSpecifierTest.java diff --git a/tests/net/java/android/net/VpnManagerTest.java b/packages/Connectivity/tests/unit/java/android/net/VpnManagerTest.java index c548e30761c9..3135062138ac 100644 --- a/tests/net/java/android/net/VpnManagerTest.java +++ b/packages/Connectivity/tests/unit/java/android/net/VpnManagerTest.java @@ -28,11 +28,13 @@ import static org.mockito.Mockito.when; import android.content.ComponentName; import android.content.Intent; import android.test.mock.MockContext; +import android.util.SparseArray; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.internal.net.VpnProfile; +import com.android.internal.util.MessageUtils; import org.junit.Before; import org.junit.Test; @@ -119,4 +121,18 @@ public class VpnManagerTest { .setAuthPsk(PSK_BYTES) .build(); } + + @Test + public void testVpnTypesEqual() throws Exception { + SparseArray<String> vmVpnTypes = MessageUtils.findMessageNames( + new Class[] { VpnManager.class }, new String[]{ "TYPE_VPN_" }); + SparseArray<String> nativeVpnType = MessageUtils.findMessageNames( + new Class[] { NativeVpnType.class }, new String[]{ "" }); + + // TYPE_VPN_NONE = -1 is only defined in VpnManager. + assertEquals(vmVpnTypes.size() - 1, nativeVpnType.size()); + for (int i = VpnManager.TYPE_VPN_SERVICE; i < vmVpnTypes.size(); i++) { + assertEquals(vmVpnTypes.get(i), "TYPE_VPN_" + nativeVpnType.get(i)); + } + } } diff --git a/tests/net/java/android/net/VpnTransportInfoTest.java b/packages/Connectivity/tests/unit/java/android/net/VpnTransportInfoTest.java index ccaa5cf7e9f7..ccaa5cf7e9f7 100644 --- a/tests/net/java/android/net/VpnTransportInfoTest.java +++ b/packages/Connectivity/tests/unit/java/android/net/VpnTransportInfoTest.java diff --git a/tests/net/java/android/net/ipmemorystore/ParcelableTests.java b/packages/Connectivity/tests/unit/java/android/net/ipmemorystore/ParcelableTests.java index 603c87519532..603c87519532 100644 --- a/tests/net/java/android/net/ipmemorystore/ParcelableTests.java +++ b/packages/Connectivity/tests/unit/java/android/net/ipmemorystore/ParcelableTests.java diff --git a/tests/net/java/android/net/nsd/NsdManagerTest.java b/packages/Connectivity/tests/unit/java/android/net/nsd/NsdManagerTest.java index b0a9b8a55322..b0a9b8a55322 100644 --- a/tests/net/java/android/net/nsd/NsdManagerTest.java +++ b/packages/Connectivity/tests/unit/java/android/net/nsd/NsdManagerTest.java diff --git a/tests/net/java/android/net/nsd/NsdServiceInfoTest.java b/packages/Connectivity/tests/unit/java/android/net/nsd/NsdServiceInfoTest.java index 94dfc7515c67..94dfc7515c67 100644 --- a/tests/net/java/android/net/nsd/NsdServiceInfoTest.java +++ b/packages/Connectivity/tests/unit/java/android/net/nsd/NsdServiceInfoTest.java diff --git a/tests/net/java/android/net/util/DnsUtilsTest.java b/packages/Connectivity/tests/unit/java/android/net/util/DnsUtilsTest.java index b626db8d89e4..b626db8d89e4 100644 --- a/tests/net/java/android/net/util/DnsUtilsTest.java +++ b/packages/Connectivity/tests/unit/java/android/net/util/DnsUtilsTest.java diff --git a/tests/net/java/android/net/util/KeepaliveUtilsTest.kt b/packages/Connectivity/tests/unit/java/android/net/util/KeepaliveUtilsTest.kt index b62bdbcfb5eb..b62bdbcfb5eb 100644 --- a/tests/net/java/android/net/util/KeepaliveUtilsTest.kt +++ b/packages/Connectivity/tests/unit/java/android/net/util/KeepaliveUtilsTest.kt diff --git a/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt b/packages/Connectivity/tests/unit/java/android/net/util/MultinetworkPolicyTrackerTest.kt index 25aa6266577e..25aa6266577e 100644 --- a/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt +++ b/packages/Connectivity/tests/unit/java/android/net/util/MultinetworkPolicyTrackerTest.kt diff --git a/tests/net/java/com/android/internal/net/NetworkUtilsInternalTest.java b/packages/Connectivity/tests/unit/java/com/android/internal/net/NetworkUtilsInternalTest.java index 3cfecd552967..3cfecd552967 100644 --- a/tests/net/java/com/android/internal/net/NetworkUtilsInternalTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/internal/net/NetworkUtilsInternalTest.java diff --git a/tests/net/java/com/android/internal/net/VpnProfileTest.java b/packages/Connectivity/tests/unit/java/com/android/internal/net/VpnProfileTest.java index 46597d19ef1b..46597d19ef1b 100644 --- a/tests/net/java/com/android/internal/net/VpnProfileTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/internal/net/VpnProfileTest.java diff --git a/tests/net/java/com/android/internal/util/BitUtilsTest.java b/packages/Connectivity/tests/unit/java/com/android/internal/util/BitUtilsTest.java index d2fbdce9771a..d2fbdce9771a 100644 --- a/tests/net/java/com/android/internal/util/BitUtilsTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/internal/util/BitUtilsTest.java diff --git a/tests/net/java/com/android/internal/util/RingBufferTest.java b/packages/Connectivity/tests/unit/java/com/android/internal/util/RingBufferTest.java index d06095a690cf..d06095a690cf 100644 --- a/tests/net/java/com/android/internal/util/RingBufferTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/internal/util/RingBufferTest.java diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/packages/Connectivity/tests/unit/java/com/android/server/ConnectivityServiceTest.java index bc06a6e43fff..221cc9b26ae4 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/ConnectivityServiceTest.java @@ -19,6 +19,7 @@ package com.android.server; import static android.Manifest.permission.CHANGE_NETWORK_STATE; import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS; import static android.Manifest.permission.DUMP; +import static android.Manifest.permission.LOCAL_MAC_ADDRESS; import static android.Manifest.permission.NETWORK_FACTORY; import static android.Manifest.permission.NETWORK_SETTINGS; import static android.app.PendingIntent.FLAG_IMMUTABLE; @@ -44,9 +45,6 @@ import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO; import static android.net.ConnectivityManager.EXTRA_NETWORK_TYPE; -import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF; -import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; -import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT; import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE; import static android.net.ConnectivityManager.TYPE_ETHERNET; @@ -57,6 +55,9 @@ import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL; import static android.net.ConnectivityManager.TYPE_PROXY; import static android.net.ConnectivityManager.TYPE_VPN; import static android.net.ConnectivityManager.TYPE_WIFI; +import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OFF; +import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; +import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS; import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK; import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTP; @@ -211,6 +212,8 @@ import android.net.IpSecManager.UdpEncapsulationSocket; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.MatchAllNetworkSpecifier; +import android.net.NativeNetworkConfig; +import android.net.NativeNetworkType; import android.net.Network; import android.net.NetworkAgent; import android.net.NetworkAgentConfig; @@ -1253,6 +1256,8 @@ public class ConnectivityServiceTest { verify(mMockNetd, never()) .networkRemoveUidRanges(eq(mMockVpn.getNetwork().getNetId()), any()); mAgentRegistered = true; + verify(mMockNetd).networkCreate(nativeNetworkConfigVpn(getNetwork().netId, + !mMockNetworkAgent.isBypassableVpn(), mVpnType)); updateState(NetworkInfo.DetailedState.CONNECTED, "registerAgent"); mNetworkCapabilities.set(mMockNetworkAgent.getNetworkCapabilities()); mNetworkAgent = mMockNetworkAgent.getNetworkAgent(); @@ -2809,8 +2814,9 @@ public class ConnectivityServiceTest { private void grantUsingBackgroundNetworksPermissionForUid( final int uid, final String packageName) throws Exception { - when(mPackageManager.getPackageInfo(eq(packageName), eq(GET_PERMISSIONS))) - .thenReturn(buildPackageInfo(true, uid)); + when(mPackageManager.getPackageInfo( + eq(packageName), eq(GET_PERMISSIONS | MATCH_ANY_USER))) + .thenReturn(buildPackageInfo(true /* hasSystemPermission */, uid)); mService.mPermissionMonitor.onPackageAdded(packageName, uid); } @@ -2860,6 +2866,16 @@ public class ConnectivityServiceTest { mCm.unregisterNetworkCallback(callback); } + private NativeNetworkConfig nativeNetworkConfigPhysical(int netId, int permission) { + return new NativeNetworkConfig(netId, NativeNetworkType.PHYSICAL, permission, + /*secure=*/ false, VpnManager.TYPE_VPN_NONE); + } + + private NativeNetworkConfig nativeNetworkConfigVpn(int netId, boolean secure, int vpnType) { + return new NativeNetworkConfig(netId, NativeNetworkType.VIRTUAL, INetd.PERMISSION_NONE, + secure, vpnType); + } + @Test public void testNetworkAgentCallbacks() throws Exception { // Keeps track of the order of events that happen in this test. @@ -2881,8 +2897,8 @@ public class ConnectivityServiceTest { wifiNetwork.set(mWiFiNetworkAgent.getNetwork()); assertNotNull(wifiNetwork.get()); try { - verify(mMockNetd).networkCreatePhysical(wifiNetwork.get().getNetId(), - INetd.PERMISSION_NONE); + verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( + wifiNetwork.get().getNetId(), INetd.PERMISSION_NONE)); } catch (RemoteException impossible) { fail(); } @@ -4242,10 +4258,9 @@ public class ConnectivityServiceTest { waitForIdle(); } - private void setPrivateDnsSettings(String mode, String specifier) { - final ContentResolver cr = mServiceContext.getContentResolver(); - Settings.Global.putString(cr, ConnectivitySettingsManager.PRIVATE_DNS_MODE, mode); - Settings.Global.putString(cr, ConnectivitySettingsManager.PRIVATE_DNS_SPECIFIER, specifier); + private void setPrivateDnsSettings(int mode, String specifier) { + ConnectivitySettingsManager.setPrivateDnsMode(mServiceContext, mode); + ConnectivitySettingsManager.setPrivateDnsHostname(mServiceContext, specifier); mService.updatePrivateDnsSettings(); waitForIdle(); } @@ -8327,7 +8342,8 @@ public class ConnectivityServiceTest { final int cellNetId = mCellNetworkAgent.getNetwork().netId; waitForIdle(); - verify(mMockNetd, times(1)).networkCreatePhysical(eq(cellNetId), anyInt()); + verify(mMockNetd, times(1)).networkCreate(nativeNetworkConfigPhysical(cellNetId, + INetd.PERMISSION_NONE)); assertRoutesAdded(cellNetId, ipv6Subnet, defaultRoute); verify(mMockDnsResolver, times(1)).createNetworkCache(eq(cellNetId)); verify(mMockNetd, times(1)).networkAddInterface(cellNetId, MOBILE_IFNAME); @@ -9392,9 +9408,9 @@ public class ConnectivityServiceTest { @Override public TransportInfo makeCopy(@NetworkCapabilities.RedactionType long redactions) { return new TestTransportInfo( - (redactions & REDACT_FOR_ACCESS_FINE_LOCATION) != 0, - (redactions & REDACT_FOR_LOCAL_MAC_ADDRESS) != 0, - (redactions & REDACT_FOR_NETWORK_SETTINGS) != 0 + locationRedacted | (redactions & REDACT_FOR_ACCESS_FINE_LOCATION) != 0, + localMacAddressRedacted | (redactions & REDACT_FOR_LOCAL_MAC_ADDRESS) != 0, + settingsRedacted | (redactions & REDACT_FOR_NETWORK_SETTINGS) != 0 ); } @@ -9417,8 +9433,26 @@ public class ConnectivityServiceTest { public int hashCode() { return Objects.hash(locationRedacted, localMacAddressRedacted, settingsRedacted); } + + @Override + public String toString() { + return String.format( + "TestTransportInfo{locationRedacted=%s macRedacted=%s settingsRedacted=%s}", + locationRedacted, localMacAddressRedacted, settingsRedacted); + } + } + + private TestTransportInfo getTestTransportInfo(NetworkCapabilities nc) { + return (TestTransportInfo) nc.getTransportInfo(); } + private TestTransportInfo getTestTransportInfo(TestNetworkAgentWrapper n) { + final NetworkCapabilities nc = mCm.getNetworkCapabilities(n.getNetwork()); + assertNotNull(nc); + return getTestTransportInfo(nc); + } + + private void verifyNetworkCallbackLocationDataInclusionUsingTransportInfoAndOwnerUidInNetCaps( @NonNull TestNetworkCallback wifiNetworkCallback, int actualOwnerUid, @NonNull TransportInfo actualTransportInfo, int expectedOwnerUid, @@ -9447,7 +9481,6 @@ public class ConnectivityServiceTest { wifiNetworkCallback.expectCapabilitiesThat(mWiFiNetworkAgent, nc -> Objects.equals(expectedOwnerUid, nc.getOwnerUid()) && Objects.equals(expectedTransportInfo, nc.getTransportInfo())); - } @Test @@ -9468,6 +9501,40 @@ public class ConnectivityServiceTest { wifiNetworkCallack, ownerUid, transportInfo, INVALID_UID, sanitizedTransportInfo); } + @Test + public void testTransportInfoRedactionInSynchronousCalls() throws Exception { + final NetworkCapabilities ncTemplate = new NetworkCapabilities() + .addTransportType(TRANSPORT_WIFI) + .setTransportInfo(new TestTransportInfo()); + + mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), + ncTemplate); + mWiFiNetworkAgent.connect(true /* validated; waits for callback */); + + // NETWORK_SETTINGS redaction is controlled by the NETWORK_SETTINGS permission + assertTrue(getTestTransportInfo(mWiFiNetworkAgent).settingsRedacted); + withPermission(NETWORK_SETTINGS, () -> { + assertFalse(getTestTransportInfo(mWiFiNetworkAgent).settingsRedacted); + }); + assertTrue(getTestTransportInfo(mWiFiNetworkAgent).settingsRedacted); + + // LOCAL_MAC_ADDRESS redaction is controlled by the LOCAL_MAC_ADDRESS permission + assertTrue(getTestTransportInfo(mWiFiNetworkAgent).localMacAddressRedacted); + withPermission(LOCAL_MAC_ADDRESS, () -> { + assertFalse(getTestTransportInfo(mWiFiNetworkAgent).localMacAddressRedacted); + }); + assertTrue(getTestTransportInfo(mWiFiNetworkAgent).localMacAddressRedacted); + + // Synchronous getNetworkCapabilities calls never return unredacted location-sensitive + // information. + assertTrue(getTestTransportInfo(mWiFiNetworkAgent).locationRedacted); + setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_FINE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION); + assertTrue(getTestTransportInfo(mWiFiNetworkAgent).locationRedacted); + denyAllLocationPrivilegedPermissions(); + assertTrue(getTestTransportInfo(mWiFiNetworkAgent).locationRedacted); + } + private void setupConnectionOwnerUid(int vpnOwnerUid, @VpnManager.VpnType int vpnType) throws Exception { final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE); @@ -9825,12 +9892,27 @@ public class ConnectivityServiceTest { // Connect the cell agent verify that it notifies TestNetworkCallback that it is available final TestNetworkCallback callback = new TestNetworkCallback(); mCm.registerDefaultNetworkCallback(callback); - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); + + final NetworkCapabilities ncTemplate = new NetworkCapabilities() + .addTransportType(TRANSPORT_CELLULAR) + .setTransportInfo(new TestTransportInfo()); + mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, new LinkProperties(), + ncTemplate); mCellNetworkAgent.connect(true); callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); callback.assertNoCallback(); } + private boolean areConnDiagCapsRedacted(NetworkCapabilities nc) { + TestTransportInfo ti = (TestTransportInfo) nc.getTransportInfo(); + return nc.getUids() == null + && nc.getAdministratorUids().length == 0 + && nc.getOwnerUid() == Process.INVALID_UID + && getTestTransportInfo(nc).locationRedacted + && getTestTransportInfo(nc).localMacAddressRedacted + && getTestTransportInfo(nc).settingsRedacted; + } + @Test public void testConnectivityDiagnosticsCallbackOnConnectivityReportAvailable() throws Exception { @@ -9841,12 +9923,7 @@ public class ConnectivityServiceTest { // Verify onConnectivityReport fired verify(mConnectivityDiagnosticsCallback).onConnectivityReportAvailable( - argThat(report -> { - final NetworkCapabilities nc = report.getNetworkCapabilities(); - return nc.getUids() == null - && nc.getAdministratorUids().length == 0 - && nc.getOwnerUid() == Process.INVALID_UID; - })); + argThat(report -> areConnDiagCapsRedacted(report.getNetworkCapabilities()))); } @Test @@ -9862,12 +9939,7 @@ public class ConnectivityServiceTest { // Verify onDataStallSuspected fired verify(mConnectivityDiagnosticsCallback).onDataStallSuspected( - argThat(report -> { - final NetworkCapabilities nc = report.getNetworkCapabilities(); - return nc.getUids() == null - && nc.getAdministratorUids().length == 0 - && nc.getOwnerUid() == Process.INVALID_UID; - })); + argThat(report -> areConnDiagCapsRedacted(report.getNetworkCapabilities()))); } @Test @@ -11982,8 +12054,9 @@ public class ConnectivityServiceTest { mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); mProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - inOrder.verify(mMockNetd).networkCreatePhysical(mCellNetworkAgent.getNetwork().netId, - INetd.PERMISSION_NONE); + inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( + mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE)); + final TestOnCompleteListener listener = new TestOnCompleteListener(); mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, @@ -12010,8 +12083,8 @@ public class ConnectivityServiceTest { mProfileDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(workAgent); mSystemDefaultNetworkCallback.assertNoCallback(); mDefaultNetworkCallback.assertNoCallback(); - inOrder.verify(mMockNetd).networkCreatePhysical(workAgent.getNetwork().netId, - INetd.PERMISSION_SYSTEM); + inOrder.verify(mMockNetd).networkCreate( + nativeNetworkConfigPhysical(workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM)); inOrder.verify(mMockNetd).networkAddUidRanges(workAgent.getNetwork().netId, uidRangeFor(testHandle)); inOrder.verify(mMockNetd).networkRemoveUidRanges(mCellNetworkAgent.getNetwork().netId, @@ -12054,8 +12127,8 @@ public class ConnectivityServiceTest { mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); mProfileDefaultNetworkCallback.assertNoCallback(); - inOrder.verify(mMockNetd).networkCreatePhysical(mCellNetworkAgent.getNetwork().netId, - INetd.PERMISSION_NONE); + inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( + mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE)); // When the agent disconnects, test that the app on the work profile falls back to the // default network. @@ -12085,8 +12158,8 @@ public class ConnectivityServiceTest { mProfileDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(workAgent2); assertNoCallbacks(mSystemDefaultNetworkCallback, mDefaultNetworkCallback); - inOrder.verify(mMockNetd).networkCreatePhysical(workAgent2.getNetwork().netId, - INetd.PERMISSION_SYSTEM); + inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( + workAgent2.getNetwork().netId, INetd.PERMISSION_SYSTEM)); inOrder.verify(mMockNetd).networkAddUidRanges(workAgent2.getNetwork().netId, uidRangeFor(testHandle)); @@ -12131,8 +12204,8 @@ public class ConnectivityServiceTest { mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, r -> r.run(), listener); listener.expectOnComplete(); - inOrder.verify(mMockNetd).networkCreatePhysical(mCellNetworkAgent.getNetwork().netId, - INetd.PERMISSION_NONE); + inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( + mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE)); inOrder.verify(mMockNetd).networkAddUidRanges(workAgent.getNetwork().netId, uidRangeFor(testHandle)); @@ -12184,10 +12257,10 @@ public class ConnectivityServiceTest { mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); mProfileDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); app4Cb.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - inOrder.verify(mMockNetd).networkCreatePhysical(mCellNetworkAgent.getNetwork().netId, - INetd.PERMISSION_NONE); - inOrder.verify(mMockNetd).networkCreatePhysical(workAgent.getNetwork().netId, - INetd.PERMISSION_SYSTEM); + inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( + mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE)); + inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( + workAgent.getNetwork().netId, INetd.PERMISSION_SYSTEM)); final TestOnCompleteListener listener = new TestOnCompleteListener(); mCm.setProfileNetworkPreference(testHandle2, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, @@ -12239,8 +12312,8 @@ public class ConnectivityServiceTest { mCm.setProfileNetworkPreference(testHandle, PROFILE_NETWORK_PREFERENCE_ENTERPRISE, r -> r.run(), listener); listener.expectOnComplete(); - inOrder.verify(mMockNetd).networkCreatePhysical(mCellNetworkAgent.getNetwork().netId, - INetd.PERMISSION_NONE); + inOrder.verify(mMockNetd).networkCreate(nativeNetworkConfigPhysical( + mCellNetworkAgent.getNetwork().netId, INetd.PERMISSION_NONE)); inOrder.verify(mMockNetd).networkAddUidRanges(mCellNetworkAgent.getNetwork().netId, uidRangeFor(testHandle)); diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/packages/Connectivity/tests/unit/java/com/android/server/IpSecServiceParameterizedTest.java index cf2c9c783ac7..cf2c9c783ac7 100644 --- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/IpSecServiceParameterizedTest.java diff --git a/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java b/packages/Connectivity/tests/unit/java/com/android/server/IpSecServiceRefcountedResourceTest.java index 22a2c94fc194..22a2c94fc194 100644 --- a/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/IpSecServiceRefcountedResourceTest.java diff --git a/tests/net/java/com/android/server/IpSecServiceTest.java b/packages/Connectivity/tests/unit/java/com/android/server/IpSecServiceTest.java index 6232423b4f9e..6232423b4f9e 100644 --- a/tests/net/java/com/android/server/IpSecServiceTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/IpSecServiceTest.java diff --git a/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt b/packages/Connectivity/tests/unit/java/com/android/server/LegacyTypeTrackerTest.kt index 5ec111954fcc..5ec111954fcc 100644 --- a/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt +++ b/packages/Connectivity/tests/unit/java/com/android/server/LegacyTypeTrackerTest.kt diff --git a/tests/net/java/com/android/server/NetIdManagerTest.kt b/packages/Connectivity/tests/unit/java/com/android/server/NetIdManagerTest.kt index 6f5e740d344c..6f5e740d344c 100644 --- a/tests/net/java/com/android/server/NetIdManagerTest.kt +++ b/packages/Connectivity/tests/unit/java/com/android/server/NetIdManagerTest.kt diff --git a/tests/net/java/com/android/server/NetworkManagementServiceTest.java b/packages/Connectivity/tests/unit/java/com/android/server/NetworkManagementServiceTest.java index 13516d75a50d..13516d75a50d 100644 --- a/tests/net/java/com/android/server/NetworkManagementServiceTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/NetworkManagementServiceTest.java diff --git a/tests/net/java/com/android/server/NsdServiceTest.java b/packages/Connectivity/tests/unit/java/com/android/server/NsdServiceTest.java index a90fa6882c25..a90fa6882c25 100644 --- a/tests/net/java/com/android/server/NsdServiceTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/NsdServiceTest.java diff --git a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java index 692c50fbef86..0ffeec98cf90 100644 --- a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java @@ -16,10 +16,10 @@ package com.android.server.connectivity; -import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF; -import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_DEFAULT_MODE; import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE; +import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OFF; +import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_SPECIFIER; import static android.net.NetworkCapabilities.MAX_TRANSPORT; import static android.net.NetworkCapabilities.MIN_TRANSPORT; @@ -44,6 +44,7 @@ import static org.mockito.Mockito.when; import android.annotation.NonNull; import android.content.Context; +import android.net.ConnectivitySettingsManager; import android.net.IDnsResolver; import android.net.IpPrefix; import android.net.LinkAddress; @@ -187,9 +188,8 @@ public class DnsManagerTest { lp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"), TEST_IFACENAME)); - Settings.Global.putString(mContentResolver, - PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME); - Settings.Global.putString(mContentResolver, PRIVATE_DNS_SPECIFIER, "strictmode.com"); + ConnectivitySettingsManager.setPrivateDnsMode(mCtx, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME); + ConnectivitySettingsManager.setPrivateDnsHostname(mCtx, "strictmode.com"); mDnsManager.updatePrivateDns(new Network(TEST_NETID), new PrivateDnsConfig("strictmode.com", new InetAddress[] { InetAddress.parseNumericAddress("6.6.6.6"), @@ -294,7 +294,7 @@ public class DnsManagerTest { assertNull(lp.getPrivateDnsServerName()); // Turn private DNS mode off - Settings.Global.putString(mContentResolver, PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_OFF); + ConnectivitySettingsManager.setPrivateDnsMode(mCtx, PRIVATE_DNS_MODE_OFF); mDnsManager.updatePrivateDns(new Network(TEST_NETID), mDnsManager.getPrivateDnsConfig()); mDnsManager.updateTransportsForNetwork(TEST_NETID, TEST_TRANSPORT_TYPES); @@ -318,16 +318,15 @@ public class DnsManagerTest { assertEquals(new InetAddress[0], cfgAuto.ips); // Pretend a gservices push sets the default to "off". - Settings.Global.putString(mContentResolver, PRIVATE_DNS_DEFAULT_MODE, "off"); + ConnectivitySettingsManager.setPrivateDnsDefaultMode(mCtx, PRIVATE_DNS_MODE_OFF); final PrivateDnsConfig cfgOff = DnsManager.getPrivateDnsConfig(mCtx); assertFalse(cfgOff.useTls); assertEquals("", cfgOff.hostname); assertEquals(new InetAddress[0], cfgOff.ips); // Strict mode still works. - Settings.Global.putString( - mContentResolver, PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME); - Settings.Global.putString(mContentResolver, PRIVATE_DNS_SPECIFIER, "strictmode.com"); + ConnectivitySettingsManager.setPrivateDnsMode(mCtx, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME); + ConnectivitySettingsManager.setPrivateDnsHostname(mCtx, "strictmode.com"); final PrivateDnsConfig cfgStrict = DnsManager.getPrivateDnsConfig(mCtx); assertTrue(cfgStrict.useTls); assertEquals("strictmode.com", cfgStrict.hostname); diff --git a/tests/net/java/com/android/server/connectivity/FullScoreTest.kt b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/FullScoreTest.kt index eb3b4df1a282..eb3b4df1a282 100644 --- a/tests/net/java/com/android/server/connectivity/FullScoreTest.kt +++ b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/FullScoreTest.kt diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java index 70495cced536..70495cced536 100644 --- a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/IpConnectivityMetricsTest.java index 8b072c49de82..8b072c49de82 100644 --- a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/IpConnectivityMetricsTest.java diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/LingerMonitorTest.java index 116d755e30a4..116d755e30a4 100644 --- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/LingerMonitorTest.java diff --git a/tests/net/java/com/android/server/connectivity/MetricsTestUtil.java b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/MetricsTestUtil.java index 5064b9bd91b9..5064b9bd91b9 100644 --- a/tests/net/java/com/android/server/connectivity/MetricsTestUtil.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/MetricsTestUtil.java diff --git a/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java index 38f6d7f3172d..38f6d7f3172d 100644 --- a/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java diff --git a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/Nat464XlatTest.java index 9b2a638f8b39..9b2a638f8b39 100644 --- a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/Nat464XlatTest.java diff --git a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/NetdEventListenerServiceTest.java index 50aaaee24418..50aaaee24418 100644 --- a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/NetdEventListenerServiceTest.java diff --git a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/NetworkNotificationManagerTest.java index 3adf08c19986..3adf08c19986 100644 --- a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/NetworkNotificationManagerTest.java diff --git a/tests/net/java/com/android/server/connectivity/NetworkRankerTest.kt b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/NetworkRankerTest.kt index 86c91165f61b..86c91165f61b 100644 --- a/tests/net/java/com/android/server/connectivity/NetworkRankerTest.kt +++ b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/NetworkRankerTest.kt diff --git a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java index d7535a958117..02a58080fefd 100644 --- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java @@ -479,13 +479,14 @@ public class PermissionMonitorTest { public void testUidFilteringDuringVpnConnectDisconnectAndUidUpdates() throws Exception { when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn( Arrays.asList(new PackageInfo[] { - buildPackageInfo(/* SYSTEM */ true, SYSTEM_UID1, MOCK_USER1), - buildPackageInfo(/* SYSTEM */ false, MOCK_UID1, MOCK_USER1), - buildPackageInfo(/* SYSTEM */ false, MOCK_UID2, MOCK_USER1), - buildPackageInfo(/* SYSTEM */ false, VPN_UID, MOCK_USER1) + buildPackageInfo(true /* hasSystemPermission */, SYSTEM_UID1, MOCK_USER1), + buildPackageInfo(false /* hasSystemPermission */, MOCK_UID1, MOCK_USER1), + buildPackageInfo(false /* hasSystemPermission */, MOCK_UID2, MOCK_USER1), + buildPackageInfo(false /* hasSystemPermission */, VPN_UID, MOCK_USER1) })); - when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1), eq(GET_PERMISSIONS))).thenReturn( - buildPackageInfo(false, MOCK_UID1, MOCK_USER1)); + when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1), + eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn( + buildPackageInfo(false /* hasSystemPermission */, MOCK_UID1, MOCK_USER1)); mPermissionMonitor.startMonitoring(); // Every app on user 0 except MOCK_UID2 are under VPN. final Set<UidRange> vpnRange1 = new HashSet<>(Arrays.asList(new UidRange[] { @@ -530,11 +531,12 @@ public class PermissionMonitorTest { public void testUidFilteringDuringPackageInstallAndUninstall() throws Exception { when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn( Arrays.asList(new PackageInfo[] { - buildPackageInfo(true, SYSTEM_UID1, MOCK_USER1), - buildPackageInfo(false, VPN_UID, MOCK_USER1) + buildPackageInfo(true /* hasSystemPermission */, SYSTEM_UID1, MOCK_USER1), + buildPackageInfo(false /* hasSystemPermission */, VPN_UID, MOCK_USER1) })); - when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1), eq(GET_PERMISSIONS))).thenReturn( - buildPackageInfo(false, MOCK_UID1, MOCK_USER1)); + when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1), + eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn( + buildPackageInfo(false /* hasSystemPermission */, MOCK_UID1, MOCK_USER1)); mPermissionMonitor.startMonitoring(); final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(MOCK_USER1)); diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/VpnTest.java index b725b826b14f..b725b826b14f 100644 --- a/tests/net/java/com/android/server/connectivity/VpnTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/connectivity/VpnTest.java diff --git a/tests/net/java/com/android/server/net/NetworkStatsAccessTest.java b/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsAccessTest.java index 8b730af76951..8b730af76951 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsAccessTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsAccessTest.java diff --git a/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java b/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsBaseTest.java index a058a466a4ff..a058a466a4ff 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsBaseTest.java diff --git a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java b/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsCollectionTest.java index 505ff9b6a34b..505ff9b6a34b 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsCollectionTest.java diff --git a/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java b/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java index f3ae9b051e7c..f3ae9b051e7c 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java diff --git a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java b/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java index 9fa1c50423d9..9fa1c50423d9 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java index fd374bc9e68f..fd374bc9e68f 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java diff --git a/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java b/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java index 6d2c7dc39ffd..6d2c7dc39ffd 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java diff --git a/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java b/packages/Connectivity/tests/unit/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java index ebbc0ef62548..ebbc0ef62548 100644 --- a/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java +++ b/packages/Connectivity/tests/unit/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java diff --git a/tests/net/jni/Android.bp b/packages/Connectivity/tests/unit/jni/Android.bp index 22a04f5c0945..22a04f5c0945 100644 --- a/tests/net/jni/Android.bp +++ b/packages/Connectivity/tests/unit/jni/Android.bp diff --git a/tests/net/jni/test_onload.cpp b/packages/Connectivity/tests/unit/jni/test_onload.cpp index 5194ddb0d882..5194ddb0d882 100644 --- a/tests/net/jni/test_onload.cpp +++ b/packages/Connectivity/tests/unit/jni/test_onload.cpp diff --git a/tests/net/res/raw/history_v1 b/packages/Connectivity/tests/unit/res/raw/history_v1 Binary files differindex de79491c032e..de79491c032e 100644 --- a/tests/net/res/raw/history_v1 +++ b/packages/Connectivity/tests/unit/res/raw/history_v1 diff --git a/tests/net/res/raw/net_dev_typical b/packages/Connectivity/tests/unit/res/raw/net_dev_typical index 290bf03eb9b4..290bf03eb9b4 100644 --- a/tests/net/res/raw/net_dev_typical +++ b/packages/Connectivity/tests/unit/res/raw/net_dev_typical diff --git a/tests/net/res/raw/netstats_uid_v4 b/packages/Connectivity/tests/unit/res/raw/netstats_uid_v4 Binary files differindex e75fc1ca5c2e..e75fc1ca5c2e 100644 --- a/tests/net/res/raw/netstats_uid_v4 +++ b/packages/Connectivity/tests/unit/res/raw/netstats_uid_v4 diff --git a/tests/net/res/raw/netstats_v1 b/packages/Connectivity/tests/unit/res/raw/netstats_v1 Binary files differindex e80860a6b959..e80860a6b959 100644 --- a/tests/net/res/raw/netstats_v1 +++ b/packages/Connectivity/tests/unit/res/raw/netstats_v1 diff --git a/tests/net/res/raw/xt_qtaguid_iface_fmt_typical b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_iface_fmt_typical index 656d5bb82da4..656d5bb82da4 100644 --- a/tests/net/res/raw/xt_qtaguid_iface_fmt_typical +++ b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_iface_fmt_typical diff --git a/tests/net/res/raw/xt_qtaguid_iface_typical b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_iface_typical index 610723aef2f2..610723aef2f2 100644 --- a/tests/net/res/raw/xt_qtaguid_iface_typical +++ b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_iface_typical diff --git a/tests/net/res/raw/xt_qtaguid_typical b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_typical index c1b0d259955c..c1b0d259955c 100644 --- a/tests/net/res/raw/xt_qtaguid_typical +++ b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_typical diff --git a/tests/net/res/raw/xt_qtaguid_vpn_incorrect_iface b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_incorrect_iface index fc92715253ed..fc92715253ed 100644 --- a/tests/net/res/raw/xt_qtaguid_vpn_incorrect_iface +++ b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_incorrect_iface diff --git a/tests/net/res/raw/xt_qtaguid_vpn_one_underlying b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_one_underlying index 1ef18894b669..1ef18894b669 100644 --- a/tests/net/res/raw/xt_qtaguid_vpn_one_underlying +++ b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_one_underlying diff --git a/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_compression b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_one_underlying_compression index 6d6bf550bbfa..6d6bf550bbfa 100644 --- a/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_compression +++ b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_one_underlying_compression diff --git a/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_own_traffic b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_one_underlying_own_traffic index 2c2e5d2555f6..2c2e5d2555f6 100644 --- a/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_own_traffic +++ b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_one_underlying_own_traffic diff --git a/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_two_vpn b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_one_underlying_two_vpn index eb0513b10049..eb0513b10049 100644 --- a/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_two_vpn +++ b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_one_underlying_two_vpn diff --git a/tests/net/res/raw/xt_qtaguid_vpn_rewrite_through_self b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_rewrite_through_self index afcdd7199026..afcdd7199026 100644 --- a/tests/net/res/raw/xt_qtaguid_vpn_rewrite_through_self +++ b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_rewrite_through_self diff --git a/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_duplication b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_two_underlying_duplication index d7c7eb9f4ae8..d7c7eb9f4ae8 100644 --- a/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_duplication +++ b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_two_underlying_duplication diff --git a/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_split b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_two_underlying_split index 38a3dce4a834..38a3dce4a834 100644 --- a/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_split +++ b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_two_underlying_split diff --git a/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_split_compression b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_two_underlying_split_compression index d35244b3b4f2..d35244b3b4f2 100644 --- a/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_split_compression +++ b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_two_underlying_split_compression diff --git a/tests/net/res/raw/xt_qtaguid_vpn_with_clat b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_with_clat index 0d893d515ca2..0d893d515ca2 100644 --- a/tests/net/res/raw/xt_qtaguid_vpn_with_clat +++ b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_vpn_with_clat diff --git a/tests/net/res/raw/xt_qtaguid_with_clat b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_with_clat index f04b32f08332..f04b32f08332 100644 --- a/tests/net/res/raw/xt_qtaguid_with_clat +++ b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_with_clat diff --git a/tests/net/res/raw/xt_qtaguid_with_clat_100mb_download_after b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_with_clat_100mb_download_after index 12d98ca29f57..12d98ca29f57 100644 --- a/tests/net/res/raw/xt_qtaguid_with_clat_100mb_download_after +++ b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_with_clat_100mb_download_after diff --git a/tests/net/res/raw/xt_qtaguid_with_clat_100mb_download_before b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_with_clat_100mb_download_before index ce4bcc3a3b43..ce4bcc3a3b43 100644 --- a/tests/net/res/raw/xt_qtaguid_with_clat_100mb_download_before +++ b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_with_clat_100mb_download_before diff --git a/tests/net/res/raw/xt_qtaguid_with_clat_simple b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_with_clat_simple index a1d6d411bad8..a1d6d411bad8 100644 --- a/tests/net/res/raw/xt_qtaguid_with_clat_simple +++ b/packages/Connectivity/tests/unit/res/raw/xt_qtaguid_with_clat_simple diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java index 16a946dc7bc6..f8cb5d3d2419 100644 --- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java +++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java @@ -561,7 +561,20 @@ public class DynamicSystemInstallationService extends Service break; } - Log.d(TAG, "status=" + statusString + ", cause=" + causeString + ", detail=" + detail); + StringBuilder msg = new StringBuilder(); + msg.append("status: " + statusString + ", cause: " + causeString); + if (status == STATUS_IN_PROGRESS) { + msg.append( + String.format( + ", partition name: %s, progress: %d/%d", + mCurrentPartitionName, + mCurrentPartitionInstalledSize, + mCurrentPartitionSize)); + } + if (detail != null) { + msg.append(", detail: " + detail); + } + Log.d(TAG, msg.toString()); if (notifyOnNotificationBar) { mNM.notify(NOTIFICATION_ID, buildNotification(status, cause, detail)); diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java index 59ea9f0150bf..f18d4269c3ef 100644 --- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java +++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java @@ -320,20 +320,21 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog } } - private void installScratch() throws IOException { - final long scratchSize = mDynSystem.suggestScratchSize(); + private void installWritablePartition(final String partitionName, final long partitionSize) + throws IOException { + Log.d(TAG, "Creating writable partition: " + partitionName + ", size: " + partitionSize); + Thread thread = new Thread() { @Override public void run() { mInstallationSession = - mDynSystem.createPartition("scratch", scratchSize, /* readOnly= */ false); + mDynSystem.createPartition( + partitionName, partitionSize, /* readOnly= */ false); } }; - Log.d(TAG, "Creating partition: scratch, size = " + scratchSize); thread.start(); - - Progress progress = new Progress("scratch", scratchSize, mNumInstalledPartitions++); + Progress progress = new Progress(partitionName, partitionSize, mNumInstalledPartitions++); while (thread.isAlive()) { if (isCancelled()) { @@ -356,53 +357,22 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog if (mInstallationSession == null) { throw new IOException( - "Failed to start installation with requested size: " + scratchSize); + "Failed to start installation with requested size: " + partitionSize); } + // Reset installation session and verify that installation completes successfully. mInstallationSession = null; if (!mDynSystem.closePartition()) { - throw new IOException("Failed to complete partition installation: scratch"); + throw new IOException("Failed to complete partition installation: " + partitionName); } } - private void installUserdata() throws IOException { - Thread thread = new Thread(() -> { - mInstallationSession = mDynSystem.createPartition("userdata", mUserdataSize, false); - }); - - Log.d(TAG, "Creating partition: userdata, size = " + mUserdataSize); - thread.start(); - - Progress progress = new Progress("userdata", mUserdataSize, mNumInstalledPartitions++); - - while (thread.isAlive()) { - if (isCancelled()) { - return; - } - - final long installedSize = mDynSystem.getInstallationProgress().bytes_processed; - - if (installedSize > progress.installedSize + MIN_PROGRESS_TO_PUBLISH) { - progress.installedSize = installedSize; - publishProgress(progress); - } - - try { - Thread.sleep(100); - } catch (InterruptedException e) { - // Ignore the error. - } - } + private void installScratch() throws IOException { + installWritablePartition("scratch", mDynSystem.suggestScratchSize()); + } - if (mInstallationSession == null) { - throw new IOException( - "Failed to start installation with requested size: " + mUserdataSize); - } - // Reset installation session and verify that installation completes successfully. - mInstallationSession = null; - if (!mDynSystem.closePartition()) { - throw new IOException("Failed to complete partition installation: userdata"); - } + private void installUserdata() throws IOException { + installWritablePartition("userdata", mUserdataSize); } private void installImages() throws IOException, ImageValidationException { diff --git a/packages/InputDevices/res/raw/keyboard_layout_arabic.kcm b/packages/InputDevices/res/raw/keyboard_layout_arabic.kcm index 44d5a0c376f7..16141883df98 100644 --- a/packages/InputDevices/res/raw/keyboard_layout_arabic.kcm +++ b/packages/InputDevices/res/raw/keyboard_layout_arabic.kcm @@ -171,15 +171,15 @@ key P { } key LEFT_BRACKET { - label: '[' + label: ']' base, capslock: '\u062c' - shift: '<' + shift: '>' } key RIGHT_BRACKET { - label: ']' + label: '[' base, capslock: '\u062f' - shift: '>' + shift: '<' } key BACKSLASH { diff --git a/packages/InputDevices/res/raw/keyboard_layout_hebrew.kcm b/packages/InputDevices/res/raw/keyboard_layout_hebrew.kcm index cd3a4b959386..283cb4ef2081 100644 --- a/packages/InputDevices/res/raw/keyboard_layout_hebrew.kcm +++ b/packages/InputDevices/res/raw/keyboard_layout_hebrew.kcm @@ -89,14 +89,14 @@ key 8 { key 9 { label: '9' base: '9' - shift: '(' + shift: ')' shift+capslock: '\u05c2' } key 0 { label: '0' base: '0' - shift: ')' + shift: '(' shift+capslock: '\u05c1' } @@ -180,17 +180,17 @@ key P { } key LEFT_BRACKET { - label: '[' - base, capslock: '[' - shift: '{' -} - -key RIGHT_BRACKET { label: ']' base, capslock: ']' shift: '}' } +key RIGHT_BRACKET { + label: '[' + base, capslock: '[' + shift: '{' +} + ### ROW 3 key A { @@ -322,14 +322,14 @@ key M { key COMMA { label: ',' base: '\u05ea' - shift: '<' + shift: '>' capslock: ',' } key PERIOD { label: '.' base: '\u05e5' - shift: '>' + shift: '<' capslock: '.' } diff --git a/packages/InputDevices/res/raw/keyboard_layout_persian.kcm b/packages/InputDevices/res/raw/keyboard_layout_persian.kcm index e7dd6c6d68c8..bfe78212b1eb 100644 --- a/packages/InputDevices/res/raw/keyboard_layout_persian.kcm +++ b/packages/InputDevices/res/raw/keyboard_layout_persian.kcm @@ -292,14 +292,14 @@ key TAB { key COMMA { label, number: '\u0648' base: '\u0648' - shift: '<' + shift: '>' ctrl, alt, meta: none } key PERIOD { label, number: '.' base: '.' - shift: '>' + shift: '<' ctrl, alt, meta: none } @@ -440,14 +440,14 @@ key NUMPAD_9 { } key NUMPAD_LEFT_PAREN { - label, number: '(' - base: '(' + label, number: ')' + base: ')' ctrl, alt, meta: none } key NUMPAD_RIGHT_PAREN { - label, number: ')' - base: ')' + label, number: '(' + base: '(' ctrl, alt, meta: none } diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt index 9e603561acf1..5a525974f3cb 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt @@ -114,7 +114,7 @@ class ControlsUiControllerImpl @Inject constructor ( private val onSeedingComplete = Consumer<Boolean> { accepted -> if (accepted) { - selectedStructure = controlsController.get().getFavorites().maxByOrNull { + selectedStructure = controlsController.get().getFavorites().maxBy { it.controls.size } ?: EMPTY_STRUCTURE updatePreferences(selectedStructure) diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java index 583953ce34af..50437240a29f 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java @@ -80,6 +80,7 @@ public class PipBoundsHandler { private int mImeHeight; private boolean mIsShelfShowing; private int mShelfHeight; + private boolean mDefaultLandscape; private final DisplayController.OnDisplaysChangedListener mDisplaysChangedListener = new DisplayController.OnDisplaysChangedListener() { @@ -87,6 +88,7 @@ public class PipBoundsHandler { public void onDisplayAdded(int displayId) { if (displayId == mContext.getDisplayId()) { mDisplayLayout.set(mDisplayController.getDisplayLayout(displayId)); + mDefaultLandscape = (mDisplayInfo.logicalWidth > mDisplayInfo.logicalHeight); } } }; @@ -362,9 +364,17 @@ public class PipBoundsHandler { private void updateDisplayInfoIfNeeded() { final boolean updateNeeded; if ((mDisplayInfo.rotation == ROTATION_0) || (mDisplayInfo.rotation == ROTATION_180)) { - updateNeeded = (mDisplayInfo.logicalWidth > mDisplayInfo.logicalHeight); + if (!mDefaultLandscape) { + updateNeeded = (mDisplayInfo.logicalWidth > mDisplayInfo.logicalHeight); + } else { + updateNeeded = (mDisplayInfo.logicalWidth < mDisplayInfo.logicalHeight); + } } else { - updateNeeded = (mDisplayInfo.logicalWidth < mDisplayInfo.logicalHeight); + if (!mDefaultLandscape) { + updateNeeded = (mDisplayInfo.logicalWidth < mDisplayInfo.logicalHeight); + } else { + updateNeeded = (mDisplayInfo.logicalWidth > mDisplayInfo.logicalHeight); + } } if (updateNeeded) { final int newLogicalHeight = mDisplayInfo.logicalWidth; diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipBuilder.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipBuilder.kt index eec69f98b9be..1d2e74703b42 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipBuilder.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipBuilder.kt @@ -28,7 +28,7 @@ class PrivacyChipBuilder(private val context: Context, itemsList: List<PrivacyIt appsAndTypes = itemsList.groupBy({ it.application }, { it.privacyType }) .toList() .sortedWith(compareBy({ -it.second.size }, // Sort by number of AppOps - { it.second.minOrNull() })) // Sort by "smallest" AppOpp (Location is largest) + { it.second.min() })) // Sort by "smallest" AppOpp (Location is largest) types = itemsList.map { it.privacyType }.distinct().sorted() } diff --git a/services/core/Android.bp b/services/core/Android.bp index 0ac8f74ff831..9d505643332f 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -218,6 +218,7 @@ filegroup { "java/com/android/server/connectivity/NetworkAgentInfo.java", "java/com/android/server/connectivity/NetworkDiagnostics.java", "java/com/android/server/connectivity/NetworkNotificationManager.java", + "java/com/android/server/connectivity/NetworkOffer.java", "java/com/android/server/connectivity/NetworkRanker.java", "java/com/android/server/connectivity/PermissionMonitor.java", "java/com/android/server/connectivity/ProxyTracker.java", diff --git a/services/core/java/com/android/server/BinderCallsStatsService.java b/services/core/java/com/android/server/BinderCallsStatsService.java index 9c8582f78134..f4a8f372bc36 100644 --- a/services/core/java/com/android/server/BinderCallsStatsService.java +++ b/services/core/java/com/android/server/BinderCallsStatsService.java @@ -133,6 +133,12 @@ public class BinderCallsStatsService extends Binder { private static final String SETTINGS_COLLECT_LATENCY_DATA_KEY = "collect_Latency_data"; private static final String SETTINGS_LATENCY_OBSERVER_SAMPLING_INTERVAL_KEY = "latency_observer_sampling_interval"; + private static final String SETTINGS_LATENCY_HISTOGRAM_BUCKET_COUNT_KEY = + "latency_histogram_bucket_count"; + private static final String SETTINGS_LATENCY_HISTOGRAM_FIRST_BUCKET_SIZE_KEY = + "latency_histogram_first_bucket_size"; + private static final String SETTINGS_LATENCY_HISTOGRAM_BUCKET_SCALE_FACTOR_KEY = + "latency_histogram_bucket_scale_factor"; private boolean mEnabled; private final Uri mUri = Settings.Global.getUriFor(Settings.Global.BINDER_CALLS_STATS); @@ -190,9 +196,20 @@ public class BinderCallsStatsService extends Binder { mParser.getBoolean(SETTINGS_COLLECT_LATENCY_DATA_KEY, BinderCallsStats.DEFAULT_COLLECT_LATENCY_DATA)); // Binder latency observer settings. - mBinderCallsStats.getLatencyObserver().setSamplingInterval(mParser.getInt( + BinderLatencyObserver binderLatencyObserver = mBinderCallsStats.getLatencyObserver(); + binderLatencyObserver.setSamplingInterval(mParser.getInt( SETTINGS_LATENCY_OBSERVER_SAMPLING_INTERVAL_KEY, BinderLatencyObserver.PERIODIC_SAMPLING_INTERVAL_DEFAULT)); + binderLatencyObserver.setHistogramBucketsParams( + mParser.getInt( + SETTINGS_LATENCY_HISTOGRAM_BUCKET_COUNT_KEY, + BinderLatencyObserver.BUCKET_COUNT_DEFAULT), + mParser.getInt( + SETTINGS_LATENCY_HISTOGRAM_FIRST_BUCKET_SIZE_KEY, + BinderLatencyObserver.FIRST_BUCKET_SIZE_DEFAULT), + mParser.getFloat( + SETTINGS_LATENCY_HISTOGRAM_BUCKET_SCALE_FACTOR_KEY, + BinderLatencyObserver.BUCKET_SCALE_FACTOR_DEFAULT)); final boolean enabled = diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index b31adac222df..7ffca45efedb 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -15,7 +15,6 @@ */ package com.android.server; - import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE; import static android.content.pm.PackageManager.FEATURE_BLUETOOTH; import static android.content.pm.PackageManager.FEATURE_WATCH; @@ -34,7 +33,6 @@ import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK; import static android.net.ConnectivityManager.BLOCKED_REASON_LOCKDOWN_VPN; import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; -import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; import static android.net.ConnectivityManager.TYPE_BLUETOOTH; import static android.net.ConnectivityManager.TYPE_ETHERNET; import static android.net.ConnectivityManager.TYPE_MOBILE; @@ -54,6 +52,7 @@ import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.ConnectivityManager.TYPE_WIFI_P2P; import static android.net.ConnectivityManager.getNetworkTypeName; import static android.net.ConnectivityManager.isNetworkTypeValid; +import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS; import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL; import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID; @@ -125,6 +124,7 @@ import android.net.INetworkActivityListener; import android.net.INetworkAgent; import android.net.INetworkMonitor; import android.net.INetworkMonitorCallbacks; +import android.net.INetworkOfferCallback; import android.net.IOnCompleteListener; import android.net.IQosCallback; import android.net.ISocketKeepaliveCallback; @@ -133,6 +133,8 @@ import android.net.IpMemoryStore; import android.net.IpPrefix; import android.net.LinkProperties; import android.net.MatchAllNetworkSpecifier; +import android.net.NativeNetworkConfig; +import android.net.NativeNetworkType; import android.net.NattSocketKeepalive; import android.net.Network; import android.net.NetworkAgent; @@ -232,6 +234,7 @@ import com.android.net.module.util.PermissionUtils; import com.android.server.connectivity.AutodestructReference; import com.android.server.connectivity.DnsManager; import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate; +import com.android.server.connectivity.FullScore; import com.android.server.connectivity.KeepaliveTracker; import com.android.server.connectivity.LingerMonitor; import com.android.server.connectivity.MockableSystemProperties; @@ -239,6 +242,7 @@ import com.android.server.connectivity.NetworkAgentInfo; import com.android.server.connectivity.NetworkDiagnostics; import com.android.server.connectivity.NetworkNotificationManager; import com.android.server.connectivity.NetworkNotificationManager.NotificationType; +import com.android.server.connectivity.NetworkOffer; import com.android.server.connectivity.NetworkRanker; import com.android.server.connectivity.PermissionMonitor; import com.android.server.connectivity.ProfileNetworkPreferences; @@ -602,6 +606,18 @@ public class ConnectivityService extends IConnectivityManager.Stub private static final int EVENT_UID_BLOCKED_REASON_CHANGED = 51; /** + * Event to register a new network offer + * obj = NetworkOffer + */ + private static final int EVENT_REGISTER_NETWORK_OFFER = 52; + + /** + * Event to unregister an existing network offer + * obj = INetworkOfferCallback + */ + private static final int EVENT_UNREGISTER_NETWORK_OFFER = 53; + + /** * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification * should be shown. */ @@ -3804,36 +3820,43 @@ public class ConnectivityService extends IConnectivityManager.Stub nai.onNetworkDestroyed(); } - private boolean createNativeNetwork(@NonNull NetworkAgentInfo networkAgent) { + private boolean createNativeNetwork(@NonNull NetworkAgentInfo nai) { try { // This should never fail. Specifying an already in use NetID will cause failure. - if (networkAgent.isVPN()) { - mNetd.networkCreateVpn(networkAgent.network.getNetId(), - (networkAgent.networkAgentConfig == null - || !networkAgent.networkAgentConfig.allowBypass)); + final NativeNetworkConfig config; + if (nai.isVPN()) { + if (getVpnType(nai) == VpnManager.TYPE_VPN_NONE) { + Log.wtf(TAG, "Unable to get VPN type from network " + nai.toShortString()); + return false; + } + config = new NativeNetworkConfig(nai.network.getNetId(), NativeNetworkType.VIRTUAL, + INetd.PERMISSION_NONE, + (nai.networkAgentConfig == null || !nai.networkAgentConfig.allowBypass), + getVpnType(nai)); } else { - mNetd.networkCreatePhysical(networkAgent.network.getNetId(), - getNetworkPermission(networkAgent.networkCapabilities)); - } - mDnsResolver.createNetworkCache(networkAgent.network.getNetId()); - mDnsManager.updateTransportsForNetwork(networkAgent.network.getNetId(), - networkAgent.networkCapabilities.getTransportTypes()); + config = new NativeNetworkConfig(nai.network.getNetId(), NativeNetworkType.PHYSICAL, + getNetworkPermission(nai.networkCapabilities), /*secure=*/ false, + VpnManager.TYPE_VPN_NONE); + } + mNetd.networkCreate(config); + mDnsResolver.createNetworkCache(nai.network.getNetId()); + mDnsManager.updateTransportsForNetwork(nai.network.getNetId(), + nai.networkCapabilities.getTransportTypes()); return true; } catch (RemoteException | ServiceSpecificException e) { - loge("Error creating network " + networkAgent.network.getNetId() + ": " - + e.getMessage()); + loge("Error creating network " + nai.toShortString() + ": " + e.getMessage()); return false; } } - private void destroyNativeNetwork(@NonNull NetworkAgentInfo networkAgent) { + private void destroyNativeNetwork(@NonNull NetworkAgentInfo nai) { try { - mNetd.networkDestroy(networkAgent.network.getNetId()); + mNetd.networkDestroy(nai.network.getNetId()); } catch (RemoteException | ServiceSpecificException e) { loge("Exception destroying network(networkDestroy): " + e); } try { - mDnsResolver.destroyNetworkCache(networkAgent.network.getNetId()); + mDnsResolver.destroyNetworkCache(nai.network.getNetId()); } catch (RemoteException | ServiceSpecificException e) { loge("Exception destroying network: " + e); } @@ -4675,6 +4698,18 @@ public class ConnectivityService extends IConnectivityManager.Stub handleUnregisterNetworkProvider((Messenger) msg.obj); break; } + case EVENT_REGISTER_NETWORK_OFFER: { + handleRegisterNetworkOffer((NetworkOffer) msg.obj); + break; + } + case EVENT_UNREGISTER_NETWORK_OFFER: { + final NetworkOfferInfo offer = + findNetworkOfferInfoByCallback((INetworkOfferCallback) msg.obj); + if (null != offer) { + handleUnregisterNetworkOffer(offer); + } + break; + } case EVENT_REGISTER_NETWORK_AGENT: { final Pair<NetworkAgentInfo, INetworkMonitor> arg = (Pair<NetworkAgentInfo, INetworkMonitor>) msg.obj; @@ -6205,12 +6240,37 @@ public class ConnectivityService extends IConnectivityManager.Stub mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_PROVIDER, messenger)); } + @Override + public void offerNetwork(@NonNull final Messenger providerMessenger, + @NonNull final NetworkScore score, @NonNull final NetworkCapabilities caps, + @NonNull final INetworkOfferCallback callback) { + final NetworkOffer offer = new NetworkOffer( + FullScore.makeProspectiveScore(score, caps), caps, callback, providerMessenger); + mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_OFFER, offer)); + } + + @Override + public void unofferNetwork(@NonNull final INetworkOfferCallback callback) { + mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_OFFER, callback)); + } + private void handleUnregisterNetworkProvider(Messenger messenger) { NetworkProviderInfo npi = mNetworkProviderInfos.remove(messenger); if (npi == null) { loge("Failed to find Messenger in unregisterNetworkProvider"); return; } + // Unregister all the offers from this provider + final ArrayList<NetworkOfferInfo> toRemove = new ArrayList<>(); + for (final NetworkOfferInfo noi : mNetworkOffers) { + if (noi.offer.provider == messenger) { + // Can't call handleUnregisterNetworkOffer here because iteration is in progress + toRemove.add(noi); + } + } + for (NetworkOfferInfo noi : toRemove) { + handleUnregisterNetworkOffer(noi); + } if (DBG) log("unregisterNetworkProvider for " + npi.name); } @@ -6249,6 +6309,10 @@ public class ConnectivityService extends IConnectivityManager.Stub // (on the handler thread). private volatile List<UidRange> mVpnBlockedUidRanges = new ArrayList<>(); + // Must only be accessed on the handler thread + @NonNull + private final ArrayList<NetworkOfferInfo> mNetworkOffers = new ArrayList<>(); + @GuardedBy("mBlockedAppUids") private final HashSet<Integer> mBlockedAppUids = new HashSet<>(); @@ -6573,6 +6637,65 @@ public class ConnectivityService extends IConnectivityManager.Stub updateUids(nai, null, nai.networkCapabilities); } + private class NetworkOfferInfo implements IBinder.DeathRecipient { + @NonNull public final NetworkOffer offer; + + NetworkOfferInfo(@NonNull final NetworkOffer offer) { + this.offer = offer; + } + + @Override + public void binderDied() { + mHandler.post(() -> handleUnregisterNetworkOffer(this)); + } + } + + /** + * Register or update a network offer. + * @param newOffer The new offer. If the callback member is the same as an existing + * offer, it is an update of that offer. + */ + private void handleRegisterNetworkOffer(@NonNull final NetworkOffer newOffer) { + ensureRunningOnConnectivityServiceThread(); + if (null == mNetworkProviderInfos.get(newOffer.provider)) { + // This may actually happen if a provider updates its score or registers and then + // immediately unregisters. The offer would still be in the handler queue, but the + // provider would have been removed. + if (DBG) log("Received offer from an unregistered provider"); + return; + } + + final NetworkOfferInfo existingOffer = findNetworkOfferInfoByCallback(newOffer.callback); + if (null != existingOffer) { + handleUnregisterNetworkOffer(existingOffer); + newOffer.migrateFrom(existingOffer.offer); + } + final NetworkOfferInfo noi = new NetworkOfferInfo(newOffer); + try { + noi.offer.provider.getBinder().linkToDeath(noi, 0 /* flags */); + } catch (RemoteException e) { + noi.binderDied(); + return; + } + mNetworkOffers.add(noi); + // TODO : send requests to the provider. + } + + private void handleUnregisterNetworkOffer(@NonNull final NetworkOfferInfo noi) { + ensureRunningOnConnectivityServiceThread(); + mNetworkOffers.remove(noi); + noi.offer.provider.getBinder().unlinkToDeath(noi, 0 /* flags */); + } + + @Nullable private NetworkOfferInfo findNetworkOfferInfoByCallback( + @NonNull final INetworkOfferCallback callback) { + ensureRunningOnConnectivityServiceThread(); + for (final NetworkOfferInfo noi : mNetworkOffers) { + if (noi.offer.callback.equals(callback)) return noi; + } + return null; + } + /** * Called when receiving LinkProperties directly from a NetworkAgent. * Stores into |nai| any data coming from the agent that might also be written to the network's @@ -8572,8 +8695,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // restore private DNS settings to default mode (opportunistic) if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_PRIVATE_DNS)) { - Settings.Global.putString(mContext.getContentResolver(), - ConnectivitySettingsManager.PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_OPPORTUNISTIC); + ConnectivitySettingsManager.setPrivateDnsMode(mContext, PRIVATE_DNS_MODE_OPPORTUNISTIC); } Settings.Global.putString(mContext.getContentResolver(), @@ -9033,7 +9155,8 @@ public class ConnectivityService extends IConnectivityManager.Stub } private NetworkCapabilities getNetworkCapabilitiesWithoutUids(@NonNull NetworkCapabilities nc) { - final NetworkCapabilities sanitized = new NetworkCapabilities(nc); + final NetworkCapabilities sanitized = new NetworkCapabilities(nc, + NetworkCapabilities.REDACT_ALL); sanitized.setUids(null); sanitized.setAdministratorUids(new int[0]); sanitized.setOwnerUid(Process.INVALID_UID); diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java index 1fd637ad20c4..bcbd692a2f7d 100644 --- a/services/core/java/com/android/server/VcnManagementService.java +++ b/services/core/java/com/android/server/VcnManagementService.java @@ -167,7 +167,6 @@ public class VcnManagementService extends IVcnManagementService.Stub { @NonNull private final VcnNetworkProvider mNetworkProvider; @NonNull private final TelephonySubscriptionTrackerCallback mTelephonySubscriptionTrackerCb; @NonNull private final TelephonySubscriptionTracker mTelephonySubscriptionTracker; - @NonNull private final VcnContext mVcnContext; @NonNull private final BroadcastReceiver mPkgChangeReceiver; @NonNull @@ -212,7 +211,6 @@ public class VcnManagementService extends IVcnManagementService.Stub { mContext, mLooper, mTelephonySubscriptionTrackerCb); mConfigDiskRwHelper = mDeps.newPersistableBundleLockingReadWriteHelper(VCN_CONFIG_FILE); - mVcnContext = mDeps.newVcnContext(mContext, mLooper, mNetworkProvider); mPkgChangeReceiver = new BroadcastReceiver() { @Override @@ -336,8 +334,9 @@ public class VcnManagementService extends IVcnManagementService.Stub { public VcnContext newVcnContext( @NonNull Context context, @NonNull Looper looper, - @NonNull VcnNetworkProvider vcnNetworkProvider) { - return new VcnContext(context, looper, vcnNetworkProvider); + @NonNull VcnNetworkProvider vcnNetworkProvider, + boolean isInTestMode) { + return new VcnContext(context, looper, vcnNetworkProvider, isInTestMode); } /** Creates a new Vcn instance using the provided configuration */ @@ -421,6 +420,14 @@ public class VcnManagementService extends IVcnManagementService.Stub { "Carrier privilege required for subscription group to set VCN Config"); } + private void enforceManageTestNetworksForTestMode(@NonNull VcnConfig vcnConfig) { + if (vcnConfig.isTestModeProfile()) { + mContext.enforceCallingPermission( + android.Manifest.permission.MANAGE_TEST_NETWORKS, + "Test-mode require the MANAGE_TEST_NETWORKS permission"); + } + } + private class VcnSubscriptionTrackerCallback implements TelephonySubscriptionTrackerCallback { /** * Handles subscription group changes, as notified by {@link TelephonySubscriptionTracker} @@ -544,8 +551,11 @@ public class VcnManagementService extends IVcnManagementService.Stub { final VcnCallbackImpl vcnCallback = new VcnCallbackImpl(subscriptionGroup); + final VcnContext vcnContext = + mDeps.newVcnContext( + mContext, mLooper, mNetworkProvider, config.isTestModeProfile()); final Vcn newInstance = - mDeps.newVcn(mVcnContext, subscriptionGroup, config, mLastSnapshot, vcnCallback); + mDeps.newVcn(vcnContext, subscriptionGroup, config, mLastSnapshot, vcnCallback); mVcns.put(subscriptionGroup, newInstance); // Now that a new VCN has started, notify all registered listeners to refresh their @@ -589,6 +599,7 @@ public class VcnManagementService extends IVcnManagementService.Stub { mContext.getSystemService(AppOpsManager.class) .checkPackage(mDeps.getBinderCallingUid(), config.getProvisioningPackageName()); + enforceManageTestNetworksForTestMode(config); enforceCallingUserAndCarrierPrivilege(subscriptionGroup, opPkgName); Binder.withCleanCallingIdentity(() -> { diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 22a6044fbb8a..d0a307932db0 100755 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -5860,6 +5860,10 @@ public class AudioService extends IAudioService.Stub if (index == -1) { continue; } + if (mPublicStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED + && mCameraSoundForced) { + index = mIndexMax; + } if (DEBUG_VOL) { Log.v(TAG, "readSettings: found stored index " + getValidIndex(index) + " for group " + mAudioVolumeGroup.name() + ", device: " + name); diff --git a/services/core/java/com/android/server/connectivity/DnsManager.java b/services/core/java/com/android/server/connectivity/DnsManager.java index cf4fe1ef9f97..05b12bad5589 100644 --- a/services/core/java/com/android/server/connectivity/DnsManager.java +++ b/services/core/java/com/android/server/connectivity/DnsManager.java @@ -16,14 +16,14 @@ package com.android.server.connectivity; -import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF; -import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; import static android.net.ConnectivitySettingsManager.DNS_RESOLVER_MAX_SAMPLES; import static android.net.ConnectivitySettingsManager.DNS_RESOLVER_MIN_SAMPLES; import static android.net.ConnectivitySettingsManager.DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS; import static android.net.ConnectivitySettingsManager.DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT; import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_DEFAULT_MODE; import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE; +import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OFF; +import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_SPECIFIER; import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE; import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_SUCCESS; @@ -33,6 +33,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; +import android.net.ConnectivitySettingsManager; import android.net.IDnsResolver; import android.net.InetAddresses; import android.net.LinkProperties; @@ -131,11 +132,11 @@ public class DnsManager { * Get PrivateDnsConfig. */ public static PrivateDnsConfig getPrivateDnsConfig(Context context) { - final String mode = ConnectivityManager.getPrivateDnsMode(context); + final int mode = ConnectivitySettingsManager.getPrivateDnsMode(context); - final boolean useTls = !TextUtils.isEmpty(mode) && !PRIVATE_DNS_MODE_OFF.equals(mode); + final boolean useTls = mode != PRIVATE_DNS_MODE_OFF; - if (PRIVATE_DNS_MODE_PROVIDER_HOSTNAME.equals(mode)) { + if (PRIVATE_DNS_MODE_PROVIDER_HOSTNAME == mode) { final String specifier = getStringSetting(context.getContentResolver(), PRIVATE_DNS_SPECIFIER); return new PrivateDnsConfig(specifier, null); diff --git a/services/core/java/com/android/server/connectivity/FullScore.java b/services/core/java/com/android/server/connectivity/FullScore.java index 028cfee36593..9326d692f6e4 100644 --- a/services/core/java/com/android/server/connectivity/FullScore.java +++ b/services/core/java/com/android/server/connectivity/FullScore.java @@ -16,6 +16,7 @@ package com.android.server.connectivity; +import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; import static android.net.NetworkCapabilities.TRANSPORT_VPN; @@ -116,6 +117,33 @@ public class FullScore { } /** + * Given a score supplied by the NetworkAgent, produce a prospective score for an offer. + * + * NetworkOffers have score filters that are compared to the scores of actual networks + * to see if they could possibly beat the current satisfier. Some things the agent can't + * know in advance ; a good example is the validation bit – some networks will validate, + * others won't. For comparison purposes, assume the best, so all possibly beneficial + * networks will be brought up. + * + * @param score the score supplied by the agent for this offer + * @param caps the capabilities supplied by the agent for this offer + * @return a FullScore appropriate for comparing to actual network's scores. + */ + public static FullScore makeProspectiveScore(@NonNull final NetworkScore score, + @NonNull final NetworkCapabilities caps) { + // If the network offers Internet access, it may validate. + final boolean mayValidate = caps.hasCapability(NET_CAPABILITY_INTERNET); + // VPN transports are known in advance. + final boolean vpn = caps.hasTransport(TRANSPORT_VPN); + // The network hasn't been chosen by the user (yet, at least). + final boolean everUserSelected = false; + // Don't assume the user will accept unvalidated connectivity. + final boolean acceptUnvalidated = false; + return withPolicies(score.getLegacyInt(), mayValidate, vpn, everUserSelected, + acceptUnvalidated); + } + + /** * Return a new score given updated caps and config. * * @param caps the NetworkCapabilities of the network diff --git a/services/core/java/com/android/server/connectivity/NetworkOffer.java b/services/core/java/com/android/server/connectivity/NetworkOffer.java new file mode 100644 index 000000000000..fa2d465fff1d --- /dev/null +++ b/services/core/java/com/android/server/connectivity/NetworkOffer.java @@ -0,0 +1,94 @@ +/* + * 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 com.android.server.connectivity; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.net.INetworkOfferCallback; +import android.net.NetworkCapabilities; +import android.net.NetworkRequest; +import android.os.Messenger; + +import java.util.Objects; + + +/** + * Represents an offer made by a NetworkProvider to create a network if a need arises. + * + * This class contains the prospective score and capabilities of the network. The provider + * is not obligated to caps able to create a network satisfying this, nor to build a network + * with the exact score and/or capabilities passed ; after all, not all providers know in + * advance what a network will look like after it's connected. Instead, this is meant as a + * filter to limit requests sent to the provider by connectivity to those that this offer stands + * a chance to fulfill. + * + * @see NetworkProvider#offerNetwork. + * + * @hide + */ +public class NetworkOffer { + @NonNull public final FullScore score; + @NonNull public final NetworkCapabilities caps; + @NonNull public final INetworkOfferCallback callback; + @NonNull public final Messenger provider; + + private static NetworkCapabilities emptyCaps() { + final NetworkCapabilities nc = new NetworkCapabilities(); + return nc; + } + + // Ideally the caps argument would be non-null, but null has historically meant no filter + // and telephony passes null. Keep backward compatibility. + public NetworkOffer(@NonNull final FullScore score, + @Nullable final NetworkCapabilities caps, + @NonNull final INetworkOfferCallback callback, + @NonNull final Messenger provider) { + this.score = Objects.requireNonNull(score); + this.caps = null != caps ? caps : emptyCaps(); + this.callback = Objects.requireNonNull(callback); + this.provider = Objects.requireNonNull(provider); + } + + /** + * Migrate from, and take over, a previous offer. + * + * When an updated offer is sent from a provider, call this method on the new offer, passing + * the old one, to take over the state. + * + * @param previousOffer + */ + public void migrateFrom(@NonNull final NetworkOffer previousOffer) { + if (!callback.equals(previousOffer.callback)) { + throw new IllegalArgumentException("Can only migrate from a previous version of" + + " the same offer"); + } + } + + /** + * Returns whether an offer can satisfy a NetworkRequest, according to its capabilities. + * @param request The request to test against. + * @return Whether this offer can satisfy the request. + */ + public final boolean canSatisfy(@NonNull final NetworkRequest request) { + return request.networkCapabilities.satisfiedByNetworkCapabilities(caps); + } + + @Override + public String toString() { + return "NetworkOffer [ Score " + score + " ]"; + } +} diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java index 7837e6e812f8..506cadb2b1d2 100644 --- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java +++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java @@ -338,7 +338,8 @@ public class PermissionMonitor { return currentPermission; } try { - final PackageInfo app = mPackageManager.getPackageInfo(name, GET_PERMISSIONS); + final PackageInfo app = mPackageManager.getPackageInfo(name, + GET_PERMISSIONS | MATCH_ANY_USER); final boolean isNetwork = hasNetworkPermission(app); final boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app); if (isNetwork || hasRestrictedPermission) { @@ -664,6 +665,7 @@ public class PermissionMonitor { break; case INetd.PERMISSION_UNINSTALLED: uninstalledAppIds.add(netdPermissionsAppIds.keyAt(i)); + break; default: Log.e(TAG, "unknown permission type: " + permissions + "for uid: " + netdPermissionsAppIds.keyAt(i)); diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index fa64df5b1670..836e6150414c 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -5257,6 +5257,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { long[] pattern; switch (effectId) { case HapticFeedbackConstants.CONTEXT_CLICK: + case HapticFeedbackConstants.GESTURE_END: return VibrationEffect.get(VibrationEffect.EFFECT_TICK); case HapticFeedbackConstants.TEXT_HANDLE_MOVE: if (!mHapticTextHandleEnabled) { @@ -5269,7 +5270,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { case HapticFeedbackConstants.VIRTUAL_KEY_RELEASE: case HapticFeedbackConstants.ENTRY_BUMP: case HapticFeedbackConstants.DRAG_CROSSING: - case HapticFeedbackConstants.GESTURE_END: return VibrationEffect.get(VibrationEffect.EFFECT_TICK, false); case HapticFeedbackConstants.KEYBOARD_TAP: // == KEYBOARD_PRESS case HapticFeedbackConstants.VIRTUAL_KEY: diff --git a/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java b/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java index 88180239da67..3bdeec0c1d8e 100644 --- a/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java +++ b/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java @@ -158,8 +158,15 @@ public class UnderlyingNetworkTracker { * carrier owned networks may be selected, as the request specifies only subIds in the VCN's * subscription group, while the VCN networks are excluded by virtue of not having subIds set on * the VCN-exposed networks. + * + * <p>If the VCN that this UnderlyingNetworkTracker belongs to is in test-mode, this will return + * a NetworkRequest that only matches Test Networks. */ private NetworkRequest getRouteSelectionRequest() { + if (mVcnContext.isInTestMode()) { + return getTestNetworkRequest(mLastSnapshot.getAllSubIdsInGroup(mSubscriptionGroup)); + } + return getBaseNetworkRequestBuilder() .setSubscriptionIds(mLastSnapshot.getAllSubIdsInGroup(mSubscriptionGroup)) .build(); @@ -210,6 +217,15 @@ public class UnderlyingNetworkTracker { .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED); } + /** Builds and returns a NetworkRequest for the given subIds to match Test Networks. */ + private NetworkRequest getTestNetworkRequest(@NonNull Set<Integer> subIds) { + return new NetworkRequest.Builder() + .clearCapabilities() + .addTransportType(NetworkCapabilities.TRANSPORT_TEST) + .setSubscriptionIds(subIds) + .build(); + } + /** * Update this UnderlyingNetworkTracker's TelephonySubscriptionSnapshot. * diff --git a/services/core/java/com/android/server/vcn/VcnContext.java b/services/core/java/com/android/server/vcn/VcnContext.java index 7399e56b3a95..d958222ea407 100644 --- a/services/core/java/com/android/server/vcn/VcnContext.java +++ b/services/core/java/com/android/server/vcn/VcnContext.java @@ -31,14 +31,17 @@ public class VcnContext { @NonNull private final Context mContext; @NonNull private final Looper mLooper; @NonNull private final VcnNetworkProvider mVcnNetworkProvider; + private final boolean mIsInTestMode; public VcnContext( @NonNull Context context, @NonNull Looper looper, - @NonNull VcnNetworkProvider vcnNetworkProvider) { + @NonNull VcnNetworkProvider vcnNetworkProvider, + boolean isInTestMode) { mContext = Objects.requireNonNull(context, "Missing context"); mLooper = Objects.requireNonNull(looper, "Missing looper"); mVcnNetworkProvider = Objects.requireNonNull(vcnNetworkProvider, "Missing networkProvider"); + mIsInTestMode = isInTestMode; } @NonNull @@ -56,6 +59,10 @@ public class VcnContext { return mVcnNetworkProvider; } + public boolean isInTestMode() { + return mIsInTestMode; + } + /** * Verifies that the caller is running on the VcnContext Thread. * diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 736a6f68725e..8e3cb2594986 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -91,7 +91,6 @@ import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; import static android.os.UserManagerInternal.OWNER_TYPE_DEVICE_OWNER; import static android.os.UserManagerInternal.OWNER_TYPE_PROFILE_OWNER; import static android.os.UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE; -import static android.provider.Settings.Global.PRIVATE_DNS_MODE; import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER; import static android.provider.Telephony.Carriers.DPC_URI; import static android.provider.Telephony.Carriers.ENFORCE_KEY; @@ -195,6 +194,7 @@ import android.location.LocationManager; import android.media.AudioManager; import android.media.IAudioService; import android.net.ConnectivityManager; +import android.net.ConnectivitySettingsManager; import android.net.IIpConnectivityMetrics; import android.net.ProxyInfo; import android.net.Uri; @@ -15566,12 +15566,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return context.getResources().getString(R.string.config_managed_provisioning_package); } - private void putPrivateDnsSettings(@Nullable String mode, @Nullable String host) { + private void putPrivateDnsSettings(int mode, @Nullable String host) { // Set Private DNS settings using system permissions, as apps cannot write // to global settings. mInjector.binderWithCleanCallingIdentity(() -> { - mInjector.settingsGlobalPutString(PRIVATE_DNS_MODE, mode); - mInjector.settingsGlobalPutString(PRIVATE_DNS_SPECIFIER, host); + ConnectivitySettingsManager.setPrivateDnsMode(mContext, mode); + ConnectivitySettingsManager.setPrivateDnsHostname(mContext, host); }); } @@ -15592,7 +15592,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { throw new IllegalArgumentException( "Host provided for opportunistic mode, but is not needed."); } - putPrivateDnsSettings(ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC, null); + putPrivateDnsSettings(ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC, + null); return PRIVATE_DNS_SET_NO_ERROR; case PRIVATE_DNS_MODE_PROVIDER_HOSTNAME: if (TextUtils.isEmpty(privateDnsHost) @@ -15604,7 +15605,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // Connectivity check will have been performed in the DevicePolicyManager before // the call here. putPrivateDnsSettings( - ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, + ConnectivitySettingsManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, privateDnsHost); return PRIVATE_DNS_SET_NO_ERROR; default: @@ -15621,13 +15622,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Objects.requireNonNull(who, "ComponentName is null"); enforceDeviceOwner(who); - final String currentMode = ConnectivityManager.getPrivateDnsMode(mContext); + final int currentMode = ConnectivitySettingsManager.getPrivateDnsMode(mContext); switch (currentMode) { - case ConnectivityManager.PRIVATE_DNS_MODE_OFF: + case ConnectivitySettingsManager.PRIVATE_DNS_MODE_OFF: return PRIVATE_DNS_MODE_OFF; - case ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC: + case ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC: return PRIVATE_DNS_MODE_OPPORTUNISTIC; - case ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME: + case ConnectivitySettingsManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME: return PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; } diff --git a/services/net/TEST_MAPPING b/services/net/TEST_MAPPING index 7025dd178e0f..7eca1f99e4ef 100644 --- a/services/net/TEST_MAPPING +++ b/services/net/TEST_MAPPING @@ -2,6 +2,9 @@ "imports": [ { "path": "frameworks/base/core/java/android/net" + }, + { + "path": "packages/modules/Wifi/framework" } ] -}
\ No newline at end of file +} diff --git a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java index deaeb46c4074..a1bce52fe63a 100644 --- a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java +++ b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java @@ -374,7 +374,7 @@ public class JobStoreTest { .setPersisted(true) .setRequiredNetwork(new NetworkRequest.Builder() .addCapability(NET_CAPABILITY_IMS) - .addUnwantedCapability(NET_CAPABILITY_OEM_PAID) + .addForbiddenCapability(NET_CAPABILITY_OEM_PAID) .build()) .build()); } diff --git a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java index 9410886c3549..c59dcf879b1c 100644 --- a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java +++ b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java @@ -16,13 +16,17 @@ package android.net.vcn; +import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_MOBIKE; + import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.net.NetworkCapabilities; +import android.net.ipsec.ike.IkeSessionParams; import android.net.ipsec.ike.IkeTunnelConnectionParams; +import android.net.vcn.persistablebundleutils.IkeSessionParamsUtilsTest; import android.net.vcn.persistablebundleutils.TunnelConnectionParamsUtilsTest; import androidx.test.filters.SmallTest; @@ -120,6 +124,21 @@ public class VcnGatewayConnectionConfigTest { } @Test + public void testBuilderRequiresMobikeEnabled() { + try { + final IkeSessionParams ikeParams = + IkeSessionParamsUtilsTest.createBuilderMinimum() + .removeIkeOption(IKE_OPTION_MOBIKE) + .build(); + final IkeTunnelConnectionParams tunnelParams = + TunnelConnectionParamsUtilsTest.buildTestParams(ikeParams); + new VcnGatewayConnectionConfig.Builder(GATEWAY_CONNECTION_NAME_PREFIX, tunnelParams); + fail("Expected exception due to MOBIKE not enabled"); + } catch (IllegalArgumentException e) { + } + } + + @Test public void testBuilderRequiresNonEmptyExposedCaps() { try { newBuilder() diff --git a/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java b/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java index 582275d0547d..abae81cf1742 100644 --- a/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java +++ b/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java @@ -16,15 +16,17 @@ package android.net.vcn; -import static android.net.NetworkCapabilities.REDACT_ALL; -import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS; +import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION; +import static android.net.NetworkCapabilities.REDACT_NONE; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNull; +import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; +import android.os.Build; import android.os.Parcel; import org.junit.Test; @@ -39,12 +41,6 @@ public class VcnTransportInfoTest { private static final VcnTransportInfo WIFI_UNDERLYING_INFO = new VcnTransportInfo(WIFI_INFO); @Test - public void testRedactionDefaults() { - assertEquals(REDACT_ALL, CELL_UNDERLYING_INFO.getRedaction()); - assertEquals(REDACT_ALL, WIFI_UNDERLYING_INFO.getRedaction()); - } - - @Test public void testGetWifiInfo() { assertEquals(WIFI_INFO, WIFI_UNDERLYING_INFO.getWifiInfo()); @@ -59,15 +55,19 @@ public class VcnTransportInfoTest { } @Test - public void testMakeCopySetsRedactions() { - assertEquals( - REDACT_FOR_NETWORK_SETTINGS, - ((VcnTransportInfo) CELL_UNDERLYING_INFO.makeCopy(REDACT_FOR_NETWORK_SETTINGS)) - .getRedaction()); + public void testMakeCopyRedactForAccessFineLocation() { assertEquals( - REDACT_FOR_NETWORK_SETTINGS, - ((VcnTransportInfo) WIFI_UNDERLYING_INFO.makeCopy(REDACT_FOR_NETWORK_SETTINGS)) - .getRedaction()); + SUB_ID, + ((VcnTransportInfo) CELL_UNDERLYING_INFO.makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION)) + .getSubId()); + + // TODO: remove the if statement when S pushes to AOSP. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + assertEquals( + WifiConfiguration.INVALID_NETWORK_ID, + ((VcnTransportInfo) WIFI_UNDERLYING_INFO.makeCopy( + REDACT_FOR_ACCESS_FINE_LOCATION)).getWifiInfo().getNetworkId()); + } } @Test @@ -78,35 +78,31 @@ public class VcnTransportInfoTest { } @Test - public void testParcelUnparcel() { - verifyParcelingIsNull(CELL_UNDERLYING_INFO); - verifyParcelingIsNull(WIFI_UNDERLYING_INFO); - } - - private void verifyParcelingIsNull(VcnTransportInfo vcnTransportInfo) { - // Verify redacted by default - Parcel parcel = Parcel.obtain(); - vcnTransportInfo.writeToParcel(parcel, 0 /* flags */); - parcel.setDataPosition(0); + public void testApplicableRedactions() { + assertEquals(REDACT_NONE, CELL_UNDERLYING_INFO.getApplicableRedactions()); - assertNull(VcnTransportInfo.CREATOR.createFromParcel(parcel)); + final long wifiRedactions = WIFI_INFO.getApplicableRedactions(); + assertEquals(wifiRedactions, WIFI_UNDERLYING_INFO.getApplicableRedactions()); } @Test - public void testParcelUnparcelNotRedactedForSysUi() { - verifyParcelingForSysUi(CELL_UNDERLYING_INFO); - verifyParcelingForSysUi(WIFI_UNDERLYING_INFO); + public void testParcelNotRedactedForSysUi() { + VcnTransportInfo cellRedacted = parcelForSysUi(CELL_UNDERLYING_INFO); + assertEquals(SUB_ID, cellRedacted.getSubId()); + VcnTransportInfo wifiRedacted = parcelForSysUi(WIFI_UNDERLYING_INFO); + assertEquals(NETWORK_ID, wifiRedacted.getWifiInfo().getNetworkId()); } - private void verifyParcelingForSysUi(VcnTransportInfo vcnTransportInfo) { + private VcnTransportInfo parcelForSysUi(VcnTransportInfo vcnTransportInfo) { // Allow fully unredacted; SysUI will have all the relevant permissions. - final VcnTransportInfo unRedacted = (VcnTransportInfo) vcnTransportInfo.makeCopy(0); + final VcnTransportInfo unRedacted = (VcnTransportInfo) vcnTransportInfo.makeCopy( + REDACT_NONE); final Parcel parcel = Parcel.obtain(); unRedacted.writeToParcel(parcel, 0 /* flags */); parcel.setDataPosition(0); final VcnTransportInfo unparceled = VcnTransportInfo.CREATOR.createFromParcel(parcel); assertEquals(vcnTransportInfo, unparceled); - assertEquals(REDACT_ALL, unparceled.getRedaction()); + return unparceled; } } diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java index 393787f1a8b8..f3851130c68a 100644 --- a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java +++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java @@ -52,8 +52,8 @@ import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) @SmallTest public class IkeSessionParamsUtilsTest { - // Package private for use in EncryptedTunnelParamsUtilsTest - static IkeSessionParams.Builder createBuilderMinimum() { + // Public for use in VcnGatewayConnectionConfigTest, EncryptedTunnelParamsUtilsTest + public static IkeSessionParams.Builder createBuilderMinimum() { final InetAddress serverAddress = InetAddresses.parseNumericAddress("192.0.2.100"); // TODO: b/185941731 Make sure all valid IKE_OPTIONS are added and validated. @@ -63,6 +63,7 @@ public class IkeSessionParamsUtilsTest { .setLocalIdentification(new IkeFqdnIdentification("client.test.android.net")) .setRemoteIdentification(new IkeFqdnIdentification("server.test.android.net")) .addIkeOption(IkeSessionParams.IKE_OPTION_FORCE_PORT_4500) + .addIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE) .setAuthPsk("psk".getBytes()); } diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java index 0c8ad32b0c27..f9dc9eb4d5ae 100644 --- a/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java +++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java @@ -18,6 +18,7 @@ package android.net.vcn.persistablebundleutils; import static org.junit.Assert.assertEquals; +import android.net.ipsec.ike.IkeSessionParams; import android.net.ipsec.ike.IkeTunnelConnectionParams; import androidx.test.filters.SmallTest; @@ -31,9 +32,13 @@ import org.junit.runner.RunWith; public class TunnelConnectionParamsUtilsTest { // Public for use in VcnGatewayConnectionConfigTest public static IkeTunnelConnectionParams buildTestParams() { + return buildTestParams(IkeSessionParamsUtilsTest.createBuilderMinimum().build()); + } + + // Public for use in VcnGatewayConnectionConfigTest + public static IkeTunnelConnectionParams buildTestParams(IkeSessionParams params) { return new IkeTunnelConnectionParams( - IkeSessionParamsUtilsTest.createBuilderMinimum().build(), - TunnelModeChildSessionParamsUtilsTest.createBuilderMinimum().build()); + params, TunnelModeChildSessionParamsUtilsTest.createBuilderMinimum().build()); } @Test diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java index 9ecd82ff6bcb..3360d40062a3 100644 --- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java +++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java @@ -37,6 +37,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.CALLS_REAL_METHODS; @@ -66,6 +67,7 @@ import android.net.vcn.IVcnStatusCallback; import android.net.vcn.IVcnUnderlyingNetworkPolicyListener; import android.net.vcn.VcnConfig; import android.net.vcn.VcnConfigTest; +import android.net.vcn.VcnGatewayConnectionConfigTest; import android.net.vcn.VcnManager; import android.net.vcn.VcnUnderlyingNetworkPolicy; import android.os.IBinder; @@ -197,7 +199,8 @@ public class VcnManagementServiceTest { .newVcnContext( eq(mMockContext), eq(mTestLooper.getLooper()), - any(VcnNetworkProvider.class)); + any(VcnNetworkProvider.class), + anyBoolean()); doReturn(mSubscriptionTracker) .when(mMockDeps) .newTelephonySubscriptionTracker( @@ -371,6 +374,12 @@ public class VcnManagementServiceTest { TelephonySubscriptionSnapshot snapshot = triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(TEST_UUID_1)); verify(mMockDeps) + .newVcnContext( + eq(mMockContext), + eq(mTestLooper.getLooper()), + any(VcnNetworkProvider.class), + anyBoolean()); + verify(mMockDeps) .newVcn(eq(mVcnContext), eq(TEST_UUID_1), eq(TEST_VCN_CONFIG), eq(snapshot), any()); } @@ -528,6 +537,28 @@ public class VcnManagementServiceTest { } @Test + public void testSetVcnConfigTestModeRequiresPermission() throws Exception { + doThrow(new SecurityException("Requires MANAGE_TEST_NETWORKS")) + .when(mMockContext) + .enforceCallingPermission( + eq(android.Manifest.permission.MANAGE_TEST_NETWORKS), any()); + + final VcnConfig vcnConfig = + new VcnConfig.Builder(mMockContext) + .addGatewayConnectionConfig( + VcnGatewayConnectionConfigTest.buildTestConfig()) + .setIsTestModeProfile() + .build(); + + try { + mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, vcnConfig, TEST_PACKAGE_NAME); + fail("Expected exception due to using test-mode without permission"); + } catch (SecurityException e) { + verify(mMockPolicyListener, never()).onPolicyChanged(); + } + } + + @Test public void testSetVcnConfigNotifiesStatusCallback() throws Exception { triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(TEST_UUID_2)); diff --git a/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java b/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java index 8289e85dadf9..0b72cd93e8b0 100644 --- a/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java +++ b/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java @@ -26,6 +26,7 @@ import static org.mockito.Mockito.any; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -112,8 +113,14 @@ public class UnderlyingNetworkTrackerTest { MockitoAnnotations.initMocks(this); mTestLooper = new TestLooper(); - mVcnContext = spy(new VcnContext(mContext, mTestLooper.getLooper(), mVcnNetworkProvider)); - doNothing().when(mVcnContext).ensureRunningOnLooperThread(); + mVcnContext = + spy( + new VcnContext( + mContext, + mTestLooper.getLooper(), + mVcnNetworkProvider, + false /* isInTestMode */)); + resetVcnContext(); setupSystemService( mContext, @@ -132,6 +139,11 @@ public class UnderlyingNetworkTrackerTest { mNetworkTrackerCb); } + private void resetVcnContext() { + reset(mVcnContext); + doNothing().when(mVcnContext).ensureRunningOnLooperThread(); + } + private static LinkProperties getLinkPropertiesWithName(String iface) { LinkProperties linkProperties = new LinkProperties(); linkProperties.setInterfaceName(iface); @@ -149,6 +161,31 @@ public class UnderlyingNetworkTrackerTest { verifyNetworkRequestsRegistered(INITIAL_SUB_IDS); } + @Test + public void testNetworkCallbacksRegisteredOnStartupForTestMode() { + final VcnContext vcnContext = + spy( + new VcnContext( + mContext, + mTestLooper.getLooper(), + mVcnNetworkProvider, + true /* isInTestMode */)); + + mUnderlyingNetworkTracker = + new UnderlyingNetworkTracker( + vcnContext, + SUB_GROUP, + mSubscriptionSnapshot, + Collections.singleton(NetworkCapabilities.NET_CAPABILITY_INTERNET), + mNetworkTrackerCb); + + verify(mConnectivityManager) + .requestBackgroundNetwork( + eq(getTestNetworkRequest(INITIAL_SUB_IDS)), + any(RouteSelectionCallback.class), + any()); + } + private void verifyNetworkRequestsRegistered(Set<Integer> expectedSubIds) { verify(mConnectivityManager) .requestBackgroundNetwork( @@ -165,7 +202,8 @@ public class UnderlyingNetworkTrackerTest { verify(mConnectivityManager) .requestBackgroundNetwork( eq(getRouteSelectionRequest(expectedSubIds)), - any(RouteSelectionCallback.class), any()); + any(RouteSelectionCallback.class), + any()); } @Test @@ -204,6 +242,14 @@ public class UnderlyingNetworkTrackerTest { return getExpectedRequestBase().setSubscriptionIds(netCapsSubIds).build(); } + private NetworkRequest getTestNetworkRequest(Set<Integer> netCapsSubIds) { + return new NetworkRequest.Builder() + .clearCapabilities() + .addTransportType(NetworkCapabilities.TRANSPORT_TEST) + .setSubscriptionIds(netCapsSubIds) + .build(); + } + private NetworkRequest.Builder getExpectedRequestBase() { final NetworkRequest.Builder builder = new NetworkRequest.Builder() diff --git a/tools/aapt/pseudolocalize.cpp b/tools/aapt/pseudolocalize.cpp index 5c47e0fa8a16..4e8dcb1bc6ee 100644 --- a/tools/aapt/pseudolocalize.cpp +++ b/tools/aapt/pseudolocalize.cpp @@ -194,7 +194,8 @@ static String16 pseudo_generate_expansion(const unsigned int length) { break; } } - result.remove(length + ext, 0); + // Just keep the first length + ext characters + result = String16(result, length + ext); } return result; } diff --git a/tools/codegen/src/com/android/codegen/Utils.kt b/tools/codegen/src/com/android/codegen/Utils.kt index a117aa09ab62..c19ae3b0b11f 100644 --- a/tools/codegen/src/com/android/codegen/Utils.kt +++ b/tools/codegen/src/com/android/codegen/Utils.kt @@ -43,8 +43,8 @@ inline infix fun Int.times(action: () -> Unit) { * cccc dd */ fun Iterable<Pair<String, String>>.columnize(separator: String = " | "): String { - val col1w = map { (a, _) -> a.length }.maxOrNull()!! - val col2w = map { (_, b) -> b.length }.maxOrNull()!! + val col1w = map { (a, _) -> a.length }.max()!! + val col2w = map { (_, b) -> b.length }.max()!! return map { it.first.padEnd(col1w) + separator + it.second.padEnd(col2w) }.joinToString("\n") } |