Merge "Move offered RTP header extension types API."
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 7060347..aa39824 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -177,31 +177,6 @@
     "\\) "
 
 droidstubs {
-    name: "system-api-stubs-docs",
-    defaults: ["metalava-full-api-stubs-default"],
-    arg_files: [
-        "core/res/AndroidManifest.xml",
-    ],
-    args: metalava_framework_docs_args + priv_apps,
-    check_api: {
-        current: {
-            api_file: "api/system-current.txt",
-            removed_api_file: "api/system-removed.txt",
-        },
-        last_released: {
-            api_file: ":android.api.system.latest",
-            removed_api_file: ":removed.api.system.latest",
-            baseline_file: ":system-api-incompatibilities-with-last-released"
-        },
-        api_lint: {
-            enabled: true,
-            new_since: ":android.api.system.latest",
-            baseline_file: "api/system-lint-baseline.txt",
-        },
-    },
-}
-
-droidstubs {
     name: "system-api-stubs-docs-non-updatable",
     defaults: ["metalava-non-updatable-api-stubs-default"],
     arg_files: ["core/res/AndroidManifest.xml"],
diff --git a/apex/permission/Android.bp b/apex/permission/Android.bp
index 71a52bb..e30df05 100644
--- a/apex/permission/Android.bp
+++ b/apex/permission/Android.bp
@@ -21,7 +21,7 @@
 apex_defaults {
     name: "com.android.permission-defaults",
     updatable: true,
-    min_sdk_version: "R",
+    min_sdk_version: "30",
     key: "com.android.permission.key",
     certificate: ":com.android.permission.certificate",
     java_libs: [
diff --git a/api/current.txt b/api/current.txt
index 1a405d52..69f7645 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -42821,10 +42821,11 @@
     method public String getKeystoreAlias();
     method public int getOrigin();
     method public int getPurposes();
+    method public int getSecurityLevel();
     method @NonNull public String[] getSignaturePaddings();
     method public int getUserAuthenticationType();
     method public int getUserAuthenticationValidityDurationSeconds();
-    method public boolean isInsideSecureHardware();
+    method @Deprecated public boolean isInsideSecureHardware();
     method public boolean isInvalidatedByBiometricEnrollment();
     method public boolean isTrustedUserPresenceRequired();
     method public boolean isUserAuthenticationRequired();
@@ -45850,6 +45851,8 @@
     field public static final String EXTRA_ANSWERING_DROPS_FG_CALL = "android.telecom.extra.ANSWERING_DROPS_FG_CALL";
     field public static final String EXTRA_ANSWERING_DROPS_FG_CALL_APP_NAME = "android.telecom.extra.ANSWERING_DROPS_FG_CALL_APP_NAME";
     field public static final String EXTRA_AUDIO_CODEC = "android.telecom.extra.AUDIO_CODEC";
+    field public static final String EXTRA_AUDIO_CODEC_BANDWIDTH_KHZ = "android.telecom.extra.AUDIO_CODEC_BANDWIDTH_KHZ";
+    field public static final String EXTRA_AUDIO_CODEC_BITRATE_KBPS = "android.telecom.extra.AUDIO_CODEC_BITRATE_KBPS";
     field public static final String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
     field public static final String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS";
     field public static final String EXTRA_IS_RTT_AUDIO_PRESENT = "android.telecom.extra.IS_RTT_AUDIO_PRESENT";
@@ -46296,6 +46299,7 @@
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getVoiceMailNumber(android.telecom.PhoneAccountHandle);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handleMmi(String);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handleMmi(String, android.telecom.PhoneAccountHandle);
+    method public boolean hasCompanionInCallServiceAccess();
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isInCall();
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isInManagedCall();
     method public boolean isIncomingCallPermitted(android.telecom.PhoneAccountHandle);
diff --git a/api/system-current.txt b/api/system-current.txt
index bc39596..dcffa06 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -9377,8 +9377,13 @@
     ctor public DeviceIdAttestationException(@Nullable String, @Nullable Throwable);
   }
 
+  public final class KeyGenParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+    method public int getNamespace();
+  }
+
   public static final class KeyGenParameterSpec.Builder {
-    method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUid(int);
+    method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setNamespace(int);
+    method @Deprecated @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUid(int);
   }
 
 }
@@ -10587,6 +10592,17 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallQuality> CREATOR;
   }
 
+  public final class CarrierBandwidth implements android.os.Parcelable {
+    ctor public CarrierBandwidth(int, int, int, int);
+    method public int describeContents();
+    method public int getPrimaryDownlinkCapacityKbps();
+    method public int getPrimaryUplinkCapacityKbps();
+    method public int getSecondaryDownlinkCapacityKbps();
+    method public int getSecondaryUplinkCapacityKbps();
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CarrierBandwidth> CREATOR;
+    field public static final int INVALID = -1; // 0xffffffff
+  }
+
   public class CarrierConfigManager {
     method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDefaultCarrierServicePackageName();
     method @NonNull public static android.os.PersistableBundle getDefaultConfig();
@@ -11203,6 +11219,7 @@
     method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getAndUpdateDefaultRespondViaMessageApplication();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getCallForwarding(int, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CallForwardingInfoCallback);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getCallWaitingStatus(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+    method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CarrierBandwidth getCarrierBandwidth();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int);
     method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
     method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int);
diff --git a/core/api/current.txt b/core/api/current.txt
index 35abacb..055f909 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -40989,10 +40989,11 @@
     method public String getKeystoreAlias();
     method public int getOrigin();
     method public int getPurposes();
+    method public int getSecurityLevel();
     method @NonNull public String[] getSignaturePaddings();
     method public int getUserAuthenticationType();
     method public int getUserAuthenticationValidityDurationSeconds();
-    method public boolean isInsideSecureHardware();
+    method @Deprecated public boolean isInsideSecureHardware();
     method public boolean isInvalidatedByBiometricEnrollment();
     method public boolean isTrustedUserPresenceRequired();
     method public boolean isUserAuthenticationRequired();
@@ -44018,6 +44019,8 @@
     field public static final String EXTRA_ANSWERING_DROPS_FG_CALL = "android.telecom.extra.ANSWERING_DROPS_FG_CALL";
     field public static final String EXTRA_ANSWERING_DROPS_FG_CALL_APP_NAME = "android.telecom.extra.ANSWERING_DROPS_FG_CALL_APP_NAME";
     field public static final String EXTRA_AUDIO_CODEC = "android.telecom.extra.AUDIO_CODEC";
+    field public static final String EXTRA_AUDIO_CODEC_BANDWIDTH_KHZ = "android.telecom.extra.AUDIO_CODEC_BANDWIDTH_KHZ";
+    field public static final String EXTRA_AUDIO_CODEC_BITRATE_KBPS = "android.telecom.extra.AUDIO_CODEC_BITRATE_KBPS";
     field public static final String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
     field public static final String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS";
     field public static final String EXTRA_IS_RTT_AUDIO_PRESENT = "android.telecom.extra.IS_RTT_AUDIO_PRESENT";
@@ -44464,6 +44467,7 @@
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getVoiceMailNumber(android.telecom.PhoneAccountHandle);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handleMmi(String);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handleMmi(String, android.telecom.PhoneAccountHandle);
+    method public boolean hasCompanionInCallServiceAccess();
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isInCall();
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isInManagedCall();
     method public boolean isIncomingCallPermitted(android.telecom.PhoneAccountHandle);
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 2ebbf6d..18d1064 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -8259,8 +8259,13 @@
     ctor public DeviceIdAttestationException(@Nullable String, @Nullable Throwable);
   }
 
+  public final class KeyGenParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+    method public int getNamespace();
+  }
+
   public static final class KeyGenParameterSpec.Builder {
-    method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUid(int);
+    method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setNamespace(int);
+    method @Deprecated @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUid(int);
   }
 
 }
@@ -9469,6 +9474,17 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallQuality> CREATOR;
   }
 
+  public final class CarrierBandwidth implements android.os.Parcelable {
+    ctor public CarrierBandwidth(int, int, int, int);
+    method public int describeContents();
+    method public int getPrimaryDownlinkCapacityKbps();
+    method public int getPrimaryUplinkCapacityKbps();
+    method public int getSecondaryDownlinkCapacityKbps();
+    method public int getSecondaryUplinkCapacityKbps();
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CarrierBandwidth> CREATOR;
+    field public static final int INVALID = -1; // 0xffffffff
+  }
+
   public class CarrierConfigManager {
     method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDefaultCarrierServicePackageName();
     method @NonNull public static android.os.PersistableBundle getDefaultConfig();
@@ -10085,6 +10101,7 @@
     method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getAndUpdateDefaultRespondViaMessageApplication();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getCallForwarding(int, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CallForwardingInfoCallback);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getCallWaitingStatus(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+    method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CarrierBandwidth getCarrierBandwidth();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int);
     method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
     method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int);
diff --git a/core/java/android/app/backup/OWNERS b/core/java/android/app/backup/OWNERS
index 7e7710b..0f88811 100644
--- a/core/java/android/app/backup/OWNERS
+++ b/core/java/android/app/backup/OWNERS
@@ -1,4 +1,4 @@
 # Bug component: 656484
 
-include platform/frameworks/base/services/backup:/OWNERS
+include platform/frameworks/base:/services/backup/OWNERS
 
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index dbddc22..6648259 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -40,7 +40,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.app.usage.StorageStatsManager;
 import android.compat.annotation.ChangeId;
-import android.compat.annotation.EnabledAfter;
+import android.compat.annotation.EnabledSince;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.Context;
@@ -3682,7 +3682,7 @@
      * @hide
      */
     @ChangeId
-    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
+    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.R)
     public static final long FILTER_APPLICATION_QUERY = 135549675L;
 
     /** {@hide} */
diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java
index a985e93..7376830 100644
--- a/core/java/android/net/TrafficStats.java
+++ b/core/java/android/net/TrafficStats.java
@@ -976,11 +976,17 @@
         }
     }
 
-    // NOTE: keep these in sync with android_net_TrafficStats.cpp
-    private static final int TYPE_RX_BYTES = 0;
-    private static final int TYPE_RX_PACKETS = 1;
-    private static final int TYPE_TX_BYTES = 2;
-    private static final int TYPE_TX_PACKETS = 3;
-    private static final int TYPE_TCP_RX_PACKETS = 4;
-    private static final int TYPE_TCP_TX_PACKETS = 5;
+    // NOTE: keep these in sync with {@code com_android_server_net_NetworkStatsService.cpp}.
+    /** {@hide} */
+    public static final int TYPE_RX_BYTES = 0;
+    /** {@hide} */
+    public static final int TYPE_RX_PACKETS = 1;
+    /** {@hide} */
+    public static final int TYPE_TX_BYTES = 2;
+    /** {@hide} */
+    public static final int TYPE_TX_PACKETS = 3;
+    /** {@hide} */
+    public static final int TYPE_TCP_RX_PACKETS = 4;
+    /** {@hide} */
+    public static final int TYPE_TCP_TX_PACKETS = 5;
 }
diff --git a/core/java/android/uwb/RangingParams.java b/core/java/android/uwb/RangingParams.java
deleted file mode 100644
index f23d9ed..0000000
--- a/core/java/android/uwb/RangingParams.java
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
- * Copyright 2020 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.uwb;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.PersistableBundle;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.time.Duration;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * An object used when requesting to open a new {@link RangingSession}.
- * <p>Use {@link RangingParams.Builder} to create an instance of this class.
- *
- *  @hide
- */
-public final class RangingParams implements Parcelable {
-    private final boolean mIsInitiator;
-    private final boolean mIsController;
-    private final Duration mSamplePeriod;
-    private final UwbAddress mLocalDeviceAddress;
-    private final List<UwbAddress> mRemoteDeviceAddresses;
-    private final int mChannelNumber;
-    private final int mTransmitPreambleCodeIndex;
-    private final int mReceivePreambleCodeIndex;
-    private final int mStsPhyPacketType;
-    private final PersistableBundle mSpecificationParameters;
-
-    private RangingParams(boolean isInitiator, boolean isController,
-            @NonNull Duration samplingPeriod, @NonNull UwbAddress localDeviceAddress,
-            @NonNull List<UwbAddress> remoteDeviceAddresses, int channelNumber,
-            int transmitPreambleCodeIndex, int receivePreambleCodeIndex,
-            @StsPhyPacketType int stsPhyPacketType,
-            @NonNull PersistableBundle specificationParameters) {
-        mIsInitiator = isInitiator;
-        mIsController = isController;
-        mSamplePeriod = samplingPeriod;
-        mLocalDeviceAddress = localDeviceAddress;
-        mRemoteDeviceAddresses = remoteDeviceAddresses;
-        mChannelNumber = channelNumber;
-        mTransmitPreambleCodeIndex = transmitPreambleCodeIndex;
-        mReceivePreambleCodeIndex = receivePreambleCodeIndex;
-        mStsPhyPacketType = stsPhyPacketType;
-        mSpecificationParameters = specificationParameters;
-    }
-
-    /**
-     * Get if the local device is the initiator
-     *
-     * @return true if the device is the initiator
-     */
-    public boolean isInitiator() {
-        return mIsInitiator;
-    }
-
-    /**
-     * Get if the local device is the controller
-     *
-     * @return true if the device is the controller
-     */
-    public boolean isController() {
-        return mIsController;
-    }
-
-    /**
-     * The desired amount of time between two adjacent samples of measurement
-     *
-     * @return the ranging sample period
-     */
-    @NonNull
-    public Duration getSamplingPeriod() {
-        return mSamplePeriod;
-    }
-
-    /**
-     * Local device's {@link UwbAddress}
-     *
-     * <p>Simultaneous {@link RangingSession}s on the same device can have different results for
-     * {@link #getLocalDeviceAddress()}.
-     *
-     * @return the local device's {@link UwbAddress}
-     */
-    @NonNull
-    public UwbAddress getLocalDeviceAddress() {
-        return mLocalDeviceAddress;
-    }
-
-    /**
-     * Gets a list of all remote device's {@link UwbAddress}
-     *
-     * @return a {@link List} of {@link UwbAddress} representing the remote devices
-     */
-    @NonNull
-    public List<UwbAddress> getRemoteDeviceAddresses() {
-        return mRemoteDeviceAddresses;
-    }
-
-    /**
-     * Channel number used between this device pair as defined by 802.15.4z
-     *
-     * Range: -1, 0-15
-     *
-     * @return the channel to use
-     */
-    public int getChannelNumber() {
-        return mChannelNumber;
-    }
-
-    /**
-     * Preamble index used between this device pair as defined by 802.15.4z
-     *
-     * Range: 0, 0-32
-     *
-     * @return the preamble index to use for transmitting
-     */
-    public int getTxPreambleIndex() {
-        return mTransmitPreambleCodeIndex;
-    }
-
-    /**
-     * preamble index used between this device pair as defined by 802.15.4z
-     *
-     * Range: 0, 13-16, 21-32
-     *
-     * @return the preamble index to use for receiving
-     */
-    public int getRxPreambleIndex() {
-        return mReceivePreambleCodeIndex;
-    }
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = {
-            STS_PHY_PACKET_TYPE_SP0,
-            STS_PHY_PACKET_TYPE_SP1,
-            STS_PHY_PACKET_TYPE_SP2,
-            STS_PHY_PACKET_TYPE_SP3})
-    public @interface StsPhyPacketType {}
-
-    /**
-     * PHY packet type SP0 when STS is used as defined by 802.15.4z
-     */
-    public static final int STS_PHY_PACKET_TYPE_SP0 = 0;
-
-    /**
-     * PHY packet type SP1 when STS is used as defined by 802.15.4z
-     */
-    public static final int STS_PHY_PACKET_TYPE_SP1 = 1;
-
-    /**
-     * PHY packet type SP2 when STS is used as defined by 802.15.4z
-     */
-    public static final int STS_PHY_PACKET_TYPE_SP2 = 2;
-
-    /**
-     * PHY packet type SP3 when STS is used as defined by 802.15.4z
-     */
-    public static final int STS_PHY_PACKET_TYPE_SP3 = 3;
-
-    /**
-     * Get the type of PHY packet when STS is used as defined by 802.15.4z
-     *
-     * @return the {@link StsPhyPacketType} to use
-     */
-    @StsPhyPacketType
-    public int getStsPhyPacketType() {
-        return mStsPhyPacketType;
-    }
-
-    /**
-     * Parameters for a specific UWB protocol constructed using a support library.
-     *
-     * <p>Android reserves the '^android.*' namespace
-     *
-     * @return a {@link PersistableBundle} copy of protocol specific parameters
-     */
-    public @Nullable PersistableBundle getSpecificationParameters() {
-        return new PersistableBundle(mSpecificationParameters);
-    }
-
-    /**
-     * @hide
-     */
-    @Override
-    public boolean equals(@Nullable Object obj) {
-        if (this == obj) {
-            return true;
-        }
-
-        if (obj instanceof RangingParams) {
-            RangingParams other = (RangingParams) obj;
-
-            return mIsInitiator == other.mIsInitiator
-                    && mIsController == other.mIsController
-                    && mSamplePeriod.equals(other.mSamplePeriod)
-                    && mLocalDeviceAddress.equals(other.mLocalDeviceAddress)
-                    && mRemoteDeviceAddresses.equals(other.mRemoteDeviceAddresses)
-                    && mChannelNumber == other.mChannelNumber
-                    && mTransmitPreambleCodeIndex == other.mTransmitPreambleCodeIndex
-                    && mReceivePreambleCodeIndex == other.mReceivePreambleCodeIndex
-                    && mStsPhyPacketType == other.mStsPhyPacketType
-                    && mSpecificationParameters.size() == other.mSpecificationParameters.size()
-                    && mSpecificationParameters.kindofEquals(other.mSpecificationParameters);
-        }
-        return false;
-    }
-
-    /**
-     * @hide
-     */
-    @Override
-    public int hashCode() {
-        return Objects.hash(mIsInitiator, mIsController, mSamplePeriod, mLocalDeviceAddress,
-                mRemoteDeviceAddresses, mChannelNumber, mTransmitPreambleCodeIndex,
-                mReceivePreambleCodeIndex, mStsPhyPacketType, mSpecificationParameters);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeBoolean(mIsInitiator);
-        dest.writeBoolean(mIsController);
-        dest.writeLong(mSamplePeriod.getSeconds());
-        dest.writeInt(mSamplePeriod.getNano());
-        dest.writeParcelable(mLocalDeviceAddress, flags);
-
-        UwbAddress[] remoteAddresses = new UwbAddress[mRemoteDeviceAddresses.size()];
-        mRemoteDeviceAddresses.toArray(remoteAddresses);
-        dest.writeParcelableArray(remoteAddresses, flags);
-
-        dest.writeInt(mChannelNumber);
-        dest.writeInt(mTransmitPreambleCodeIndex);
-        dest.writeInt(mReceivePreambleCodeIndex);
-        dest.writeInt(mStsPhyPacketType);
-        dest.writePersistableBundle(mSpecificationParameters);
-    }
-
-    public static final @android.annotation.NonNull Creator<RangingParams> CREATOR =
-            new Creator<RangingParams>() {
-                @Override
-                public RangingParams createFromParcel(Parcel in) {
-                    Builder builder = new Builder();
-                    builder.setIsInitiator(in.readBoolean());
-                    builder.setIsController(in.readBoolean());
-                    builder.setSamplePeriod(Duration.ofSeconds(in.readLong(), in.readInt()));
-                    builder.setLocalDeviceAddress(
-                            in.readParcelable(UwbAddress.class.getClassLoader()));
-
-                    UwbAddress[] remoteAddresses =
-                            in.readParcelableArray(null, UwbAddress.class);
-                    for (UwbAddress remoteAddress : remoteAddresses) {
-                        builder.addRemoteDeviceAddress(remoteAddress);
-                    }
-
-                    builder.setChannelNumber(in.readInt());
-                    builder.setTransmitPreambleCodeIndex(in.readInt());
-                    builder.setReceivePreambleCodeIndex(in.readInt());
-                    builder.setStsPhPacketType(in.readInt());
-                    builder.setSpecificationParameters(in.readPersistableBundle());
-
-                    return builder.build();
-                }
-
-                @Override
-                public RangingParams[] newArray(int size) {
-                    return new RangingParams[size];
-                }
-    };
-
-    /**
-     * Builder class for {@link RangingParams}.
-     */
-    public static final class Builder {
-        private boolean mIsInitiator = false;
-        private boolean mIsController = false;
-        private Duration mSamplePeriod = null;
-        private UwbAddress mLocalDeviceAddress = null;
-        private List<UwbAddress> mRemoteDeviceAddresses = new ArrayList<>();
-        private int mChannelNumber = 0;
-        private int mTransmitPreambleCodeIndex = 0;
-        private int mReceivePreambleCodeIndex = 0;
-        private int mStsPhyPacketType = STS_PHY_PACKET_TYPE_SP0;
-        private PersistableBundle mSpecificationParameters = new PersistableBundle();
-
-        /**
-         * Set whether the device is the initiator or responder as defined by IEEE 802.15.4z
-         *
-         * @param isInitiator whether the device is the initiator (true) or responder (false)
-         */
-        public Builder setIsInitiator(boolean isInitiator) {
-            mIsInitiator = isInitiator;
-            return this;
-        }
-
-        /**
-         * Set whether the local device is the controller or controlee as defined by IEEE 802.15.4z
-         *
-         * @param isController whether the device is the controller (true) or controlee (false)
-         */
-        public Builder setIsController(boolean isController) {
-            mIsController = isController;
-            return this;
-        }
-
-        /**
-         * Set the time between ranging samples
-         *
-         * @param samplePeriod the time between ranging samples
-         */
-        public Builder setSamplePeriod(@NonNull Duration samplePeriod) {
-            mSamplePeriod = samplePeriod;
-            return this;
-        }
-
-        /**
-         * Set the local device address
-         *
-         * @param localDeviceAddress the local device's address for the {@link RangingSession}
-         */
-        public Builder setLocalDeviceAddress(@NonNull UwbAddress localDeviceAddress) {
-            mLocalDeviceAddress = localDeviceAddress;
-            return this;
-        }
-
-        /**
-         * Add a remote device's address to the ranging session
-         *
-         * @param remoteDeviceAddress a remote device's address for the {@link RangingSession}
-         * @throws IllegalArgumentException if {@code remoteDeviceAddress} is already present.
-         */
-        public Builder addRemoteDeviceAddress(@NonNull UwbAddress remoteDeviceAddress) {
-            if (mRemoteDeviceAddresses.contains(remoteDeviceAddress)) {
-                throw new IllegalArgumentException(
-                        "Remote device address already added: " + remoteDeviceAddress.toString());
-            }
-            mRemoteDeviceAddresses.add(remoteDeviceAddress);
-            return this;
-        }
-
-        /**
-         * Set the IEEE 802.15.4z channel to use for the {@link RangingSession}
-         * <p>Valid values are in the range [-1, 15]
-         *
-         * @param channelNumber the channel to use for the {@link RangingSession}
-         * @throws IllegalArgumentException if {@code channelNumber} is invalid.
-         */
-        public Builder setChannelNumber(int channelNumber) {
-            if (channelNumber < -1 || channelNumber > 15) {
-                throw new IllegalArgumentException("Invalid channel number");
-            }
-            mChannelNumber = channelNumber;
-            return this;
-        }
-
-        private static final Set<Integer> VALID_TX_PREAMBLE_CODES = new HashSet<Integer>(
-                Arrays.asList(0, 13, 14, 15, 16, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32));
-
-        /**
-         * Set the IEEE 802.15.4z preamble code index to use when transmitting
-         *
-         * <p>Valid values are in the ranges: [0], [13-16], [21-32]
-         *
-         * @param transmitPreambleCodeIndex preamble code index to use for transmitting
-         * @throws IllegalArgumentException if {@code transmitPreambleCodeIndex} is invalid.
-         */
-        public Builder setTransmitPreambleCodeIndex(int transmitPreambleCodeIndex) {
-            if (!VALID_TX_PREAMBLE_CODES.contains(transmitPreambleCodeIndex)) {
-                throw new IllegalArgumentException(
-                        "Invalid transmit preamble: " + transmitPreambleCodeIndex);
-            }
-            mTransmitPreambleCodeIndex = transmitPreambleCodeIndex;
-            return this;
-        }
-
-        private static final Set<Integer> VALID_RX_PREAMBLE_CODES = new HashSet<Integer>(
-                Arrays.asList(0, 16, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32));
-
-        /**
-         * Set the IEEE 802.15.4z preamble code index to use when receiving
-         *
-         * Valid values are in the ranges: [0], [16-32]
-         *
-         * @param receivePreambleCodeIndex preamble code index to use for receiving
-         * @throws IllegalArgumentException if {@code receivePreambleCodeIndex} is invalid.
-         */
-        public Builder setReceivePreambleCodeIndex(int receivePreambleCodeIndex) {
-            if (!VALID_RX_PREAMBLE_CODES.contains(receivePreambleCodeIndex)) {
-                throw new IllegalArgumentException(
-                        "Invalid receive preamble: " + receivePreambleCodeIndex);
-            }
-            mReceivePreambleCodeIndex = receivePreambleCodeIndex;
-            return this;
-        }
-
-        /**
-         * Set the IEEE 802.15.4z PHY packet type when STS is used
-         *
-         * @param stsPhyPacketType PHY packet type when STS is used
-         * @throws IllegalArgumentException if {@code stsPhyPacketType} is invalid.
-         */
-        public Builder setStsPhPacketType(@StsPhyPacketType int stsPhyPacketType) {
-            if (stsPhyPacketType != STS_PHY_PACKET_TYPE_SP0
-                    && stsPhyPacketType != STS_PHY_PACKET_TYPE_SP1
-                    && stsPhyPacketType != STS_PHY_PACKET_TYPE_SP2
-                    && stsPhyPacketType != STS_PHY_PACKET_TYPE_SP3) {
-                throw new IllegalArgumentException("unknown StsPhyPacketType: " + stsPhyPacketType);
-            }
-
-            mStsPhyPacketType = stsPhyPacketType;
-            return this;
-        }
-
-        /**
-         * Set the specification parameters
-         *
-         * <p>Creates a copy of the parameters
-         *
-         * @param parameters specification parameters built from support library
-         */
-        public Builder setSpecificationParameters(@NonNull PersistableBundle parameters) {
-            mSpecificationParameters = new PersistableBundle(parameters);
-            return this;
-        }
-
-        /**
-         * Build the {@link RangingParams} object.
-         *
-         * @throws IllegalStateException if required parameters are missing
-         */
-        public RangingParams build() {
-            if (mSamplePeriod == null) {
-                throw new IllegalStateException("No sample period provided");
-            }
-
-            if (mLocalDeviceAddress == null) {
-                throw new IllegalStateException("Local device address not provided");
-            }
-
-            if (mRemoteDeviceAddresses.size() == 0) {
-                throw new IllegalStateException("No remote device address(es) provided");
-            }
-
-            return new RangingParams(mIsInitiator, mIsController, mSamplePeriod,
-                    mLocalDeviceAddress, mRemoteDeviceAddresses, mChannelNumber,
-                    mTransmitPreambleCodeIndex, mReceivePreambleCodeIndex, mStsPhyPacketType,
-                    mSpecificationParameters);
-        }
-    }
-}
diff --git a/core/java/android/uwb/RangingSession.java b/core/java/android/uwb/RangingSession.java
index f4033fe..8639269 100644
--- a/core/java/android/uwb/RangingSession.java
+++ b/core/java/android/uwb/RangingSession.java
@@ -30,7 +30,7 @@
  * {@link RangingSession}.
  *
  * <p>To get an instance of {@link RangingSession}, first use
- * {@link UwbManager#openRangingSession(RangingParams, Executor, Callback)} to request to open a
+ * {@link UwbManager#openRangingSession(PersistableBundle, Executor, Callback)} to request to open a
  * session. Once the session is opened, a {@link RangingSession} object is provided through
  * {@link RangingSession.Callback#onOpenSuccess(RangingSession, PersistableBundle)}. If opening a
  * session fails, the failure is reported through {@link RangingSession.Callback#onClosed(int)} with
@@ -44,7 +44,7 @@
      */
     public interface Callback {
         /**
-         * Invoked when {@link UwbManager#openRangingSession(RangingParams, Executor, Callback)}
+         * Invoked when {@link UwbManager#openRangingSession(PersistableBundle, Executor, Callback)}
          * is successful
          *
          * @param session the newly opened {@link RangingSession}
@@ -77,7 +77,7 @@
 
         /**
          * Indicates that the session failed to open due to erroneous parameters passed
-         * to {@link UwbManager#openRangingSession(RangingParams, Executor, Callback)}
+         * to {@link UwbManager#openRangingSession(PersistableBundle, Executor, Callback)}
          */
         int CLOSE_REASON_LOCAL_BAD_PARAMETERS = 2;
 
@@ -137,8 +137,8 @@
      * will still be invoked.
      *
      * <p>{@link Callback#onClosed(int)} will be invoked using the same callback
-     * object given to {@link UwbManager#openRangingSession(RangingParams, Executor, Callback)} when
-     * the {@link RangingSession} was opened. The callback will be invoked after each call to
+     * object given to {@link UwbManager#openRangingSession(PersistableBundle, Executor, Callback)}
+     * when the {@link RangingSession} was opened. The callback will be invoked after each call to
      * {@link #close()}, even if the {@link RangingSession} is already closed.
      */
     @Override
diff --git a/core/java/android/uwb/UwbManager.java b/core/java/android/uwb/UwbManager.java
index 6bf7d6f..2f1e2de 100644
--- a/core/java/android/uwb/UwbManager.java
+++ b/core/java/android/uwb/UwbManager.java
@@ -279,7 +279,10 @@
      * <p>An open {@link RangingSession} will be automatically closed if client application process
      * dies.
      *
-     * @param params {@link RangingParams} used to initialize this {@link RangingSession}
+     * <p>A UWB support library must be used in order to construct the {@code parameter}
+     * {@link PersistableBundle}.
+     *
+     * @param parameters the parameters that define the ranging session
      * @param executor {@link Executor} to run callbacks
      * @param callbacks {@link RangingSession.Callback} to associate with the
      *                  {@link RangingSession} that is being opened.
@@ -290,8 +293,9 @@
      *         {@link RangingSession.Callback#onOpenSuccess}.
      */
     @NonNull
-    public AutoCloseable openRangingSession(@NonNull RangingParams params,
-            @NonNull Executor executor, @NonNull RangingSession.Callback callbacks) {
+    public AutoCloseable openRangingSession(@NonNull PersistableBundle parameters,
+            @NonNull Executor executor,
+            @NonNull RangingSession.Callback callbacks) {
         throw new UnsupportedOperationException();
     }
 }
diff --git a/core/tests/uwbtests/src/android/uwb/RangingParamsTest.java b/core/tests/uwbtests/src/android/uwb/RangingParamsTest.java
deleted file mode 100644
index 8095c99..0000000
--- a/core/tests/uwbtests/src/android/uwb/RangingParamsTest.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright 2020 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.uwb;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-import android.os.PersistableBundle;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.time.Duration;
-
-/**
- * Test of {@link RangingParams}.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class RangingParamsTest {
-
-    @Test
-    public void testParams_Build() {
-        UwbAddress local = UwbAddress.fromBytes(new byte[] {(byte) 0xA0, (byte) 0x57});
-        UwbAddress remote = UwbAddress.fromBytes(new byte[] {(byte) 0x4D, (byte) 0x8C});
-        int channel = 9;
-        int rxPreamble = 16;
-        int txPreamble = 21;
-        boolean isController = true;
-        boolean isInitiator = false;
-        @RangingParams.StsPhyPacketType int stsPhyType = RangingParams.STS_PHY_PACKET_TYPE_SP2;
-        Duration samplePeriod = Duration.ofSeconds(1, 234);
-        PersistableBundle specParams = new PersistableBundle();
-        specParams.putString("protocol", "some_protocol");
-
-        RangingParams params = new RangingParams.Builder()
-                .setChannelNumber(channel)
-                .setReceivePreambleCodeIndex(rxPreamble)
-                .setTransmitPreambleCodeIndex(txPreamble)
-                .setLocalDeviceAddress(local)
-                .addRemoteDeviceAddress(remote)
-                .setIsController(isController)
-                .setIsInitiator(isInitiator)
-                .setSamplePeriod(samplePeriod)
-                .setStsPhPacketType(stsPhyType)
-                .setSpecificationParameters(specParams)
-                .build();
-
-        assertEquals(params.getLocalDeviceAddress(), local);
-        assertEquals(params.getRemoteDeviceAddresses().size(), 1);
-        assertEquals(params.getRemoteDeviceAddresses().get(0), remote);
-        assertEquals(params.getChannelNumber(), channel);
-        assertEquals(params.isController(), isController);
-        assertEquals(params.isInitiator(), isInitiator);
-        assertEquals(params.getRxPreambleIndex(), rxPreamble);
-        assertEquals(params.getTxPreambleIndex(), txPreamble);
-        assertEquals(params.getStsPhyPacketType(), stsPhyType);
-        assertEquals(params.getSamplingPeriod(), samplePeriod);
-        assertTrue(params.getSpecificationParameters().kindofEquals(specParams));
-    }
-
-    @Test
-    public void testParcel() {
-        Parcel parcel = Parcel.obtain();
-        RangingParams params = new RangingParams.Builder()
-                .setChannelNumber(9)
-                .setReceivePreambleCodeIndex(16)
-                .setTransmitPreambleCodeIndex(21)
-                .setLocalDeviceAddress(UwbTestUtils.getUwbAddress(false))
-                .addRemoteDeviceAddress(UwbTestUtils.getUwbAddress(true))
-                .setIsController(false)
-                .setIsInitiator(true)
-                .setSamplePeriod(Duration.ofSeconds(2))
-                .setStsPhPacketType(RangingParams.STS_PHY_PACKET_TYPE_SP1)
-                .build();
-        params.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        RangingParams fromParcel = RangingParams.CREATOR.createFromParcel(parcel);
-        assertEquals(params, fromParcel);
-    }
-}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
index 71e6559..d1b4464 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
@@ -23,6 +23,7 @@
 import android.security.keymaster.ExportResult;
 import android.security.keymaster.KeyCharacteristics;
 import android.security.keymaster.KeymasterDefs;
+import android.sysprop.Keystore2Properties;
 
 import java.io.IOException;
 import java.security.KeyFactory;
@@ -111,6 +112,26 @@
         putSecretKeyFactoryImpl("HmacSHA512");
     }
 
+    private static boolean sKeystore2Enabled;
+
+    /**
+     * This function indicates whether or not Keystore 2.0 is enabled. Some parts of the
+     * Keystore SPI must behave subtly differently when Keystore 2.0 is enabled. However,
+     * the platform property that indicates that Keystore 2.0 is enabled is not readable
+     * by applications. So we set this value when {@code install()} is called because it
+     * is called by zygote, which can access Keystore2Properties.
+     *
+     * This function can be removed once the transition to Keystore 2.0 is complete.
+     * b/171305684
+     *
+     * @return true if Keystore 2.0 is enabled.
+     * @hide
+     */
+    public static boolean isKeystore2Enabled() {
+        return sKeystore2Enabled;
+    }
+
+
     /**
      * Installs a new instance of this provider (and the
      * {@link AndroidKeyStoreBCWorkaroundProvider}).
@@ -138,6 +159,11 @@
             // priority.
             Security.addProvider(workaroundProvider);
         }
+
+        // {@code install()} is run by zygote when this property is still accessible. We store its
+        // value so that the Keystore SPI can act accordingly without having to access an internal
+        // property.
+        sKeystore2Enabled = Keystore2Properties.keystore2_enabled().orElse(false);
     }
 
     private void putSecretKeyFactoryImpl(String algorithm) {
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
index 9707260..3694d63 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
@@ -211,7 +211,11 @@
                 userAuthenticationValidWhileOnBody,
                 trustedUserPresenceRequired,
                 invalidatedByBiometricEnrollment,
-                userConfirmationRequired);
+                userConfirmationRequired,
+                // Keystore 1.0 does not tell us the exact security level of the key
+                // so we report an unknown but secure security level.
+                insideSecureHardware ? KeyProperties.SECURITY_LEVEL_UNKNOWN_SECURE
+                        : KeyProperties.SECURITY_LEVEL_SOFTWARE);
     }
 
     private static BigInteger getGateKeeperSecureUserId() throws ProviderException {
diff --git a/keystore/java/android/security/keystore/ArrayUtils.java b/keystore/java/android/security/keystore/ArrayUtils.java
index f519c7c..c8c1de4 100644
--- a/keystore/java/android/security/keystore/ArrayUtils.java
+++ b/keystore/java/android/security/keystore/ArrayUtils.java
@@ -18,6 +18,8 @@
 
 import libcore.util.EmptyArray;
 
+import java.util.function.Consumer;
+
 /**
  * @hide
  */
@@ -107,4 +109,16 @@
             return result;
         }
     }
+
+    /**
+     * Runs {@code consumer.accept()} for each element of {@code array}.
+     * @param array
+     * @param consumer
+     * @hide
+     */
+    public static void forEach(int[] array, Consumer<Integer> consumer) {
+        for (int i : array) {
+            consumer.accept(i);
+        }
+    }
 }
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index 688c4a7..e9aac7d 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -27,7 +27,6 @@
 import android.hardware.biometrics.BiometricPrompt;
 import android.os.Build;
 import android.security.GateKeeper;
-import android.security.KeyStore;
 import android.text.TextUtils;
 
 import java.math.BigInteger;
@@ -246,7 +245,7 @@
     private static final Date DEFAULT_CERT_NOT_AFTER = new Date(2461449600000L); // Jan 1 2048
 
     private final String mKeystoreAlias;
-    private final int mUid;
+    private final int mNamespace;
     private final int mKeySize;
     private final AlgorithmParameterSpec mSpec;
     private final X500Principal mCertificateSubject;
@@ -286,7 +285,7 @@
      */
     public KeyGenParameterSpec(
             String keyStoreAlias,
-            int uid,
+            int namespace,
             int keySize,
             AlgorithmParameterSpec spec,
             X500Principal certificateSubject,
@@ -337,7 +336,7 @@
         }
 
         mKeystoreAlias = keyStoreAlias;
-        mUid = uid;
+        mNamespace = namespace;
         mKeySize = keySize;
         mSpec = spec;
         mCertificateSubject = certificateSubject;
@@ -382,11 +381,43 @@
      * Returns the UID which will own the key. {@code -1} is an alias for the UID of the current
      * process.
      *
+     * @deprecated See deprecation message on {@link KeyGenParameterSpec.Builder#setUid(int)}.
+     *             Known namespaces will be translated to their legacy UIDs. Unknown
+     *             Namespaces will yield {@link IllegalStateException}.
+     *
      * @hide
      */
     @UnsupportedAppUsage
+    @Deprecated
     public int getUid() {
-        return mUid;
+        if (!AndroidKeyStoreProvider.isKeystore2Enabled()) {
+            // If Keystore2 has not been enabled we have to behave as if mNamespace is actually
+            // a UID, because we are still being used with the old Keystore SPI.
+            // TODO This if statement and body can be removed when the Keystore 2 migration is
+            //      complete. b/171563717
+            return mNamespace;
+        }
+        try {
+            return KeyProperties.namespaceToLegacyUid(mNamespace);
+        } catch (IllegalArgumentException e) {
+            throw new IllegalStateException("getUid called on KeyGenParameterSpec with non legacy"
+                    + " keystore namespace.", e);
+        }
+    }
+
+    /**
+     * Returns the target namespace for the key.
+     * See {@link KeyGenParameterSpec.Builder#setNamespace(int)}.
+     *
+     * @return The numeric namespace as configured in the keystore2_key_contexts files of Android's
+     *         SEPolicy.
+     *         TODO b/171806779 link to public Keystore 2.0 documentation.
+     *              See bug for more details for now.
+     * @hide
+     */
+    @SystemApi
+    public int getNamespace() {
+        return mNamespace;
     }
 
     /**
@@ -767,7 +798,7 @@
         private final String mKeystoreAlias;
         private @KeyProperties.PurposeEnum int mPurposes;
 
-        private int mUid = KeyStore.UID_SELF;
+        private int mNamespace = KeyProperties.NAMESPACE_APPLICATION;
         private int mKeySize = -1;
         private AlgorithmParameterSpec mSpec;
         private X500Principal mCertificateSubject;
@@ -830,7 +861,7 @@
          */
         public Builder(@NonNull KeyGenParameterSpec sourceSpec) {
             this(sourceSpec.getKeystoreAlias(), sourceSpec.getPurposes());
-            mUid = sourceSpec.getUid();
+            mNamespace = sourceSpec.getNamespace();
             mKeySize = sourceSpec.getKeySize();
             mSpec = sourceSpec.getAlgorithmParameterSpec();
             mCertificateSubject = sourceSpec.getCertificateSubject();
@@ -873,12 +904,51 @@
          *
          * @param uid UID or {@code -1} for the UID of the current process.
          *
+         * @deprecated Setting the UID of the target namespace is based on a hardcoded
+         * hack in the Keystore service. This is no longer supported with Keystore 2.0/Android S.
+         * Instead, dedicated non UID based namespaces can be configured in SEPolicy using
+         * the keystore2_key_contexts files. The functionality of this method will be supported
+         * by mapping knows special UIDs, such as WIFI, to the newly configured SELinux based
+         * namespaces. Unknown UIDs will yield {@link IllegalArgumentException}.
+         *
          * @hide
          */
         @SystemApi
         @NonNull
+        @Deprecated
         public Builder setUid(int uid) {
-            mUid = uid;
+            if (!AndroidKeyStoreProvider.isKeystore2Enabled()) {
+                // If Keystore2 has not been enabled we have to behave as if mNamespace is actually
+                // a UID, because we are still being used with the old Keystore SPI.
+                // TODO This if statement and body can be removed when the Keystore 2 migration is
+                //      complete. b/171563717
+                mNamespace = uid;
+                return this;
+            }
+            mNamespace = KeyProperties.legacyUidToNamespace(uid);
+            return this;
+        }
+
+        /**
+         * Set the designated SELinux namespace that the key shall live in. The caller must
+         * have sufficient permissions to install a key in the given namespace. Namespaces
+         * can be created using SEPolicy. The keystore2_key_contexts files map numeric
+         * namespaces to SELinux labels, and SEPolicy can be used to grant access to these
+         * namespaces to the desired target context. This is the preferred way to share
+         * keys between system and vendor components, e.g., WIFI settings and WPA supplicant.
+         *
+         * @param namespace Numeric SELinux namespace as configured in keystore2_key_contexts
+         *                  of Android's SEPolicy.
+         *                  TODO b/171806779 link to public Keystore 2.0 documentation.
+         *                       See bug for more details for now.
+         * @return this Builder object.
+         *
+         * @hide
+         */
+        @SystemApi
+        @NonNull
+        public Builder setNamespace(int namespace) {
+            mNamespace = namespace;
             return this;
         }
 
@@ -1489,7 +1559,7 @@
         public KeyGenParameterSpec build() {
             return new KeyGenParameterSpec(
                     mKeystoreAlias,
-                    mUid,
+                    mNamespace,
                     mKeySize,
                     mSpec,
                     mCertificateSubject,
diff --git a/keystore/java/android/security/keystore/KeyInfo.java b/keystore/java/android/security/keystore/KeyInfo.java
index d891a25..7158d0c 100644
--- a/keystore/java/android/security/keystore/KeyInfo.java
+++ b/keystore/java/android/security/keystore/KeyInfo.java
@@ -84,6 +84,7 @@
     private final boolean mTrustedUserPresenceRequired;
     private final boolean mInvalidatedByBiometricEnrollment;
     private final boolean mUserConfirmationRequired;
+    private final @KeyProperties.SecurityLevelEnum int mSecurityLevel;
 
     /**
      * @hide
@@ -107,7 +108,8 @@
             boolean userAuthenticationValidWhileOnBody,
             boolean trustedUserPresenceRequired,
             boolean invalidatedByBiometricEnrollment,
-            boolean userConfirmationRequired) {
+            boolean userConfirmationRequired,
+            @KeyProperties.SecurityLevelEnum int securityLevel) {
         mKeystoreAlias = keystoreKeyAlias;
         mInsideSecureHardware = insideSecureHardware;
         mOrigin = origin;
@@ -131,6 +133,7 @@
         mTrustedUserPresenceRequired = trustedUserPresenceRequired;
         mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
         mUserConfirmationRequired = userConfirmationRequired;
+        mSecurityLevel = securityLevel;
     }
 
     /**
@@ -144,7 +147,10 @@
      * Returns {@code true} if the key resides inside secure hardware (e.g., Trusted Execution
      * Environment (TEE) or Secure Element (SE)). Key material of such keys is available in
      * plaintext only inside the secure hardware and is not exposed outside of it.
+     *
+     * @deprecated This method is superseded by @see getSecurityLevel.
      */
+    @Deprecated
     public boolean isInsideSecureHardware() {
         return mInsideSecureHardware;
     }
@@ -355,4 +361,17 @@
     public boolean isTrustedUserPresenceRequired() {
         return mTrustedUserPresenceRequired;
     }
+
+    /**
+     * Returns the security level that the key is protected by.
+     * {@code KeyProperties.SecurityLevelEnum.TRUSTED_ENVIRONMENT} and
+     * {@code KeyProperties.SecurityLevelEnum.STRONGBOX} indicate that the key material resides
+     * in secure hardware. Key material of such keys is available in
+     * plaintext only inside the secure hardware and is not exposed outside of it.
+     *
+     * <p>See {@link KeyProperties}.{@code SecurityLevelEnum} constants.
+     */
+    public @KeyProperties.SecurityLevelEnum int getSecurityLevel() {
+        return mSecurityLevel;
+    }
 }
diff --git a/keystore/java/android/security/keystore/KeyProperties.java b/keystore/java/android/security/keystore/KeyProperties.java
index 9050c69..5928540 100644
--- a/keystore/java/android/security/keystore/KeyProperties.java
+++ b/keystore/java/android/security/keystore/KeyProperties.java
@@ -20,6 +20,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.StringDef;
+import android.security.KeyStore;
 import android.security.keymaster.KeymasterDefs;
 
 import libcore.util.EmptyArray;
@@ -857,4 +858,43 @@
         }
     }
 
+    /**
+     * This value indicates the implicit keystore namespace of the calling application.
+     * It is used by default. Only select system components can choose a different namespace
+     * which it must be configured in SEPolicy.
+     * @hide
+     */
+    public static final int NAMESPACE_APPLICATION = -1;
+
+    /**
+     * For legacy support, translate namespaces into known UIDs.
+     * @hide
+     */
+    public static int namespaceToLegacyUid(int namespace) {
+        switch (namespace) {
+            case NAMESPACE_APPLICATION:
+                return KeyStore.UID_SELF;
+            // TODO Translate WIFI and VPN UIDs once the namespaces are defined.
+            //  b/171305388 and b/171305607
+            default:
+                throw new IllegalArgumentException("No UID corresponding to namespace "
+                        + namespace);
+        }
+    }
+
+    /**
+     * For legacy support, translate namespaces into known UIDs.
+     * @hide
+     */
+    public static int legacyUidToNamespace(int uid) {
+        switch (uid) {
+            case KeyStore.UID_SELF:
+                return NAMESPACE_APPLICATION;
+            // TODO Translate WIFI and VPN UIDs once the namespaces are defined.
+            //  b/171305388 and b/171305607
+            default:
+                throw new IllegalArgumentException("No namespace corresponding to uid "
+                        + uid);
+        }
+    }
 }
diff --git a/libs/WindowManager/Shell/OWNERS b/libs/WindowManager/Shell/OWNERS
index 4390004..36da7aa 100644
--- a/libs/WindowManager/Shell/OWNERS
+++ b/libs/WindowManager/Shell/OWNERS
@@ -1,4 +1,5 @@
 # sysui owners
 hwwang@google.com
 mrenouf@google.com
-winsonc@google.com
\ No newline at end of file
+winsonc@google.com
+madym@google.com
diff --git a/packages/SettingsProvider/src/android/provider/settings/OWNERS b/packages/SettingsProvider/src/android/provider/settings/OWNERS
index 7e7710b..0f88811 100644
--- a/packages/SettingsProvider/src/android/provider/settings/OWNERS
+++ b/packages/SettingsProvider/src/android/provider/settings/OWNERS
@@ -1,4 +1,4 @@
 # Bug component: 656484
 
-include platform/frameworks/base/services/backup:/OWNERS
+include platform/frameworks/base:/services/backup/OWNERS
 
diff --git a/packages/SettingsProvider/test/src/android/provider/OWNERS b/packages/SettingsProvider/test/src/android/provider/OWNERS
index 7e7710b..0f88811 100644
--- a/packages/SettingsProvider/test/src/android/provider/OWNERS
+++ b/packages/SettingsProvider/test/src/android/provider/OWNERS
@@ -1,4 +1,4 @@
 # Bug component: 656484
 
-include platform/frameworks/base/services/backup:/OWNERS
+include platform/frameworks/base:/services/backup/OWNERS
 
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 12c24d4..81a6641 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -1084,12 +1084,10 @@
             return nativeIfaceStats;
         } else {
             // When tethering offload is in use, nativeIfaceStats does not contain usage from
-            // offload, add it back here.
-            // When tethering offload is not in use, nativeIfaceStats contains tethering usage.
-            // this does not cause double-counting of tethering traffic, because
-            // NetdTetheringStatsProvider returns zero NetworkStats
-            // when called with STATS_PER_IFACE.
-            return nativeIfaceStats + getTetherStats(iface, type);
+            // offload, add it back here. Note that the included statistics might be stale
+            // since polling newest stats from hardware might impact system health and not
+            // suitable for TrafficStats API use cases.
+            return nativeIfaceStats + getProviderIfaceStats(iface, type);
         }
     }
 
@@ -1100,39 +1098,28 @@
             return nativeTotalStats;
         } else {
             // Refer to comment in getIfaceStats
-            return nativeTotalStats + getTetherStats(IFACE_ALL, type);
+            return nativeTotalStats + getProviderIfaceStats(IFACE_ALL, type);
         }
     }
 
-    private long getTetherStats(String iface, int type) {
-        final NetworkStats tetherSnapshot;
-        final long token = Binder.clearCallingIdentity();
-        try {
-            tetherSnapshot = getNetworkStatsTethering(STATS_PER_IFACE);
-        } catch (RemoteException e) {
-            Slog.w(TAG, "Error get TetherStats: " + e);
-            return 0;
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-        HashSet<String> limitIfaces;
+    private long getProviderIfaceStats(@Nullable String iface, int type) {
+        final NetworkStats providerSnapshot = getNetworkStatsFromProviders(STATS_PER_IFACE);
+        final HashSet<String> limitIfaces;
         if (iface == IFACE_ALL) {
             limitIfaces = null;
         } else {
-            limitIfaces = new HashSet<String>();
+            limitIfaces = new HashSet<>();
             limitIfaces.add(iface);
         }
-        NetworkStats.Entry entry = tetherSnapshot.getTotal(null, limitIfaces);
-        if (LOGD) Slog.d(TAG, "TetherStats: iface=" + iface + " type=" + type +
-                " entry=" + entry);
+        final NetworkStats.Entry entry = providerSnapshot.getTotal(null, limitIfaces);
         switch (type) {
-            case 0: // TYPE_RX_BYTES
+            case TrafficStats.TYPE_RX_BYTES:
                 return entry.rxBytes;
-            case 1: // TYPE_RX_PACKETS
+            case TrafficStats.TYPE_RX_PACKETS:
                 return entry.rxPackets;
-            case 2: // TYPE_TX_BYTES
+            case TrafficStats.TYPE_TX_BYTES:
                 return entry.txBytes;
-            case 3: // TYPE_TX_PACKETS
+            case TrafficStats.TYPE_TX_PACKETS:
                 return entry.txPackets;
             default:
                 return 0;
@@ -1429,14 +1416,6 @@
         final NetworkStats devSnapshot = readNetworkStatsSummaryDev();
         Trace.traceEnd(TRACE_TAG_NETWORK);
 
-        // Tethering snapshot for dev and xt stats. Counts per-interface data from tethering stats
-        // providers that isn't already counted by dev and XT stats.
-        Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotTether");
-        final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_IFACE);
-        Trace.traceEnd(TRACE_TAG_NETWORK);
-        xtSnapshot.combineAllValues(tetherSnapshot);
-        devSnapshot.combineAllValues(tetherSnapshot);
-
         // Snapshot for dev/xt stats from all custom stats providers. Counts per-interface data
         // from stats providers that isn't already counted by dev and XT stats.
         Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotStatsProvider");
@@ -1511,29 +1490,7 @@
         final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0;
         final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
 
-        // Request asynchronous stats update from all providers for next poll. And wait a bit of
-        // time to allow providers report-in given that normally binder call should be fast. Note
-        // that size of list might be changed because addition/removing at the same time. For
-        // addition, the stats of the missed provider can only be collected in next poll;
-        // for removal, wait might take up to MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS
-        // once that happened.
-        // TODO: request with a valid token.
-        Trace.traceBegin(TRACE_TAG_NETWORK, "provider.requestStatsUpdate");
-        final int registeredCallbackCount = mStatsProviderCbList.size();
-        mStatsProviderSem.drainPermits();
-        invokeForAllStatsProviderCallbacks(
-                (cb) -> cb.mProvider.onRequestStatsUpdate(0 /* unused */));
-        try {
-            mStatsProviderSem.tryAcquire(registeredCallbackCount,
-                    MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException e) {
-            // Strictly speaking it's possible a provider happened to deliver between the timeout
-            // and the log, and that doesn't matter too much as this is just a debug log.
-            Log.d(TAG, "requestStatsUpdate - providers responded "
-                    + mStatsProviderSem.availablePermits()
-                    + "/" + registeredCallbackCount + " : " + e);
-        }
-        Trace.traceEnd(TRACE_TAG_NETWORK);
+        performPollFromProvidersLocked();
 
         // TODO: consider marking "untrusted" times in historical stats
         final long currentTime = mClock.millis();
@@ -1578,6 +1535,33 @@
         Trace.traceEnd(TRACE_TAG_NETWORK);
     }
 
+    @GuardedBy("mStatsLock")
+    private void performPollFromProvidersLocked() {
+        // Request asynchronous stats update from all providers for next poll. And wait a bit of
+        // time to allow providers report-in given that normally binder call should be fast. Note
+        // that size of list might be changed because addition/removing at the same time. For
+        // addition, the stats of the missed provider can only be collected in next poll;
+        // for removal, wait might take up to MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS
+        // once that happened.
+        // TODO: request with a valid token.
+        Trace.traceBegin(TRACE_TAG_NETWORK, "provider.requestStatsUpdate");
+        final int registeredCallbackCount = mStatsProviderCbList.size();
+        mStatsProviderSem.drainPermits();
+        invokeForAllStatsProviderCallbacks(
+                (cb) -> cb.mProvider.onRequestStatsUpdate(0 /* unused */));
+        try {
+            mStatsProviderSem.tryAcquire(registeredCallbackCount,
+                    MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            // Strictly speaking it's possible a provider happened to deliver between the timeout
+            // and the log, and that doesn't matter too much as this is just a debug log.
+            Log.d(TAG, "requestStatsUpdate - providers responded "
+                    + mStatsProviderSem.availablePermits()
+                    + "/" + registeredCallbackCount + " : " + e);
+        }
+        Trace.traceEnd(TRACE_TAG_NETWORK);
+    }
+
     /**
      * Sample recent statistics summary into {@link EventLog}.
      */
@@ -1931,9 +1915,13 @@
     }
 
     /**
-     * Return snapshot of current tethering statistics. Will return empty
-     * {@link NetworkStats} if any problems are encountered.
+     * Return snapshot of current non-offloaded tethering statistics. Will return empty
+     * {@link NetworkStats} if any problems are encountered, or queried by {@code STATS_PER_IFACE}
+     * since it is already included by {@link #nativeGetIfaceStat}.
+     * See {@code OffloadTetheringStatsProvider} for offloaded tethering stats.
      */
+    // TODO: Remove this by implementing {@link NetworkStatsProvider} for non-offloaded
+    //  tethering stats.
     private NetworkStats getNetworkStatsTethering(int how) throws RemoteException {
         try {
             return mNetworkManager.getNetworkStatsTethering(how);
@@ -2226,13 +2214,6 @@
         }
     }
 
-    private static int TYPE_RX_BYTES;
-    private static int TYPE_RX_PACKETS;
-    private static int TYPE_TX_BYTES;
-    private static int TYPE_TX_PACKETS;
-    private static int TYPE_TCP_RX_PACKETS;
-    private static int TYPE_TCP_TX_PACKETS;
-
     private static native long nativeGetTotalStat(int type, boolean useBpfStats);
     private static native long nativeGetIfaceStat(String iface, int type, boolean useBpfStats);
     private static native long nativeGetUidStat(int uid, int type, boolean useBpfStats);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 3d63606..7fa3225 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -10564,7 +10564,7 @@
                     continue;
                 }
                 final PackageSetting staticLibPkgSetting = getPackageSetting(
-                        toStaticSharedLibraryPackageName(sharedLibraryInfo.getPackageName(),
+                        toStaticSharedLibraryPackageName(sharedLibraryInfo.getName(),
                                 sharedLibraryInfo.getLongVersion()));
                 if (staticLibPkgSetting == null) {
                     Slog.wtf(TAG, "Shared lib without setting: " + sharedLibraryInfo);
diff --git a/services/core/jni/com_android_server_net_NetworkStatsService.cpp b/services/core/jni/com_android_server_net_NetworkStatsService.cpp
index 0275f3e..10b248a 100644
--- a/services/core/jni/com_android_server_net_NetworkStatsService.cpp
+++ b/services/core/jni/com_android_server_net_NetworkStatsService.cpp
@@ -215,21 +215,6 @@
 };
 
 int register_android_server_net_NetworkStatsService(JNIEnv* env) {
-    jclass netStatsService = env->FindClass("com/android/server/net/NetworkStatsService");
-    jfieldID rxBytesId = env->GetStaticFieldID(netStatsService, "TYPE_RX_BYTES", "I");
-    jfieldID rxPacketsId = env->GetStaticFieldID(netStatsService, "TYPE_RX_PACKETS", "I");
-    jfieldID txBytesId = env->GetStaticFieldID(netStatsService, "TYPE_TX_BYTES", "I");
-    jfieldID txPacketsId = env->GetStaticFieldID(netStatsService, "TYPE_TX_PACKETS", "I");
-    jfieldID tcpRxPacketsId = env->GetStaticFieldID(netStatsService, "TYPE_TCP_RX_PACKETS", "I");
-    jfieldID tcpTxPacketsId = env->GetStaticFieldID(netStatsService, "TYPE_TCP_TX_PACKETS", "I");
-
-    env->SetStaticIntField(netStatsService, rxBytesId, RX_BYTES);
-    env->SetStaticIntField(netStatsService, rxPacketsId, RX_PACKETS);
-    env->SetStaticIntField(netStatsService, txBytesId, TX_BYTES);
-    env->SetStaticIntField(netStatsService, txPacketsId, TX_PACKETS);
-    env->SetStaticIntField(netStatsService, tcpRxPacketsId, TCP_RX_PACKETS);
-    env->SetStaticIntField(netStatsService, tcpTxPacketsId, TCP_TX_PACKETS);
-
     return jniRegisterNativeMethods(env, "com/android/server/net/NetworkStatsService", gMethods,
                                     NELEM(gMethods));
 }
diff --git a/services/net/Android.bp b/services/net/Android.bp
index 72ad366..29bf374 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -22,13 +22,14 @@
 
 // Version of services.net for usage by the wifi mainline module.
 // Note: This is compiled against module_current.
-// TODO(b/145825329): This should be moved to networkstack-client,
+// TODO(b/172457099): This should be moved to networkstack-client,
 // with dependencies moved to frameworks/libs/net right.
 java_library {
     name: "services.net-module-wifi",
     srcs: [
         ":framework-services-net-module-wifi-shared-srcs",
         ":net-module-utils-srcs",
+        ":net-utils-services-common-srcs",
         "java/android/net/ip/IpClientCallbacks.java",
         "java/android/net/ip/IpClientManager.java",
         "java/android/net/ip/IpClientUtil.java",
@@ -39,6 +40,7 @@
         "java/android/net/TcpKeepalivePacketData.java",
     ],
     sdk_version: "module_current",
+    min_sdk_version: "30",
     libs: [
         "unsupportedappusage",
         "framework-wifi-util-lib",
@@ -49,7 +51,6 @@
         "netd_aidl_interface-V3-java",
         "netlink-client",
         "networkstack-client",
-        "net-utils-services-common",
     ],
     apex_available: [
         "com.android.wifi",
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index 1944965..0d878b4 100644
--- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -28,7 +28,6 @@
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.SystemProperties;
 import android.os.UpdateEngine;
 import android.os.UpdateEngineCallback;
 import android.provider.DeviceConfig;
@@ -227,8 +226,8 @@
         }
 
         // Sample for a fraction of app launches.
-        int traceFrequency =
-                SystemProperties.getInt("persist.profcollectd.applaunch_trace_freq", 2);
+        int traceFrequency = DeviceConfig.getInt(DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT,
+                "applaunch_trace_freq", 2);
         int randomNum = ThreadLocalRandom.current().nextInt(100);
         if (randomNum < traceFrequency) {
             try {
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index bbf34df..724a9e4 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -767,6 +767,19 @@
             "android.telecom.extra.AUDIO_CODEC";
 
     /**
+     * Float connection extra key used to store the audio codec bitrate in kbps for the current
+     * {@link Connection}.
+     */
+    public static final String EXTRA_AUDIO_CODEC_BITRATE_KBPS =
+            "android.telecom.extra.AUDIO_CODEC_BITRATE_KBPS";
+
+    /**
+     * Float connection extra key used to store the audio codec bandwidth in khz for the current
+     * {@link Connection}.
+     */
+    public static final String EXTRA_AUDIO_CODEC_BANDWIDTH_KHZ =
+            "android.telecom.extra.AUDIO_CODEC_BANDWIDTH_KHZ";
+    /**
      * Connection event used to inform Telecom that it should play the on hold tone.  This is used
      * to play a tone when the peer puts the current call on hold.  Sent to Telecom via
      * {@link #sendConnectionEvent(String, Bundle)}.
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 724c171..fbb1701d 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -32,6 +32,7 @@
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
@@ -1589,6 +1590,30 @@
     }
 
     /**
+     * Returns whether the caller has {@link InCallService} access for companion apps.
+     *
+     * A companion app is an app associated with a physical wearable device via the
+     * {@link android.companion.CompanionDeviceManager} API.
+     *
+     * @return {@code true} if the caller has {@link InCallService} access for
+     *      companion app; {@code false} otherwise.
+     */
+    public boolean hasCompanionInCallServiceAccess() {
+        try {
+            if (isServiceConnected()) {
+                return getTelecomService().hasCompanionInCallServiceAccess(
+                        mContext.getOpPackageName());
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException calling hasCompanionInCallServiceAccess().", e);
+            if (!isSystemProcess()) {
+                e.rethrowAsRuntimeException();
+            }
+        }
+        return false;
+    }
+
+    /**
      * Returns whether there is an ongoing call originating from a managed
      * {@link ConnectionService}.  An ongoing call can be in dialing, ringing, active or holding
      * states.
@@ -2384,6 +2409,10 @@
         }
     }
 
+    private boolean isSystemProcess() {
+        return Process.myUid() == Process.SYSTEM_UID;
+    }
+
     private ITelecomService getTelecomService() {
         if (mTelecomServiceOverride != null) {
             return mTelecomServiceOverride;
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index a28a999..6dc096d 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -179,6 +179,11 @@
     boolean isInCall(String callingPackage, String callingFeatureId);
 
     /**
+     * @see TelecomServiceImpl#hasCompanionInCallServiceAccess
+     */
+    boolean hasCompanionInCallServiceAccess(String callingPackage);
+
+    /**
      * @see TelecomServiceImpl#isInManagedCall
      */
     boolean isInManagedCall(String callingPackage, String callingFeatureId);
diff --git a/telephony/common/com/android/internal/telephony/CarrierAppUtils.java b/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
index 7aecfdd..d1412b7 100644
--- a/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
+++ b/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
@@ -32,6 +32,7 @@
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.util.TelephonyUtils;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -314,7 +315,7 @@
                 String[] packageNames = new String[enabledCarrierPackages.size()];
                 enabledCarrierPackages.toArray(packageNames);
                 permissionManager.grantDefaultPermissionsToEnabledCarrierApps(packageNames,
-                        UserHandle.of(userId), Runnable::run, isSuccess -> { });
+                        UserHandle.of(userId), TelephonyUtils.DIRECT_EXECUTOR, isSuccess -> { });
             }
         } catch (PackageManager.NameNotFoundException e) {
             Log.w(TAG, "Could not reach PackageManager", e);
diff --git a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
index 7736473..02d7410 100644
--- a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
+++ b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
@@ -34,6 +34,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Supplier;
 
@@ -44,6 +45,8 @@
     public static boolean IS_USER = "user".equals(android.os.Build.TYPE);
     public static boolean IS_DEBUGGABLE = SystemProperties.getInt("ro.debuggable", 0) == 1;
 
+    public static final Executor DIRECT_EXECUTOR = Runnable::run;
+
     /**
      * Verify that caller holds {@link android.Manifest.permission#DUMP}.
      *
diff --git a/telephony/java/android/telephony/CarrierBandwidth.aidl b/telephony/java/android/telephony/CarrierBandwidth.aidl
new file mode 100644
index 0000000..d0861b8
--- /dev/null
+++ b/telephony/java/android/telephony/CarrierBandwidth.aidl
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2020 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.telephony;
+parcelable CarrierBandwidth;
\ No newline at end of file
diff --git a/telephony/java/android/telephony/CarrierBandwidth.java b/telephony/java/android/telephony/CarrierBandwidth.java
new file mode 100644
index 0000000..17747a3
--- /dev/null
+++ b/telephony/java/android/telephony/CarrierBandwidth.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2020 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.telephony;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Defines downlink and uplink capacity of a network in kbps
+ * @hide
+ */
+@SystemApi
+public final class CarrierBandwidth implements Parcelable {
+    /**
+     * Any field that is not reported shall be set to INVALID
+     */
+    public static final int INVALID = -1;
+
+    /**
+     * Estimated downlink capacity in kbps of the primary carrier.
+     * This bandwidth estimate shall be the estimated maximum sustainable link bandwidth.
+     * This will be {@link #INVALID} if the network is not connected
+     */
+    private int mPrimaryDownlinkCapacityKbps;
+
+    /**
+     * Estimated uplink capacity in kbps of the primary carrier.
+     * This bandwidth estimate shall be the estimated maximum sustainable link bandwidth.
+     * This will be {@link #INVALID} if the network is not connected
+     */
+    private int mPrimaryUplinkCapacityKbps;
+
+    /**
+     * Estimated downlink capacity in kbps of the secondary carrier in a dual connected network.
+     * This bandwidth estimate shall be the estimated maximum sustainable link bandwidth.
+     * This will be {@link #INVALID} if the network is not connected
+     */
+    private int mSecondaryDownlinkCapacityKbps;
+
+    /**
+     * Estimated uplink capacity in kbps of the secondary carrier in a dual connected network.
+     * This bandwidth estimate shall be the estimated maximum sustainable link bandwidth.
+     * This will be {@link #INVALID} if the network is not connected
+     */
+    private int mSecondaryUplinkCapacityKbps;
+
+    /** @hide **/
+    public CarrierBandwidth(Parcel in) {
+        mPrimaryDownlinkCapacityKbps = in.readInt();
+        mPrimaryUplinkCapacityKbps = in.readInt();
+        mSecondaryDownlinkCapacityKbps = in.readInt();
+        mSecondaryUplinkCapacityKbps = in.readInt();
+    }
+
+    /** @hide **/
+    public CarrierBandwidth() {
+        mPrimaryDownlinkCapacityKbps = INVALID;
+        mPrimaryUplinkCapacityKbps = INVALID;
+        mSecondaryDownlinkCapacityKbps = INVALID;
+        mSecondaryUplinkCapacityKbps = INVALID;
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param primaryDownlinkCapacityKbps Estimated downlink capacity in kbps of
+     *        the primary carrier.
+     * @param primaryUplinkCapacityKbps Estimated uplink capacity in kbps of
+     *        the primary carrier.
+     * @param secondaryDownlinkCapacityKbps Estimated downlink capacity in kbps of
+     *        the secondary carrier
+     * @param secondaryUplinkCapacityKbps Estimated uplink capacity in kbps of
+     *        the secondary carrier
+     */
+    public CarrierBandwidth(int primaryDownlinkCapacityKbps, int primaryUplinkCapacityKbps,
+            int secondaryDownlinkCapacityKbps, int secondaryUplinkCapacityKbps) {
+        mPrimaryDownlinkCapacityKbps = primaryDownlinkCapacityKbps;
+        mPrimaryUplinkCapacityKbps = primaryUplinkCapacityKbps;
+        mSecondaryDownlinkCapacityKbps = secondaryDownlinkCapacityKbps;
+        mSecondaryUplinkCapacityKbps = secondaryUplinkCapacityKbps;
+    }
+
+    /**
+     * Retrieves the upstream bandwidth for the primary network in Kbps.  This always only refers to
+     * the estimated first hop transport bandwidth.
+     * This will be INVALID if the network is not connected
+     *
+     * @return The estimated first hop upstream (device to network) bandwidth.
+     */
+    public int getPrimaryDownlinkCapacityKbps() {
+        return mPrimaryDownlinkCapacityKbps;
+    }
+
+    /**
+     * Retrieves the downstream bandwidth for the primary network in Kbps.  This always only refers
+     * to the estimated first hop transport bandwidth.
+     * This will be INVALID if the network is not connected
+     *
+     * @return The estimated first hop downstream (network to device) bandwidth.
+     */
+    public int getPrimaryUplinkCapacityKbps() {
+        return mPrimaryUplinkCapacityKbps;
+    }
+
+    /**
+     * Retrieves the upstream bandwidth for the secondary network in Kbps.  This always only refers
+     * to the estimated first hop transport bandwidth.
+     * This will be INVALID if the network is not connected
+     *
+     * @return The estimated first hop upstream (device to network) bandwidth.
+     */
+    public int getSecondaryDownlinkCapacityKbps() {
+        return mSecondaryDownlinkCapacityKbps;
+    }
+
+    /**
+     * Retrieves the downstream bandwidth for the secondary network in Kbps.  This always only
+     * refers to the estimated first hop transport bandwidth.
+     * This will be INVALID if the network is not connected
+     *
+     * @return The estimated first hop downstream (network to device) bandwidth.
+     */
+    public int getSecondaryUplinkCapacityKbps() {
+        return mSecondaryUplinkCapacityKbps;
+    }
+
+    @NonNull
+    @Override
+    public String toString() {
+        return "CarrierBandwidth: {primaryDownlinkCapacityKbps=" + mPrimaryDownlinkCapacityKbps
+                + " primaryUplinkCapacityKbps=" + mPrimaryUplinkCapacityKbps
+                + " secondaryDownlinkCapacityKbps=" + mSecondaryDownlinkCapacityKbps
+                + " secondaryUplinkCapacityKbps=" + mSecondaryUplinkCapacityKbps
+                + "}";
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                mPrimaryDownlinkCapacityKbps,
+                mPrimaryUplinkCapacityKbps,
+                mSecondaryDownlinkCapacityKbps,
+                mSecondaryUplinkCapacityKbps);
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (o == null || !(o instanceof CallQuality) || hashCode() != o.hashCode()) {
+            return false;
+        }
+        if (this == o) {
+            return true;
+        }
+        CarrierBandwidth s = (CarrierBandwidth) o;
+        return (mPrimaryDownlinkCapacityKbps == s.mPrimaryDownlinkCapacityKbps
+                && mPrimaryUplinkCapacityKbps == s.mPrimaryUplinkCapacityKbps
+                && mSecondaryDownlinkCapacityKbps == s.mSecondaryDownlinkCapacityKbps
+                && mSecondaryDownlinkCapacityKbps == s.mSecondaryDownlinkCapacityKbps);
+    }
+
+    /**
+     * {@link Parcelable#describeContents}
+     */
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * {@link Parcelable#writeToParcel}
+     * @hide
+     */
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mPrimaryDownlinkCapacityKbps);
+        dest.writeInt(mPrimaryUplinkCapacityKbps);
+        dest.writeInt(mSecondaryDownlinkCapacityKbps);
+        dest.writeInt(mSecondaryUplinkCapacityKbps);
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<CarrierBandwidth> CREATOR =
+            new Parcelable.Creator() {
+            public CarrierBandwidth createFromParcel(Parcel in) {
+                return new CarrierBandwidth(in);
+            }
+
+            public CarrierBandwidth[] newArray(int size) {
+                return new CarrierBandwidth[size];
+            }
+    };
+}
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index f8a200a..8507d85 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -20,6 +20,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telephony.AccessNetworkConstants.TransportType;
@@ -635,7 +636,8 @@
                 .append(" cellIdentity=").append(mCellIdentity)
                 .append(" voiceSpecificInfo=").append(mVoiceSpecificInfo)
                 .append(" dataSpecificInfo=").append(mDataSpecificInfo)
-                .append(" nrState=").append(nrStateToString(mNrState))
+                .append(" nrState=").append(Build.IS_DEBUGGABLE
+                        ? nrStateToString(mNrState) : "****")
                 .append(" rRplmn=").append(mRplmn)
                 .append(" isUsingCarrierAggregation=").append(mIsUsingCarrierAggregation)
                 .append("}").toString();
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 41b3ee6..dedb1af 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -1102,7 +1102,8 @@
                     .append(", isUsingCarrierAggregation=").append(isUsingCarrierAggregation())
                     .append(", mLteEarfcnRsrpBoost=").append(mLteEarfcnRsrpBoost)
                     .append(", mNetworkRegistrationInfos=").append(mNetworkRegistrationInfos)
-                    .append(", mNrFrequencyRange=").append(mNrFrequencyRange)
+                    .append(", mNrFrequencyRange=").append(Build.IS_DEBUGGABLE
+                            ? mNrFrequencyRange : FREQUENCY_RANGE_UNKNOWN)
                     .append(", mOperatorAlphaLongRaw=").append(mOperatorAlphaLongRaw)
                     .append(", mOperatorAlphaShortRaw=").append(mOperatorAlphaShortRaw)
                     .append(", mIsDataRoamingFromRegistration=")
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 88aec51..27aadd5 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -13440,6 +13440,33 @@
     }
 
     /**
+     * Get carrier bandwidth. In case of Dual connected network this will report
+     * bandwidth per primary and secondary network.
+     * @return CarrierBandwidth with bandwidth of both primary and secondary carrier.
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @NonNull
+    public CarrierBandwidth getCarrierBandwidth() {
+        try {
+            ITelephony service = getITelephony();
+            if (service != null) {
+                return service.getCarrierBandwidth(getSubId());
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            Log.e(TAG, "getCarrierBandwidth RemoteException", ex);
+            ex.rethrowFromSystemServer();
+        }
+
+        //Should not reach. Adding return statement to make compiler happy
+        return null;
+    }
+
+    /**
      * Called when userActivity is signalled in the power manager.
      * This should only be called from system Uid.
      * @hide
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 36d01f4..d16cb16 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -31,6 +31,7 @@
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telephony.CallForwardingInfo;
+import android.telephony.CarrierBandwidth;
 import android.telephony.CarrierRestrictionRules;
 import android.telephony.CellIdentity;
 import android.telephony.CellInfo;
@@ -2232,4 +2233,10 @@
      * @return true if dual connectivity is enabled else false
      */
     boolean isNrDualConnectivityEnabled(int subId);
+
+    /**
+     * Get carrier bandwidth per primary and secondary carrier
+     * @return CarrierBandwidth with bandwidth of both primary and secondary carrier.
+     */
+    CarrierBandwidth getCarrierBandwidth(int subId);
 }
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index 7abe189..cd9406c 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -35,7 +35,6 @@
 import static android.net.NetworkStats.SET_ALL;
 import static android.net.NetworkStats.SET_DEFAULT;
 import static android.net.NetworkStats.SET_FOREGROUND;
-import static android.net.NetworkStats.STATS_PER_IFACE;
 import static android.net.NetworkStats.STATS_PER_UID;
 import static android.net.NetworkStats.TAG_ALL;
 import static android.net.NetworkStats.TAG_NONE;
@@ -994,7 +993,7 @@
     public void testTethering() throws Exception {
         // pretend first mobile network comes online
         expectDefaultSettings();
-        NetworkState[] states = new NetworkState[] {buildMobile3gState(IMSI_1)};
+        final NetworkState[] states = new NetworkState[]{buildMobile3gState(IMSI_1)};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
 
@@ -1004,23 +1003,39 @@
         incrementCurrentTime(HOUR_IN_MILLIS);
         expectDefaultSettings();
 
+        // Register custom provider and retrieve callback.
+        final TestableNetworkStatsProviderBinder provider =
+                new TestableNetworkStatsProviderBinder();
+        final INetworkStatsProviderCallback cb =
+                mService.registerNetworkStatsProvider("TEST-TETHERING-OFFLOAD", provider);
+        assertNotNull(cb);
+        final long now = getElapsedRealtime();
+
         // Traffic seen by kernel counters (includes software tethering).
-        final NetworkStats ifaceStats = new NetworkStats(getElapsedRealtime(), 1)
+        final NetworkStats swIfaceStats = new NetworkStats(now, 1)
                 .insertEntry(TEST_IFACE, 1536L, 12L, 384L, 3L);
         // Hardware tethering traffic, not seen by kernel counters.
-        final NetworkStats tetherStatsHardware = new NetworkStats(getElapsedRealtime(), 1)
-                .insertEntry(TEST_IFACE, 512L, 4L, 128L, 1L);
+        final NetworkStats tetherHwIfaceStats = new NetworkStats(now, 1)
+                .insertEntry(new NetworkStats.Entry(TEST_IFACE, UID_ALL, SET_DEFAULT,
+                        TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES,
+                        512L, 4L, 128L, 1L, 0L));
+        final NetworkStats tetherHwUidStats = new NetworkStats(now, 1)
+                .insertEntry(new NetworkStats.Entry(TEST_IFACE, UID_TETHERING, SET_DEFAULT,
+                        TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES,
+                        512L, 4L, 128L, 1L, 0L));
+        cb.notifyStatsUpdated(0 /* unused */, tetherHwIfaceStats, tetherHwUidStats);
 
-        // Traffic for UID_RED.
-        final NetworkStats uidStats = new NetworkStats(getElapsedRealtime(), 1)
+        // Fake some traffic done by apps on the device (as opposed to tethering), and record it
+        // into UID stats (as opposed to iface stats).
+        final NetworkStats localUidStats = new NetworkStats(now, 1)
                 .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L);
-        // All tethering traffic, both hardware and software.
-        final NetworkStats tetherStats = new NetworkStats(getElapsedRealtime(), 1)
-                .insertEntry(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L,
+        // Software per-uid tethering traffic.
+        final NetworkStats tetherSwUidStats = new NetworkStats(now, 1)
+                .insertEntry(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1408L, 10L, 256L, 1L,
                         0L);
 
-        expectNetworkStatsSummary(ifaceStats, tetherStatsHardware);
-        expectNetworkStatsUidDetail(uidStats, tetherStats);
+        expectNetworkStatsSummary(swIfaceStats);
+        expectNetworkStatsUidDetail(localUidStats, tetherSwUidStats);
         forcePollAndWaitForIdle();
 
         // verify service recorded history
@@ -1362,12 +1377,6 @@
     }
 
     private void expectNetworkStatsSummary(NetworkStats summary) throws Exception {
-        expectNetworkStatsSummary(summary, new NetworkStats(0L, 0));
-    }
-
-    private void expectNetworkStatsSummary(NetworkStats summary, NetworkStats tetherStats)
-            throws Exception {
-        expectNetworkStatsTethering(STATS_PER_IFACE, tetherStats);
         expectNetworkStatsSummaryDev(summary.clone());
         expectNetworkStatsSummaryXt(summary.clone());
     }
@@ -1380,11 +1389,6 @@
         when(mStatsFactory.readNetworkStatsSummaryXt()).thenReturn(summary);
     }
 
-    private void expectNetworkStatsTethering(int how, NetworkStats stats)
-            throws Exception {
-        when(mNetManager.getNetworkStatsTethering(how)).thenReturn(stats);
-    }
-
     private void expectNetworkStatsUidDetail(NetworkStats detail) throws Exception {
         expectNetworkStatsUidDetail(detail, new NetworkStats(0L, 0));
     }
diff --git a/wifi/Android.bp b/wifi/Android.bp
index 1cc5073..8b89959 100644
--- a/wifi/Android.bp
+++ b/wifi/Android.bp
@@ -76,25 +76,34 @@
     "//packages/apps/Settings/tests/robotests", // TODO(b/161767237): remove
 ]
 
-// wifi-service needs pre-jarjared version of framework-wifi so it can reference copied utility
-// classes before they are renamed.
-java_library {
-    name: "framework-wifi-pre-jarjar",
+// defaults shared between `framework-wifi` & `framework-wifi-pre-jarjar`
+// java_sdk_library `framework-wifi` needs sources to generate stubs, so it cannot reuse
+// `framework-wifi-pre-jarjar`
+java_defaults {
+    name: "framework-wifi-defaults",
     defaults: ["wifi-module-sdk-version-defaults"],
-    sdk_version: "module_current",
     static_libs: [
         "framework-wifi-util-lib",
         "android.hardware.wifi-V1.0-java-constants",
+        "modules-utils-build",
     ],
     libs: [
-        "framework-annotations-lib",
         "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
     ],
     srcs: [
         ":framework-wifi-updatable-sources",
         ":framework-wifi-util-lib-aidls",
     ],
-    // java_api_finder must accompany `srcs`
+}
+
+// wifi-service needs pre-jarjared version of framework-wifi so it can reference copied utility
+// classes before they are renamed.
+java_library {
+    name: "framework-wifi-pre-jarjar",
+    defaults: ["framework-wifi-defaults"],
+    sdk_version: "module_current",
+    libs: ["framework-annotations-lib"],
+    // java_api_finder must accompany `srcs` (`srcs` defined in `framework-wifi-defaults`)
     plugins: ["java_api_finder"],
     installable: false,
     visibility: [
@@ -108,18 +117,7 @@
     name: "framework-wifi",
     defaults: [
         "framework-module-defaults",
-        "wifi-module-sdk-version-defaults",
-    ],
-    static_libs: [
-        "framework-wifi-util-lib",
-        "android.hardware.wifi-V1.0-java-constants",
-    ],
-    libs: [
-        "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
-    ],
-    srcs: [
-        ":framework-wifi-updatable-sources",
-        ":framework-wifi-util-lib-aidls",
+        "framework-wifi-defaults",
     ],
 
     jarjar_rules: ":wifi-jarjar-rules",
diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt
index b489be2..ff06a18 100644
--- a/wifi/jarjar-rules.txt
+++ b/wifi/jarjar-rules.txt
@@ -124,3 +124,4 @@
 rule com.android.internal.util.Protocol* com.android.wifi.x.@0
 
 rule com.android.net.module.util.** com.android.wifi.x.@0
+rule com.android.modules.utils.** com.android.wifi.x.@0
diff --git a/wifi/tests/Android.bp b/wifi/tests/Android.bp
index 6a39959..b710a14 100644
--- a/wifi/tests/Android.bp
+++ b/wifi/tests/Android.bp
@@ -31,10 +31,11 @@
     static_libs: [
         "androidx.test.rules",
         "core-test-rules",
+        "frameworks-base-testutils",
         "guava",
         "mockito-target-minus-junit4",
+        "modules-utils-build",
         "net-tests-utils",
-        "frameworks-base-testutils",
         "truth-prebuilt",
     ],
 
@@ -47,4 +48,8 @@
         "device-tests",
         "mts",
     ],
+
+    // static libs used by both framework-wifi & FrameworksWifiApiTests. Need to rename test usage
+    // to a different package name to prevent conflict with the copy in production code.
+    jarjar_rules: "test-jarjar-rules.txt",
 }
diff --git a/wifi/tests/test-jarjar-rules.txt b/wifi/tests/test-jarjar-rules.txt
new file mode 100644
index 0000000..41b97ab
--- /dev/null
+++ b/wifi/tests/test-jarjar-rules.txt
@@ -0,0 +1 @@
+rule com.android.modules.utils.** com.android.wifi.test.x.@0