Merge "Report more metrics in RecoverySystem"
diff --git a/Android.bp b/Android.bp
index d40f115..c9ed7ed 100644
--- a/Android.bp
+++ b/Android.bp
@@ -363,6 +363,13 @@
         ":platform-compat-native-aidl",
 
         // AIDL sources from external directories
+        ":android.hardware.security.keymint-V1-java-source",
+        ":android.hardware.security.secureclock-V1-java-source",
+        ":android.security.apc-java-source",
+        ":android.security.authorization-java-source",
+        ":android.security.maintenance-java-source",
+        ":android.security.vpnprofilestore-java-source",
+        ":android.system.keystore2-V1-java-source",
         ":credstore_aidl",
         ":dumpstate_aidl",
         ":framework_native_aidl",
@@ -523,11 +530,6 @@
         "android.hardware.vibrator-V1.1-java",
         "android.hardware.vibrator-V1.2-java",
         "android.hardware.vibrator-V1.3-java",
-        "android.security.apc-java",
-        "android.security.authorization-java",
-        "android.security.maintenance-java",
-        "android.security.vpnprofilestore-java",
-        "android.system.keystore2-V1-java",
         "android.system.suspend.control.internal-java",
         "devicepolicyprotosnano",
 
diff --git a/core/api/current.txt b/core/api/current.txt
index 2b5075d..07bebbe 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -8689,6 +8689,8 @@
     field public static final String ACTION_NAME_CHANGED = "android.bluetooth.device.action.NAME_CHANGED";
     field public static final String ACTION_PAIRING_REQUEST = "android.bluetooth.device.action.PAIRING_REQUEST";
     field public static final String ACTION_UUID = "android.bluetooth.device.action.UUID";
+    field public static final int ADDRESS_TYPE_PUBLIC = 0; // 0x0
+    field public static final int ADDRESS_TYPE_RANDOM = 1; // 0x1
     field public static final int BOND_BONDED = 12; // 0xc
     field public static final int BOND_BONDING = 11; // 0xb
     field public static final int BOND_NONE = 10; // 0xa
@@ -19852,6 +19854,7 @@
     method public android.media.AudioDeviceInfo getPreferredDevice();
     method public android.media.AudioDeviceInfo getRoutedDevice();
     method public int getSampleRate();
+    method @IntRange(from=1) public int getStartThresholdInFrames();
     method public int getState();
     method public int getStreamType();
     method public boolean getTimestamp(android.media.AudioTimestamp);
@@ -19882,6 +19885,7 @@
     method public int setPositionNotificationPeriod(int);
     method public boolean setPreferredDevice(android.media.AudioDeviceInfo);
     method public int setPresentation(@NonNull android.media.AudioPresentation);
+    method @IntRange(from=1) public int setStartThresholdInFrames(@IntRange(from=1) int);
     method @Deprecated protected void setState(int);
     method @Deprecated public int setStereoVolume(float, float);
     method public int setVolume(float);
@@ -39092,7 +39096,6 @@
     method public static boolean isConfigForIdentifiedCarrier(android.os.PersistableBundle);
     method public void notifyConfigChangedForSubId(int);
     field public static final String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
-    field public static final int CARRIER_NR_AVAILABILITY_NONE = 0; // 0x0
     field public static final int CARRIER_NR_AVAILABILITY_NSA = 1; // 0x1
     field public static final int CARRIER_NR_AVAILABILITY_SA = 2; // 0x2
     field public static final int DATA_CYCLE_THRESHOLD_DISABLED = -2; // 0xfffffffe
@@ -39153,7 +39156,7 @@
     field public static final String KEY_CARRIER_INSTANT_LETTERING_LENGTH_LIMIT_INT = "carrier_instant_lettering_length_limit_int";
     field public static final String KEY_CARRIER_NAME_OVERRIDE_BOOL = "carrier_name_override_bool";
     field public static final String KEY_CARRIER_NAME_STRING = "carrier_name_string";
-    field public static final String KEY_CARRIER_NR_AVAILABILITY_INT = "carrier_nr_availability_int";
+    field public static final String KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY = "carrier_nr_availabilities_int_array";
     field public static final String KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL = "carrier_rcs_provisioning_required_bool";
     field public static final String KEY_CARRIER_SETTINGS_ACTIVITY_COMPONENT_NAME_STRING = "carrier_settings_activity_component_name_string";
     field public static final String KEY_CARRIER_SETTINGS_ENABLE_BOOL = "carrier_settings_enable_bool";
@@ -39222,6 +39225,7 @@
     field public static final String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array";
     field public static final String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool";
     field public static final String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool";
+    field public static final String KEY_HIDE_ENABLE_2G = "hide_enable_2g_bool";
     field public static final String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool";
     field public static final String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
     field public static final String KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL = "hide_lte_plus_data_icon_bool";
@@ -41021,6 +41025,7 @@
     method @Deprecated public String iccTransmitApduBasicChannel(int, int, int, int, int, String);
     method @Deprecated public String iccTransmitApduLogicalChannel(int, int, int, int, int, int, String);
     method public boolean isConcurrentVoiceAndDataSupported();
+    method public boolean isDataCapable();
     method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.READ_PHONE_STATE, "android.permission.READ_PRIVILEGED_PHONE_STATE"}) public boolean isDataConnectionAllowed();
     method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isDataEnabled();
     method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isDataEnabledForReason(int);
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index bd4c301..f155a5f 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -46,6 +46,29 @@
     method public int getResourceId();
   }
 
+  public class NetworkPolicyManager {
+    method @NonNull public static String blockedReasonsToString(int);
+    method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public int getMultipathPreference(@NonNull android.net.Network);
+    method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public int getRestrictBackgroundStatus(int);
+    method public static boolean isUidBlocked(int, boolean);
+    method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public boolean isUidNetworkingBlocked(int, boolean);
+    method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public boolean isUidRestrictedOnMeteredNetworks(int);
+    method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public void registerNetworkPolicyCallback(@Nullable java.util.concurrent.Executor, @NonNull android.net.NetworkPolicyManager.NetworkPolicyCallback);
+    method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public void unregisterNetworkPolicyCallback(@NonNull android.net.NetworkPolicyManager.NetworkPolicyCallback);
+    field public static final int BLOCKED_METERED_REASON_ADMIN_DISABLED = 262144; // 0x40000
+    field public static final int BLOCKED_METERED_REASON_DATA_SAVER = 65536; // 0x10000
+    field public static final int BLOCKED_METERED_REASON_USER_RESTRICTED = 131072; // 0x20000
+    field public static final int BLOCKED_REASON_APP_STANDBY = 4; // 0x4
+    field public static final int BLOCKED_REASON_BATTERY_SAVER = 1; // 0x1
+    field public static final int BLOCKED_REASON_DOZE = 2; // 0x2
+    field public static final int BLOCKED_REASON_NONE = 0; // 0x0
+    field public static final int BLOCKED_REASON_RESTRICTED_MODE = 8; // 0x8
+  }
+
+  public static interface NetworkPolicyManager.NetworkPolicyCallback {
+    method public default void onUidBlockedReasonChanged(int, int);
+  }
+
   public final class NetworkStateSnapshot implements android.os.Parcelable {
     ctor public NetworkStateSnapshot(@NonNull android.net.Network, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, @Nullable String, int);
     method public int describeContents();
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index ad86788..92c18c6 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -113,6 +113,7 @@
     field public static final String LOOP_RADIO = "android.permission.LOOP_RADIO";
     field public static final String MANAGE_ACCESSIBILITY = "android.permission.MANAGE_ACCESSIBILITY";
     field public static final String MANAGE_ACTIVITY_STACKS = "android.permission.MANAGE_ACTIVITY_STACKS";
+    field public static final String MANAGE_APP_HIBERNATION = "android.permission.MANAGE_APP_HIBERNATION";
     field public static final String MANAGE_APP_OPS_RESTRICTIONS = "android.permission.MANAGE_APP_OPS_RESTRICTIONS";
     field public static final String MANAGE_APP_PREDICTIONS = "android.permission.MANAGE_APP_PREDICTIONS";
     field public static final String MANAGE_APP_TOKENS = "android.permission.MANAGE_APP_TOKENS";
@@ -1421,10 +1422,11 @@
 package android.apphibernation {
 
   public final class AppHibernationManager {
-    method public boolean isHibernatingForUser(@NonNull String);
-    method public boolean isHibernatingGlobally(@NonNull String);
-    method public void setHibernatingForUser(@NonNull String, boolean);
-    method public void setHibernatingGlobally(@NonNull String, boolean);
+    method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_APP_HIBERNATION) public java.util.List<java.lang.String> getHibernatingPackagesForUser();
+    method @RequiresPermission(android.Manifest.permission.MANAGE_APP_HIBERNATION) public boolean isHibernatingForUser(@NonNull String);
+    method @RequiresPermission(android.Manifest.permission.MANAGE_APP_HIBERNATION) public boolean isHibernatingGlobally(@NonNull String);
+    method @RequiresPermission(android.Manifest.permission.MANAGE_APP_HIBERNATION) public void setHibernatingForUser(@NonNull String, boolean);
+    method @RequiresPermission(android.Manifest.permission.MANAGE_APP_HIBERNATION) public void setHibernatingGlobally(@NonNull String, boolean);
   }
 
 }
@@ -1480,6 +1482,7 @@
 
   public final class BluetoothDevice implements android.os.Parcelable {
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean cancelBondProcess();
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean createBondOutOfBand(int, @Nullable android.bluetooth.OobData, @Nullable android.bluetooth.OobData);
     method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public byte[] getMetadata(int);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getSimAccessPermission();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isConnected();
@@ -1656,6 +1659,55 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BufferConstraints> CREATOR;
   }
 
+  public final class OobData implements android.os.Parcelable {
+    method @NonNull public static android.bluetooth.OobData.ClassicBuilder createClassicBuilder(@NonNull byte[], @NonNull byte[], @NonNull byte[]);
+    method @NonNull public static android.bluetooth.OobData.LeBuilder createLeBuilder(@NonNull byte[], @NonNull byte[], int);
+    method @NonNull public byte[] getClassOfDevice();
+    method @NonNull public byte[] getClassicLength();
+    method @NonNull public byte[] getConfirmationHash();
+    method @NonNull public byte[] getDeviceAddressWithType();
+    method @Nullable public byte[] getDeviceName();
+    method @Nullable public byte[] getLeAppearance();
+    method @NonNull public int getLeDeviceRole();
+    method @NonNull public int getLeFlags();
+    method @Nullable public byte[] getLeTemporaryKey();
+    method @NonNull public byte[] getRandomizerHash();
+    field public static final int CLASS_OF_DEVICE_OCTETS = 3; // 0x3
+    field public static final int CONFIRMATION_OCTETS = 16; // 0x10
+    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.OobData> CREATOR;
+    field public static final int DEVICE_ADDRESS_OCTETS = 7; // 0x7
+    field public static final int LE_APPEARANCE_OCTETS = 2; // 0x2
+    field public static final int LE_DEVICE_FLAG_OCTETS = 1; // 0x1
+    field public static final int LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL = 3; // 0x3
+    field public static final int LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL = 2; // 0x2
+    field public static final int LE_DEVICE_ROLE_CENTRAL_ONLY = 1; // 0x1
+    field public static final int LE_DEVICE_ROLE_OCTETS = 1; // 0x1
+    field public static final int LE_DEVICE_ROLE_PERIPHERAL_ONLY = 0; // 0x0
+    field public static final int LE_FLAG_BREDR_NOT_SUPPORTED = 2; // 0x2
+    field public static final int LE_FLAG_GENERAL_DISCOVERY_MODE = 1; // 0x1
+    field public static final int LE_FLAG_LIMITED_DISCOVERY_MODE = 0; // 0x0
+    field public static final int LE_FLAG_SIMULTANEOUS_CONTROLLER = 3; // 0x3
+    field public static final int LE_FLAG_SIMULTANEOUS_HOST = 4; // 0x4
+    field public static final int LE_TK_OCTETS = 16; // 0x10
+    field public static final int OOB_LENGTH_OCTETS = 2; // 0x2
+    field public static final int RANDOMIZER_OCTETS = 16; // 0x10
+  }
+
+  public static final class OobData.ClassicBuilder {
+    method @NonNull public android.bluetooth.OobData build();
+    method @NonNull public android.bluetooth.OobData.ClassicBuilder setClassOfDevice(@NonNull byte[]);
+    method @NonNull public android.bluetooth.OobData.ClassicBuilder setDeviceName(@NonNull byte[]);
+    method @NonNull public android.bluetooth.OobData.ClassicBuilder setRandomizerHash(@NonNull byte[]);
+  }
+
+  public static final class OobData.LeBuilder {
+    method @NonNull public android.bluetooth.OobData build();
+    method @NonNull public android.bluetooth.OobData.LeBuilder setDeviceName(@NonNull byte[]);
+    method @NonNull public android.bluetooth.OobData.LeBuilder setLeFlags(int);
+    method @NonNull public android.bluetooth.OobData.LeBuilder setLeTemporaryKey(@NonNull byte[]);
+    method @NonNull public android.bluetooth.OobData.LeBuilder setRandomizerHash(@NonNull byte[]);
+  }
+
 }
 
 package android.bluetooth.le {
@@ -1676,7 +1728,19 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.ResultStorageDescriptor> CREATOR;
   }
 
+  public final class ScanFilter implements android.os.Parcelable {
+    method public int getAddressType();
+    method @Nullable public byte[] getIrk();
+  }
+
+  public static final class ScanFilter.Builder {
+    method @NonNull public android.bluetooth.le.ScanFilter.Builder setDeviceAddress(@NonNull String, int);
+    method @NonNull public android.bluetooth.le.ScanFilter.Builder setDeviceAddress(@NonNull String, int, @NonNull byte[]);
+    field public static final int LEN_IRK_OCTETS = 16; // 0x10
+  }
+
   public final class ScanSettings implements android.os.Parcelable {
+    field public static final int SCAN_MODE_AMBIENT_DISCOVERY = 3; // 0x3
     field public static final int SCAN_RESULT_TYPE_ABBREVIATED = 1; // 0x1
     field public static final int SCAN_RESULT_TYPE_FULL = 0; // 0x0
   }
@@ -9475,7 +9539,8 @@
 
   public final class DataSpecificRegistrationInfo implements android.os.Parcelable {
     method public int describeContents();
-    method @NonNull public android.telephony.LteVopsSupportInfo getLteVopsSupportInfo();
+    method @Deprecated @NonNull public android.telephony.LteVopsSupportInfo getLteVopsSupportInfo();
+    method @Nullable public android.telephony.VopsSupportInfo getVopsSupportInfo();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationInfo> CREATOR;
   }
@@ -9520,14 +9585,16 @@
     field public static final int LCE_TYPE_SECONDARY = 1; // 0x1
   }
 
-  public final class LteVopsSupportInfo implements android.os.Parcelable {
+  public final class LteVopsSupportInfo extends android.telephony.VopsSupportInfo {
     ctor public LteVopsSupportInfo(int, int);
-    method public int describeContents();
     method public int getEmcBearerSupport();
     method public int getVopsSupport();
-    method public void writeToParcel(android.os.Parcel, int);
+    method public boolean isEmergencyServiceFallbackSupported();
+    method public boolean isEmergencyServiceSupported();
+    method public boolean isVopsSupported();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.LteVopsSupportInfo> CREATOR;
-    field public static final int LTE_STATUS_NOT_AVAILABLE = 1; // 0x1
+    field @Deprecated public static final int LTE_STATUS_NOT_AVAILABLE = 1; // 0x1
     field public static final int LTE_STATUS_NOT_SUPPORTED = 3; // 0x3
     field public static final int LTE_STATUS_SUPPORTED = 2; // 0x2
   }
@@ -9598,6 +9665,29 @@
     field public static final int RESULT_SUCCESS = 0; // 0x0
   }
 
+  public final class NrVopsSupportInfo extends android.telephony.VopsSupportInfo {
+    ctor public NrVopsSupportInfo(int, int, int);
+    method public int getEmcSupport();
+    method public int getEmfSupport();
+    method public int getVopsSupport();
+    method public boolean isEmergencyServiceFallbackSupported();
+    method public boolean isEmergencyServiceSupported();
+    method public boolean isVopsSupported();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.NrVopsSupportInfo> CREATOR;
+    field public static final int NR_STATUS_EMC_5GCN_ONLY = 1; // 0x1
+    field public static final int NR_STATUS_EMC_EUTRA_5GCN_ONLY = 2; // 0x2
+    field public static final int NR_STATUS_EMC_NOT_SUPPORTED = 0; // 0x0
+    field public static final int NR_STATUS_EMC_NR_EUTRA_5GCN = 3; // 0x3
+    field public static final int NR_STATUS_EMF_5GCN_ONLY = 1; // 0x1
+    field public static final int NR_STATUS_EMF_EUTRA_5GCN_ONLY = 2; // 0x2
+    field public static final int NR_STATUS_EMF_NOT_SUPPORTED = 0; // 0x0
+    field public static final int NR_STATUS_EMF_NR_EUTRA_5GCN = 3; // 0x3
+    field public static final int NR_STATUS_VOPS_3GPP_SUPPORTED = 1; // 0x1
+    field public static final int NR_STATUS_VOPS_NON_3GPP_SUPPORTED = 2; // 0x2
+    field public static final int NR_STATUS_VOPS_NOT_SUPPORTED = 0; // 0x0
+  }
+
   public interface NumberVerificationCallback {
     method public default void onCallReceived(@NonNull String);
     method public default void onVerificationFailed(int);
@@ -10017,7 +10107,7 @@
   }
 
   public static interface TelephonyCallback.AllowedNetworkTypesListener {
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void onAllowedNetworkTypesChanged(@NonNull java.util.Map<java.lang.Integer,java.lang.Long>);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void onAllowedNetworkTypesChanged(int, long);
   }
 
   public static interface TelephonyCallback.CallAttributesListener {
@@ -10234,6 +10324,7 @@
     field public static final String ACTION_SIM_CARD_STATE_CHANGED = "android.telephony.action.SIM_CARD_STATE_CHANGED";
     field public static final String ACTION_SIM_SLOT_STATUS_CHANGED = "android.telephony.action.SIM_SLOT_STATUS_CHANGED";
     field public static final int ALLOWED_NETWORK_TYPES_REASON_CARRIER = 2; // 0x2
+    field public static final int ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G = 3; // 0x3
     field public static final int ALLOWED_NETWORK_TYPES_REASON_POWER = 1; // 0x1
     field public static final int ALLOWED_NETWORK_TYPES_REASON_USER = 0; // 0x0
     field public static final int CALL_WAITING_STATUS_DISABLED = 2; // 0x2
@@ -10243,6 +10334,7 @@
     field public static final String CAPABILITY_ALLOWED_NETWORK_TYPES_USED = "CAPABILITY_ALLOWED_NETWORK_TYPES_USED";
     field public static final String CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE = "CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE";
     field public static final String CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE = "CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE";
+    field public static final String CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING = "CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING";
     field public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; // 0xfffffffe
     field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1
     field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0
@@ -10396,6 +10488,16 @@
     method public static final void setSmsFilterSettings(android.content.Context, android.telecom.PhoneAccountHandle, android.telephony.VisualVoicemailSmsFilterSettings);
   }
 
+  public abstract class VopsSupportInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public abstract boolean equals(Object);
+    method public abstract int hashCode();
+    method public abstract boolean isEmergencyServiceFallbackSupported();
+    method public abstract boolean isEmergencyServiceSupported();
+    method public abstract boolean isVopsSupported();
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.VopsSupportInfo> CREATOR;
+  }
+
 }
 
 package android.telephony.cdma {
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index a0ff97e..11df058 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -996,6 +996,8 @@
 
   public class NetworkPolicyManager {
     method public boolean getRestrictBackground();
+    method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public boolean isUidNetworkingBlocked(int, boolean);
+    method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public boolean isUidRestrictedOnMeteredNetworks(int);
     method @NonNull public static String resolveNetworkId(@NonNull android.net.wifi.WifiConfiguration);
     method public void setRestrictBackground(boolean);
   }
diff --git a/core/java/android/apphibernation/AppHibernationManager.java b/core/java/android/apphibernation/AppHibernationManager.java
index 7281d50..de77848 100644
--- a/core/java/android/apphibernation/AppHibernationManager.java
+++ b/core/java/android/apphibernation/AppHibernationManager.java
@@ -17,12 +17,15 @@
 package android.apphibernation;
 
 import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.content.Context;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 
+import java.util.List;
+
 /**
  * This class provides an API surface for system apps to manipulate the app hibernation
  * state of a package for the user provided in the context.
@@ -54,6 +57,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(value = android.Manifest.permission.MANAGE_APP_HIBERNATION)
     public boolean isHibernatingForUser(@NonNull String packageName) {
         try {
             return mIAppHibernationService.isHibernatingForUser(packageName, mContext.getUserId());
@@ -68,6 +72,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(value = android.Manifest.permission.MANAGE_APP_HIBERNATION)
     public void setHibernatingForUser(@NonNull String packageName, boolean isHibernating) {
         try {
             mIAppHibernationService.setHibernatingForUser(packageName, mContext.getUserId(),
@@ -83,6 +88,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(value = android.Manifest.permission.MANAGE_APP_HIBERNATION)
     public boolean isHibernatingGlobally(@NonNull String packageName) {
         try {
             return mIAppHibernationService.isHibernatingGlobally(packageName);
@@ -99,6 +105,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(value = android.Manifest.permission.MANAGE_APP_HIBERNATION)
     public void setHibernatingGlobally(@NonNull String packageName, boolean isHibernating) {
         try {
             mIAppHibernationService.setHibernatingGlobally(packageName, isHibernating);
@@ -106,4 +113,20 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    /**
+     * Get the hibernating packages for the user. This is equivalent to the list of packages for
+     * the user that return true for {@link #isHibernatingForUser}.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(value = android.Manifest.permission.MANAGE_APP_HIBERNATION)
+    public @NonNull List<String> getHibernatingPackagesForUser() {
+        try {
+            return mIAppHibernationService.getHibernatingPackagesForUser(mContext.getUserId());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/core/java/android/apphibernation/IAppHibernationService.aidl b/core/java/android/apphibernation/IAppHibernationService.aidl
index 6a068ee..afdb3fe 100644
--- a/core/java/android/apphibernation/IAppHibernationService.aidl
+++ b/core/java/android/apphibernation/IAppHibernationService.aidl
@@ -25,4 +25,5 @@
     void setHibernatingForUser(String packageName, int userId, boolean isHibernating);
     boolean isHibernatingGlobally(String packageName);
     void setHibernatingGlobally(String packageName, boolean isHibernating);
+    List<String> getHibernatingPackagesForUser(int userId);
 }
\ No newline at end of file
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index cc0b22a..38863c2 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -52,6 +52,8 @@
 import android.util.Log;
 import android.util.Pair;
 
+import com.android.internal.util.Preconditions;
+
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -3118,6 +3120,25 @@
         return true;
     }
 
+    /**
+     * Determines whether a String Bluetooth address, such as "00:43:A8:23:10:F0"
+     * is a RANDOM STATIC address.
+     *
+     * RANDOM STATIC: (addr & 0b11) == 0b11
+     * RANDOM RESOLVABLE: (addr & 0b11) == 0b10
+     * RANDOM non-RESOLVABLE: (addr & 0b11) == 0b00
+     *
+     * @param address Bluetooth address as string
+     * @return true if the 2 Least Significant Bits of the address equals 0b11.
+     *
+     * @hide
+     */
+    public static boolean isAddressRandomStatic(@NonNull String address) {
+        Preconditions.checkNotNull(address);
+        return checkBluetoothAddress(address)
+                && (Integer.parseInt(address.split(":")[5], 16) & 0b11) == 0b11;
+    }
+
     @UnsupportedAppUsage
     /*package*/ IBluetoothManager getBluetoothManager() {
         return mManagerService;
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 89030bc..c30b8af 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -1002,6 +1002,24 @@
     public static final String EXTRA_MAS_INSTANCE =
             "android.bluetooth.device.extra.MAS_INSTANCE";
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+        prefix = { "ADDRESS_TYPE_" },
+        value = {
+            /** Hardware MAC Address */
+            ADDRESS_TYPE_PUBLIC,
+            /** Address is either resolvable, non-resolvable or static.*/
+            ADDRESS_TYPE_RANDOM,
+        }
+    )
+    public @interface AddressType {}
+
+    /** Hardware MAC Address of the device */
+    public static final int ADDRESS_TYPE_PUBLIC = 0;
+    /** Address is either resolvable, non-resolvable or static. */
+    public static final int ADDRESS_TYPE_RANDOM = 1;
+
     /**
      * Lazy initialization. Guaranteed final after first object constructed, or
      * getService() called.
@@ -1010,6 +1028,7 @@
     private static volatile IBluetooth sService;
 
     private final String mAddress;
+    @AddressType private final int mAddressType;
 
     /*package*/
     @UnsupportedAppUsage
@@ -1064,6 +1083,7 @@
         }
 
         mAddress = address;
+        mAddressType = ADDRESS_TYPE_PUBLIC;
     }
 
     @Override
@@ -1279,7 +1299,6 @@
      * the bonding process completes, and its result.
      * <p>Android system services will handle the necessary user interactions
      * to confirm and complete the bonding process.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
      *
      * @param transport The transport to use for the pairing procedure.
      * @return false on immediate error, true if bonding will begin
@@ -1287,8 +1306,9 @@
      * @hide
      */
     @UnsupportedAppUsage
+    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
     public boolean createBond(int transport) {
-        return createBondOutOfBand(transport, null);
+        return createBondInternal(transport, null, null);
     }
 
     /**
@@ -1302,21 +1322,38 @@
      * <p>Android system services will handle the necessary user interactions
      * to confirm and complete the bonding process.
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
+     * <p>There are two possible versions of OOB Data.  This data can come in as
+     * P192 or P256.  This is a reference to the cryptography used to generate the key.
+     * The caller may pass one or both.  If both types of data are passed, then the
+     * P256 data will be preferred, and thus used.
      *
      * @param transport - Transport to use
-     * @param oobData - Out Of Band data
+     * @param remoteP192Data - Out Of Band data (P192) or null
+     * @param remoteP256Data - Out Of Band data (P256) or null
      * @return false on immediate error, true if bonding will begin
      * @hide
      */
-    public boolean createBondOutOfBand(int transport, OobData oobData) {
+    @SystemApi
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+    public boolean createBondOutOfBand(int transport, @Nullable OobData remoteP192Data,
+            @Nullable OobData remoteP256Data) {
+        if (remoteP192Data == null && remoteP256Data == null) {
+            throw new IllegalArgumentException(
+                "One or both arguments for the OOB data types are required to not be null."
+                + "  Please use createBond() instead if you do not have OOB data to pass.");
+        }
+        return createBondInternal(transport, remoteP192Data, remoteP256Data);
+    }
+
+    private boolean createBondInternal(int transport, @Nullable OobData remoteP192Data,
+            @Nullable OobData remoteP256Data) {
         final IBluetooth service = sService;
         if (service == null) {
             Log.w(TAG, "BT not enabled, createBondOutOfBand failed");
             return false;
         }
         try {
-            return service.createBond(this, transport, oobData);
+            return service.createBond(this, transport, remoteP192Data, remoteP256Data);
         } catch (RemoteException e) {
             Log.e(TAG, "", e);
         }
@@ -1347,27 +1384,6 @@
     }
 
     /**
-     * Set the Out Of Band data for a remote device to be used later
-     * in the pairing mechanism. Users can obtain this data through other
-     * trusted channels
-     *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
-     *
-     * @param hash Simple Secure pairing hash
-     * @param randomizer The random key obtained using OOB
-     * @return false on error; true otherwise
-     * @hide
-     */
-    public boolean setDeviceOutOfBandData(byte[] hash, byte[] randomizer) {
-        //TODO(BT)
-      /*
-      try {
-        return sService.setDeviceOutOfBandData(this, hash, randomizer);
-      } catch (RemoteException e) {Log.e(TAG, "", e);} */
-        return false;
-    }
-
-    /**
      * Cancel an in-progress bonding request started with {@link #createBond}.
      *
      * @return true on success, false on error
diff --git a/core/java/android/bluetooth/OobData.java b/core/java/android/bluetooth/OobData.java
index 0d0c6ab..08d694e 100644
--- a/core/java/android/bluetooth/OobData.java
+++ b/core/java/android/bluetooth/OobData.java
@@ -1,4 +1,4 @@
-/*
+/**
  * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,88 +16,949 @@
 
 package android.bluetooth;
 
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.internal.util.Preconditions;
+
+import java.lang.IllegalArgumentException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Out Of Band Data for Bluetooth device pairing.
  *
  * <p>This object represents optional data obtained from a remote device through
- * an out-of-band channel (eg. NFC).
+ * an out-of-band channel (eg. NFC, QR).
+ *
+ * <p>References:
+ * NFC AD Forum SSP 1.1 (AD)
+ * {@link https://members.nfc-forum.org//apps/group_public/download.php/24620/NFCForum-AD-BTSSP_1_1.pdf}
+ * Core Specification Supplement (CSS) V9
+ *
+ * <p>There are several BR/EDR Examples
+ *
+ * <p>Negotiated Handover:
+ *   Bluetooth Carrier Configuration Record:
+ *    - OOB Data Length
+ *    - Device Address
+ *    - Class of Device
+ *    - Simple Pairing Hash C
+ *    - Simple Pairing Randomizer R
+ *    - Service Class UUID
+ *    - Bluetooth Local Name
+ *
+ * <p>Static Handover:
+ *   Bluetooth Carrier Configuration Record:
+ *    - OOB Data Length
+ *    - Device Address
+ *    - Class of Device
+ *    - Service Class UUID
+ *    - Bluetooth Local Name
+ *
+ * <p>Simplified Tag Format for Single BT Carrier:
+ *   Bluetooth OOB Data Record:
+ *    - OOB Data Length
+ *    - Device Address
+ *    - Class of Device
+ *    - Service Class UUID
+ *    - Bluetooth Local Name
  *
  * @hide
  */
-public class OobData implements Parcelable {
-    private byte[] mLeBluetoothDeviceAddress;
-    private byte[] mSecurityManagerTk;
-    private byte[] mLeSecureConnectionsConfirmation;
-    private byte[] mLeSecureConnectionsRandom;
+@SystemApi
+public final class OobData implements Parcelable {
 
-    public byte[] getLeBluetoothDeviceAddress() {
-        return mLeBluetoothDeviceAddress;
+    private static final String TAG = "OobData";
+    /** The {@link OobData#mClassicLength} may be. (AD 3.1.1) (CSS 1.6.2) @hide */
+    @SystemApi
+    public static final int OOB_LENGTH_OCTETS = 2;
+    /**
+     * The length for the {@link OobData#mDeviceAddressWithType}(6) and Address Type(1).
+     * (AD 3.1.2) (CSS 1.6.2)
+     * @hide
+     */
+    @SystemApi
+    public static final int DEVICE_ADDRESS_OCTETS = 7;
+    /** The Class of Device is 3 octets. (AD 3.1.3) (CSS 1.6.2) @hide */
+    @SystemApi
+    public static final int CLASS_OF_DEVICE_OCTETS = 3;
+    /** The Confirmation data must be 16 octets. (AD 3.2.2) (CSS 1.6.2) @hide */
+    @SystemApi
+    public static final int CONFIRMATION_OCTETS = 16;
+    /** The Randomizer data must be 16 octets. (AD 3.2.3) (CSS 1.6.2) @hide */
+    @SystemApi
+    public static final int RANDOMIZER_OCTETS = 16;
+    /** The LE Device Role length is 1 octet. (AD 3.3.2) (CSS 1.17) @hide */
+    @SystemApi
+    public static final int LE_DEVICE_ROLE_OCTETS = 1;
+    /** The {@link OobData#mLeTemporaryKey} length. (3.4.1) @hide */
+    @SystemApi
+    public static final int LE_TK_OCTETS = 16;
+    /** The {@link OobData#mLeAppearance} length. (3.4.1) @hide */
+    @SystemApi
+    public static final int LE_APPEARANCE_OCTETS = 2;
+    /** The {@link OobData#mLeFlags} length. (3.4.1) @hide */
+    @SystemApi
+    public static final int LE_DEVICE_FLAG_OCTETS = 1; // 1 octet to hold the 0-4 value.
+
+    // Le Roles
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+        prefix = { "LE_DEVICE_ROLE_" },
+        value = {
+            LE_DEVICE_ROLE_PERIPHERAL_ONLY,
+            LE_DEVICE_ROLE_CENTRAL_ONLY,
+            LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL,
+            LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL
+        }
+    )
+    public @interface LeRole {}
+
+    /** @hide */
+    @SystemApi
+    public static final int LE_DEVICE_ROLE_PERIPHERAL_ONLY = 0x00;
+    /** @hide */
+    @SystemApi
+    public static final int LE_DEVICE_ROLE_CENTRAL_ONLY = 0x01;
+    /** @hide */
+    @SystemApi
+    public static final int LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL = 0x02;
+    /** @hide */
+    @SystemApi
+    public static final int LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL = 0x03;
+
+    // Le Flags
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+        prefix = { "LE_FLAG_" },
+        value = {
+            LE_FLAG_LIMITED_DISCOVERY_MODE,
+            LE_FLAG_GENERAL_DISCOVERY_MODE,
+            LE_FLAG_BREDR_NOT_SUPPORTED,
+            LE_FLAG_SIMULTANEOUS_CONTROLLER,
+            LE_FLAG_SIMULTANEOUS_HOST
+        }
+    )
+    public @interface LeFlag {}
+
+    /** @hide */
+    @SystemApi
+    public static final int LE_FLAG_LIMITED_DISCOVERY_MODE = 0x00;
+    /** @hide */
+    @SystemApi
+    public static final int LE_FLAG_GENERAL_DISCOVERY_MODE = 0x01;
+    /** @hide */
+    @SystemApi
+    public static final int LE_FLAG_BREDR_NOT_SUPPORTED = 0x02;
+    /** @hide */
+    @SystemApi
+    public static final int LE_FLAG_SIMULTANEOUS_CONTROLLER = 0x03;
+    /** @hide */
+    @SystemApi
+    public static final int LE_FLAG_SIMULTANEOUS_HOST = 0x04;
+
+    /**
+     * Main creation method for creating a Classic version of {@link OobData}.
+     *
+     * <p>This object will allow the caller to call {@link ClassicBuilder#build()}
+     * to build the data object or add any option information to the builder.
+     *
+     * @param confirmationHash byte array consisting of {@link OobData#CONFIRMATION_OCTETS} octets
+     * of data. Data is derived from controller/host stack and is required for pairing OOB.
+     * @param classicLength byte array representing the length of data from 8-65535 across 2
+     * octets (0xXXXX).
+     * @param deviceAddressWithType byte array representing the Bluetooth Address of the device
+     * that owns the OOB data. (i.e. the originator) [6 octets]
+     *
+     * @return a Classic Builder instance with all the given data set or null.
+     *
+     * @throws IllegalArgumentException if any of the values fail to be set.
+     * @throws NullPointerException if any argument is null.
+     *
+     * @hide
+     */
+    @NonNull
+    @SystemApi
+    public static ClassicBuilder createClassicBuilder(@NonNull byte[] confirmationHash,
+            @NonNull byte[] classicLength, @NonNull byte[] deviceAddressWithType) {
+        return new ClassicBuilder(confirmationHash, classicLength, deviceAddressWithType);
     }
 
     /**
-     * Sets the LE Bluetooth Device Address value to be used during LE pairing.
-     * The value shall be 7 bytes. Please see Bluetooth CSSv6, Part A 1.16 for
-     * a detailed description.
+     * Main creation method for creating a LE version of {@link OobData}.
+     *
+     * <p>This object will allow the caller to call {@link LeBuilder#build()}
+     * to build the data object or add any option information to the builder.
+     *
+     * @param deviceAddressWithType the LE device address plus the address type (7 octets);
+     * not null.
+     * @param leDeviceRole whether the device supports Peripheral, Central,
+     * Both including preference; not null. (1 octet)
+     * @param confirmationHash Array consisting of {@link OobData#CONFIRMATION_OCTETS} octets
+     * of data. Data is derived from controller/host stack and is
+     * required for pairing OOB.
+     *
+     * <p>Possible LE Device Role Values:
+     * 0x00 Only Peripheral supported
+     * 0x01 Only Central supported
+     * 0x02 Central & Peripheral supported; Peripheral Preferred
+     * 0x03 Only peripheral supported; Central Preferred
+     * 0x04 - 0xFF Reserved
+     *
+     * @return a LeBuilder instance with all the given data set or null.
+     *
+     * @throws IllegalArgumentException if any of the values fail to be set.
+     * @throws NullPointerException if any argument is null.
+     *
+     * @hide
      */
-    public void setLeBluetoothDeviceAddress(byte[] leBluetoothDeviceAddress) {
-        mLeBluetoothDeviceAddress = leBluetoothDeviceAddress;
-    }
-
-    public byte[] getSecurityManagerTk() {
-        return mSecurityManagerTk;
+    @NonNull
+    @SystemApi
+    public static LeBuilder createLeBuilder(@NonNull byte[] confirmationHash,
+            @NonNull byte[] deviceAddressWithType, @LeRole int leDeviceRole) {
+        return new LeBuilder(confirmationHash, deviceAddressWithType, leDeviceRole);
     }
 
     /**
-     * Sets the Temporary Key value to be used by the LE Security Manager during
-     * LE pairing. The value shall be 16 bytes. Please see Bluetooth CSSv6,
-     * Part A 1.8 for a detailed description.
+     * Builds an {@link OobData} object and validates that the required combination
+     * of values are present to create the LE specific OobData type.
+     *
+     * @hide
      */
-    public void setSecurityManagerTk(byte[] securityManagerTk) {
-        mSecurityManagerTk = securityManagerTk;
+    @SystemApi
+    public static final class LeBuilder {
+
+        /**
+         * It is recommended that this Hash C is generated anew for each
+         * pairing.
+         *
+         * <p>It should be noted that on passive NFC this isn't possible as the data is static
+         * and immutable.
+         */
+        private byte[] mConfirmationHash = null;
+
+        /**
+         * Optional, but adds more validity to the pairing.
+         *
+         * <p>If not present a value of 0 is assumed.
+         */
+        private byte[] mRandomizerHash = new byte[] {
+            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+        };
+
+        /**
+         * The Bluetooth Device user-friendly name presented over Bluetooth Technology.
+         *
+         * <p>This is the name that may be displayed to the device user as part of the UI.
+         */
+        private byte[] mDeviceName = null;
+
+        /**
+         * Sets the Bluetooth Device name to be used for UI purposes.
+         *
+         * <p>Optional attribute.
+         *
+         * @param deviceName byte array representing the name, may be 0 in length, not null.
+         *
+         * @return {@link OobData#ClassicBuilder}
+         *
+         * @throws NullPointerException if deviceName is null.
+         *
+         * @hide
+         */
+        @NonNull
+        @SystemApi
+        public LeBuilder setDeviceName(@NonNull byte[] deviceName) {
+            Preconditions.checkNotNull(deviceName);
+            this.mDeviceName = deviceName;
+            return this;
+        }
+
+        /**
+         * The Bluetooth Device Address is the address to which the OOB data belongs.
+         *
+         * <p>The length MUST be {@link OobData#DEVICE_ADDRESS_OCTETS} octets.
+         *
+         * <p> Address is encoded in Little Endian order.
+         *
+         * <p>e.g. 00:01:02:03:04:05 would be x05x04x03x02x01x00
+         */
+        private final byte[] mDeviceAddressWithType;
+
+        /**
+         * During an LE connection establishment, one must be in the Peripheral mode and the other
+         * in the Central role.
+         *
+         * <p>Possible Values:
+         * {@link LE_DEVICE_ROLE_PERIPHERAL_ONLY} Only Peripheral supported
+         * {@link LE_DEVICE_ROLE_CENTRAL_ONLY} Only Central supported
+         * {@link LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL} Central & Peripheral supported;
+         * Peripheral Preferred
+         * {@link LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL} Only peripheral supported; Central Preferred
+         * 0x04 - 0xFF Reserved
+         */
+        private final @LeRole int mLeDeviceRole;
+
+        /**
+         * Temporary key value from the Security Manager.
+         *
+         * <p> Must be {@link LE_TK_OCTETS} in size
+         */
+        private byte[] mLeTemporaryKey = null;
+
+        /**
+         * Defines the representation of the external appearance of the device.
+         *
+         * <p>For example, a mouse, remote control, or keyboard.
+         *
+         * <p>Used for visual on discovering device to represent icon/string/etc...
+         */
+        private byte[] mLeAppearance = null;
+
+        /**
+         * Contains which discoverable mode to use, BR/EDR support and capability.
+         *
+         * <p>Possible LE Flags:
+         * {@link LE_FLAG_LIMITED_DISCOVERY_MODE} LE Limited Discoverable Mode.
+         * {@link LE_FLAG_GENERAL_DISCOVERY_MODE} LE General Discoverable Mode.
+         * {@link LE_FLAG_BREDR_NOT_SUPPORTED} BR/EDR Not Supported. Bit 37 of
+         * LMP Feature Mask Definitions.
+         * {@link LE_FLAG_SIMULTANEOUS_CONTROLLER} Simultaneous LE and BR/EDR to
+         * Same Device Capable (Controller).
+         * Bit 49 of LMP Feature Mask Definitions.
+         * {@link LE_FLAG_SIMULTANEOUS_HOST} Simultaneous LE and BR/EDR to
+         * Same Device Capable (Host).
+         * Bit 55 of LMP Feature Mask Definitions.
+         * <b>0x05- 0x07 Reserved</b>
+         */
+        private @LeFlag int mLeFlags = LE_FLAG_GENERAL_DISCOVERY_MODE; // Invalid default
+
+        /**
+         * Constructing an OobData object for use with LE requires
+         * a LE Device Address and LE Device Role as well as the Confirmation
+         * and optionally, the Randomizer, however it is recommended to use.
+         *
+         * @param confirmationHash byte array consisting of {@link OobData#CONFIRMATION_OCTETS}
+         * octets of data. Data is derived from controller/host stack and is required for
+         * pairing OOB.
+         * @param deviceAddressWithType 7 bytes containing the 6 byte address with the 1 byte
+         * address type.
+         * @param leDeviceRole indicating device's role and preferences (Central or Peripheral)
+         *
+         * <p>Possible Values:
+         * {@link LE_DEVICE_ROLE_PERIPHERAL_ONLY} Only Peripheral supported
+         * {@link LE_DEVICE_ROLE_CENTRAL_ONLY} Only Central supported
+         * {@link LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL} Central & Peripheral supported;
+         * Peripheral Preferred
+         * {@link LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL} Only peripheral supported; Central Preferred
+         * 0x04 - 0xFF Reserved
+         *
+         * @throws IllegalArgumentException if deviceAddressWithType is not
+         *                                  {@link LE_DEVICE_ADDRESS_OCTETS} octets
+         * @throws NullPointerException if any argument is null.
+         */
+        private LeBuilder(@NonNull byte[] confirmationHash, @NonNull byte[] deviceAddressWithType,
+                @LeRole int leDeviceRole) {
+            Preconditions.checkNotNull(confirmationHash);
+            Preconditions.checkNotNull(deviceAddressWithType);
+            if (confirmationHash.length != OobData.CONFIRMATION_OCTETS) {
+                throw new IllegalArgumentException("confirmationHash must be "
+                    + OobData.CONFIRMATION_OCTETS + " octets in length.");
+            }
+            this.mConfirmationHash = confirmationHash;
+            if (deviceAddressWithType.length != OobData.DEVICE_ADDRESS_OCTETS) {
+                throw new IllegalArgumentException("confirmationHash must be "
+                    + OobData.DEVICE_ADDRESS_OCTETS+ " octets in length.");
+            }
+            this.mDeviceAddressWithType = deviceAddressWithType;
+            if (leDeviceRole < LE_DEVICE_ROLE_PERIPHERAL_ONLY
+                    || leDeviceRole > LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL) {
+                throw new IllegalArgumentException("leDeviceRole must be a valid value.");
+            }
+            this.mLeDeviceRole = leDeviceRole;
+        }
+
+        /**
+         * Sets the Temporary Key value to be used by the LE Security Manager during
+         * LE pairing.
+         *
+         * @param leTemporaryKey byte array that shall be 16 bytes. Please see Bluetooth CSSv6,
+         * Part A 1.8 for a detailed description.
+         *
+         * @return {@link OobData#Builder}
+         *
+         * @throws IllegalArgumentException if the leTemporaryKey is an invalid format.
+         * @throws NullinterException if leTemporaryKey is null.
+         *
+         * @hide
+         */
+        @NonNull
+        @SystemApi
+        public LeBuilder setLeTemporaryKey(@NonNull byte[] leTemporaryKey) {
+            Preconditions.checkNotNull(leTemporaryKey);
+            if (leTemporaryKey.length != LE_TK_OCTETS) {
+                throw new IllegalArgumentException("leTemporaryKey must be "
+                        + LE_TK_OCTETS + " octets in length.");
+            }
+            this.mLeTemporaryKey = leTemporaryKey;
+            return this;
+        }
+
+        /**
+         * @param randomizerHash byte array consisting of {@link OobData#RANDOMIZER_OCTETS} octets
+         * of data. Data is derived from controller/host stack and is required for pairing OOB.
+         * Also, randomizerHash may be all 0s or null in which case it becomes all 0s.
+         *
+         * @throws IllegalArgumentException if null or incorrect length randomizerHash was passed.
+         * @throws NullPointerException if randomizerHash is null.
+         *
+         * @hide
+         */
+        @NonNull
+        @SystemApi
+        public LeBuilder setRandomizerHash(@NonNull byte[] randomizerHash) {
+            Preconditions.checkNotNull(randomizerHash);
+            if (randomizerHash.length != OobData.RANDOMIZER_OCTETS) {
+                throw new IllegalArgumentException("randomizerHash must be "
+                    + OobData.RANDOMIZER_OCTETS + " octets in length.");
+            }
+            this.mRandomizerHash = randomizerHash;
+            return this;
+        }
+
+        /**
+         * Sets the LE Flags necessary for the pairing scenario or discovery mode.
+         *
+         * @param leFlags enum value representing the 1 octet of data about discovery modes.
+         *
+         * <p>Possible LE Flags:
+         * {@link LE_FLAG_LIMITED_DISCOVERY_MODE} LE Limited Discoverable Mode.
+         * {@link LE_FLAG_GENERAL_DISCOVERY_MODE} LE General Discoverable Mode.
+         * {@link LE_FLAG_BREDR_NOT_SUPPORTED} BR/EDR Not Supported. Bit 37 of
+         * LMP Feature Mask Definitions.
+         * {@link LE_FLAG_SIMULTANEOUS_CONTROLLER} Simultaneous LE and BR/EDR to
+         * Same Device Capable (Controller) Bit 49 of LMP Feature Mask Definitions.
+         * {@link LE_FLAG_SIMULTANEOUS_HOST} Simultaneous LE and BR/EDR to
+         * Same Device Capable (Host).
+         * Bit 55 of LMP Feature Mask Definitions.
+         * 0x05- 0x07 Reserved
+         *
+         * @throws IllegalArgumentException for invalid flag
+         * @hide
+         */
+        @NonNull
+        @SystemApi
+        public LeBuilder setLeFlags(@LeFlag int leFlags) {
+            if (leFlags < LE_FLAG_LIMITED_DISCOVERY_MODE || leFlags > LE_FLAG_SIMULTANEOUS_HOST) {
+                throw new IllegalArgumentException("leFlags must be a valid value.");
+            }
+            this.mLeFlags = leFlags;
+            return this;
+        }
+
+        /**
+         * Validates and builds the {@link OobData} object for LE Security.
+         *
+         * @return {@link OobData} with given builder values
+         *
+         * @throws IllegalStateException if either of the 2 required fields were not set.
+         *
+         * @hide
+         */
+        @NonNull
+        @SystemApi
+        public OobData build() {
+            final OobData oob =
+                    new OobData(this.mDeviceAddressWithType, this.mLeDeviceRole,
+                            this.mConfirmationHash);
+
+            // If we have values, set them, otherwise use default
+            oob.mLeTemporaryKey =
+                    (this.mLeTemporaryKey != null) ? this.mLeTemporaryKey : oob.mLeTemporaryKey;
+            oob.mLeAppearance = (this.mLeAppearance != null)
+                    ? this.mLeAppearance : oob.mLeAppearance;
+            oob.mLeFlags = (this.mLeFlags != 0xF) ? this.mLeFlags : oob.mLeFlags;
+            oob.mDeviceName = (this.mDeviceName != null) ? this.mDeviceName : oob.mDeviceName;
+            oob.mRandomizerHash = this.mRandomizerHash;
+            return oob;
+        }
     }
 
-    public byte[] getLeSecureConnectionsConfirmation() {
-        return mLeSecureConnectionsConfirmation;
+    /**
+     * Builds an {@link OobData} object and validates that the required combination
+     * of values are present to create the Classic specific OobData type.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final class ClassicBuilder {
+        // Used by both Classic and LE
+        /**
+         * It is recommended that this Hash C is generated anew for each
+         * pairing.
+         *
+         * <p>It should be noted that on passive NFC this isn't possible as the data is static
+         * and immutable.
+         *
+         * @hide
+         */
+        private byte[] mConfirmationHash = null;
+
+        /**
+         * Optional, but adds more validity to the pairing.
+         *
+         * <p>If not present a value of 0 is assumed.
+         *
+         * @hide
+         */
+        private byte[] mRandomizerHash = new byte[] {
+            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+        };
+
+        /**
+         * The Bluetooth Device user-friendly name presented over Bluetooth Technology.
+         *
+         * <p>This is the name that may be displayed to the device user as part of the UI.
+         *
+         * @hide
+         */
+        private byte[] mDeviceName = null;
+
+        /**
+         * This length value provides the absolute length of total OOB data block used for
+         * Bluetooth BR/EDR
+         *
+         * <p>OOB communication, which includes the length field itself and the Bluetooth
+         * Device Address.
+         *
+         * <p>The minimum length that may be represented in this field is 8.
+         *
+         * @hide
+         */
+        private final byte[] mClassicLength;
+
+        /**
+         * The Bluetooth Device Address is the address to which the OOB data belongs.
+         *
+         * <p>The length MUST be {@link OobData#DEVICE_ADDRESS_OCTETS} octets.
+         *
+         * <p> Address is encoded in Little Endian order.
+         *
+         * <p>e.g. 00:01:02:03:04:05 would be x05x04x03x02x01x00
+         *
+         * @hide
+         */
+        private final byte[] mDeviceAddressWithType;
+
+        /**
+         * Class of Device information is to be used to provide a graphical representation
+         * to the user as part of UI involving operations.
+         *
+         * <p>This is not to be used to determine a particular service can be used.
+         *
+         * <p>The length MUST be {@link OobData#CLASS_OF_DEVICE_OCTETS} octets.
+         *
+         * @hide
+         */
+        private byte[] mClassOfDevice = null;
+
+        /**
+         * @param confirmationHash byte array consisting of {@link OobData#CONFIRMATION_OCTETS}
+         * octets of data. Data is derived from controller/host stack and is required for pairing
+         * OOB.
+         * @param randomizerHash byte array consisting of {@link OobData#RANDOMIZER_OCTETS} octets
+         * of data. Data is derived from controller/host stack and is required
+         * for pairing OOB. Also, randomizerHash may be all 0s or null in which case
+         * it becomes all 0s.
+         * @param classicLength byte array representing the length of data from 8-65535 across 2
+         * octets (0xXXXX). Inclusive of this value in the length.
+         * @param deviceAddressWithType byte array representing the Bluetooth Address of the device
+         * that owns the OOB data. (i.e. the originator) [7 octets] this includes the Address Type
+         * as the last octet.
+         *
+         * @throws IllegalArgumentException if any value is not the correct length
+         * @throws NullPointerException if anything passed is null
+         *
+         * @hide
+         */
+        private ClassicBuilder(@NonNull byte[] confirmationHash, @NonNull byte[] classicLength,
+                @NonNull byte[] deviceAddressWithType) {
+            Preconditions.checkNotNull(confirmationHash);
+            Preconditions.checkNotNull(classicLength);
+            Preconditions.checkNotNull(deviceAddressWithType);
+            if (confirmationHash.length != OobData.CONFIRMATION_OCTETS) {
+                throw new IllegalArgumentException("confirmationHash must be "
+                    + OobData.CONFIRMATION_OCTETS + " octets in length.");
+            }
+            this.mConfirmationHash = confirmationHash;
+            if (classicLength.length != OOB_LENGTH_OCTETS) {
+                throw new IllegalArgumentException("classicLength must be "
+                        + OOB_LENGTH_OCTETS + " octets in length.");
+            }
+            this.mClassicLength = classicLength;
+            if (deviceAddressWithType.length != DEVICE_ADDRESS_OCTETS) {
+                throw new IllegalArgumentException("deviceAddressWithType must be "
+                        + DEVICE_ADDRESS_OCTETS + " octets in length.");
+            }
+            this.mDeviceAddressWithType = deviceAddressWithType;
+        }
+
+        /**
+         * @param randomizerHash byte array consisting of {@link OobData#RANDOMIZER_OCTETS} octets
+         * of data. Data is derived from controller/host stack and is required for pairing OOB.
+         * Also, randomizerHash may be all 0s or null in which case it becomes all 0s.
+         *
+         * @throws IllegalArgumentException if null or incorrect length randomizerHash was passed.
+         * @throws NullPointerException if randomizerHash is null.
+         *
+         * @hide
+         */
+        @NonNull
+        @SystemApi
+        public ClassicBuilder setRandomizerHash(@NonNull byte[] randomizerHash) {
+            Preconditions.checkNotNull(randomizerHash);
+            if (randomizerHash.length != OobData.RANDOMIZER_OCTETS) {
+                throw new IllegalArgumentException("randomizerHash must be "
+                    + OobData.RANDOMIZER_OCTETS + " octets in length.");
+            }
+            this.mRandomizerHash = randomizerHash;
+            return this;
+        }
+
+        /**
+         * Sets the Bluetooth Device name to be used for UI purposes.
+         *
+         * <p>Optional attribute.
+         *
+         * @param deviceName byte array representing the name, may be 0 in length, not null.
+         *
+         * @return {@link OobData#ClassicBuilder}
+         *
+         * @throws NullPointerException if deviceName is null
+         *
+         * @hide
+         */
+        @NonNull
+        @SystemApi
+        public ClassicBuilder setDeviceName(@NonNull byte[] deviceName) {
+            Preconditions.checkNotNull(deviceName);
+            this.mDeviceName = deviceName;
+            return this;
+        }
+
+        /**
+         * Sets the Bluetooth Class of Device; used for UI purposes only.
+         *
+         * <p>Not an indicator of available services!
+         *
+         * <p>Optional attribute.
+         *
+         * @param classOfDevice byte array of {@link OobData#CLASS_OF_DEVICE_OCTETS} octets.
+         *
+         * @return {@link OobData#ClassicBuilder}
+         *
+         * @throws IllegalArgumentException if length is not equal to
+         * {@link OobData#CLASS_OF_DEVICE_OCTETS} octets.
+         * @throws NullPointerException if classOfDevice is null.
+         *
+         * @hide
+         */
+        @NonNull
+        @SystemApi
+        public ClassicBuilder setClassOfDevice(@NonNull byte[] classOfDevice) {
+            Preconditions.checkNotNull(classOfDevice);
+            if (classOfDevice.length != OobData.CLASS_OF_DEVICE_OCTETS) {
+                throw new IllegalArgumentException("classOfDevice must be "
+                        + OobData.CLASS_OF_DEVICE_OCTETS + " octets in length.");
+            }
+            this.mClassOfDevice = classOfDevice;
+            return this;
+        }
+
+        /**
+         * Validates and builds the {@link OobDat object for Classic Security.
+         *
+         * @return {@link OobData} with previously given builder values.
+         *
+         * @hide
+         */
+        @NonNull
+        @SystemApi
+        public OobData build() {
+            final OobData oob =
+                    new OobData(this.mClassicLength, this.mDeviceAddressWithType,
+                            this.mConfirmationHash);
+            // If we have values, set them, otherwise use default
+            oob.mDeviceName = (this.mDeviceName != null) ? this.mDeviceName : oob.mDeviceName;
+            oob.mClassOfDevice = (this.mClassOfDevice != null)
+                    ? this.mClassOfDevice : oob.mClassOfDevice;
+            oob.mRandomizerHash = this.mRandomizerHash;
+            return oob;
+        }
     }
 
-    public void setLeSecureConnectionsConfirmation(byte[] leSecureConnectionsConfirmation) {
-        mLeSecureConnectionsConfirmation = leSecureConnectionsConfirmation;
+    // Members (Defaults for Optionals must be set or Parceling fails on NPE)
+    // Both
+    private final byte[] mDeviceAddressWithType;
+    private final byte[] mConfirmationHash;
+    private byte[] mRandomizerHash = new byte[] {
+        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+    };
+    // Default the name to "Bluetooth Device"
+    private byte[] mDeviceName = new byte[] {
+        // Bluetooth
+        0x42, 0x6c, 0x75, 0x65, 0x74, 0x6f, 0x6f, 0x74, 0x68,
+        // <space>Device
+        0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65
+    };
+
+    // Classic
+    private final byte[] mClassicLength;
+    private byte[] mClassOfDevice = new byte[CLASS_OF_DEVICE_OCTETS];
+
+    // LE
+    private final @LeRole int mLeDeviceRole;
+    private byte[] mLeTemporaryKey = new byte[LE_TK_OCTETS];
+    private byte[] mLeAppearance = new byte[LE_APPEARANCE_OCTETS];
+    private @LeFlag int mLeFlags = LE_FLAG_LIMITED_DISCOVERY_MODE;
+
+    /**
+     * @return byte array representing the MAC address of a bluetooth device.
+     * The Address is 6 octets long with a 1 octet address type associated with the address.
+     *
+     * <p>For classic this will be 6 byte address plus the default of PUBLIC_ADDRESS Address Type.
+     * For LE there are more choices for Address Type.
+     *
+     * @hide
+     */
+    @NonNull
+    @SystemApi
+    public byte[] getDeviceAddressWithType() {
+        return mDeviceAddressWithType;
     }
 
-    public byte[] getLeSecureConnectionsRandom() {
-        return mLeSecureConnectionsRandom;
+    /**
+     * @return byte array representing the confirmationHash value
+     * which is used to confirm the identity to the controller.
+     *
+     * @hide
+     */
+    @NonNull
+    @SystemApi
+    public byte[] getConfirmationHash() {
+        return mConfirmationHash;
     }
 
-    public void setLeSecureConnectionsRandom(byte[] leSecureConnectionsRandom) {
-        mLeSecureConnectionsRandom = leSecureConnectionsRandom;
+    /**
+     * @return byte array representing the randomizerHash value
+     * which is used to verify the identity of the controller.
+     *
+     * @hide
+     */
+    @NonNull
+    @SystemApi
+    public byte[] getRandomizerHash() {
+        return mRandomizerHash;
     }
 
-    public OobData() {
+    /**
+     * @return Device Name used for displaying name in UI.
+     *
+     * <p>Also, this will be populated with the LE Local Name if the data is for LE.
+     *
+     * @hide
+     */
+    @Nullable
+    @SystemApi
+    public byte[] getDeviceName() {
+        return mDeviceName;
+    }
+
+    /**
+     * @return byte array representing the oob data length which is the length
+     * of all of the data including these octets.
+     *
+     * @hide
+     */
+    @NonNull
+    @SystemApi
+    public byte[] getClassicLength() {
+        return mClassicLength;
+    }
+
+    /**
+     * @return byte array representing the class of device for UI display.
+     *
+     * <p>Does not indicate services available; for display only.
+     *
+     * @hide
+     */
+    @NonNull
+    @SystemApi
+    public byte[] getClassOfDevice() {
+        return mClassOfDevice;
+    }
+
+    /**
+     * @return Temporary Key used for LE pairing.
+     *
+     * @hide
+     */
+    @Nullable
+    @SystemApi
+    public byte[] getLeTemporaryKey() {
+        return mLeTemporaryKey;
+    }
+
+    /**
+     * @return Appearance used for LE pairing. For use in UI situations
+     * when determining what sort of icons or text to display regarding
+     * the device.
+     *
+     * @hide
+     */
+    @Nullable
+    @SystemApi
+    public byte[] getLeAppearance() {
+        return mLeTemporaryKey;
+    }
+
+    /**
+     * @return Flags used to determing discoverable mode to use, BR/EDR Support, and Capability.
+     *
+     * <p>Possible LE Flags:
+     * {@link LE_FLAG_LIMITED_DISCOVERY_MODE} LE Limited Discoverable Mode.
+     * {@link LE_FLAG_GENERAL_DISCOVERY_MODE} LE General Discoverable Mode.
+     * {@link LE_FLAG_BREDR_NOT_SUPPORTED} BR/EDR Not Supported. Bit 37 of
+     * LMP Feature Mask Definitions.
+     * {@link LE_FLAG_SIMULTANEOUS_CONTROLLER} Simultaneous LE and BR/EDR to
+     * Same Device Capable (Controller).
+     * Bit 49 of LMP Feature Mask Definitions.
+     * {@link LE_FLAG_SIMULTANEOUS_HOST} Simultaneous LE and BR/EDR to
+     * Same Device Capable (Host).
+     * Bit 55 of LMP Feature Mask Definitions.
+     * <b>0x05- 0x07 Reserved</b>
+     *
+     * @hide
+     */
+    @NonNull
+    @SystemApi
+    @LeFlag
+    public int getLeFlags() {
+        return mLeFlags;
+    }
+
+    /**
+     * @return the supported and preferred roles of the LE device.
+     *
+     * <p>Possible Values:
+     * {@link LE_DEVICE_ROLE_PERIPHERAL_ONLY} Only Peripheral supported
+     * {@link LE_DEVICE_ROLE_CENTRAL_ONLY} Only Central supported
+     * {@link LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL} Central & Peripheral supported;
+     * Peripheral Preferred
+     * {@link LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL} Only peripheral supported; Central Preferred
+     * 0x04 - 0xFF Reserved
+     *
+     * @hide
+     */
+    @NonNull
+    @SystemApi
+    @LeRole
+    public int getLeDeviceRole() {
+        return mLeDeviceRole;
+    }
+
+    /**
+     * Classic Security Constructor
+     */
+    private OobData(@NonNull byte[] classicLength, @NonNull byte[] deviceAddressWithType,
+            @NonNull byte[] confirmationHash) {
+        mClassicLength = classicLength;
+        mDeviceAddressWithType = deviceAddressWithType;
+        mConfirmationHash = confirmationHash;
+        mLeDeviceRole = -1; // Satisfy final
+    }
+
+    /**
+     * LE Security Constructor
+     */
+    private OobData(@NonNull byte[] deviceAddressWithType, @LeRole int leDeviceRole,
+            @NonNull byte[] confirmationHash) {
+        mDeviceAddressWithType = deviceAddressWithType;
+        mLeDeviceRole = leDeviceRole;
+        mConfirmationHash = confirmationHash;
+        mClassicLength = new byte[OOB_LENGTH_OCTETS]; // Satisfy final
     }
 
     private OobData(Parcel in) {
-        mLeBluetoothDeviceAddress = in.createByteArray();
-        mSecurityManagerTk = in.createByteArray();
-        mLeSecureConnectionsConfirmation = in.createByteArray();
-        mLeSecureConnectionsRandom = in.createByteArray();
+        // Both
+        mDeviceAddressWithType = in.createByteArray();
+        mConfirmationHash = in.createByteArray();
+        mRandomizerHash = in.createByteArray();
+        mDeviceName = in.createByteArray();
+
+        // Classic
+        mClassicLength = in.createByteArray();
+        mClassOfDevice = in.createByteArray();
+
+        // LE
+        mLeDeviceRole = in.readInt();
+        mLeTemporaryKey = in.createByteArray();
+        mLeAppearance = in.createByteArray();
+        mLeFlags = in.readInt();
     }
 
+    /**
+     * @hide
+     */
     @Override
     public int describeContents() {
         return 0;
     }
 
+    /**
+     * @hide
+     */
     @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeByteArray(mLeBluetoothDeviceAddress);
-        out.writeByteArray(mSecurityManagerTk);
-        out.writeByteArray(mLeSecureConnectionsConfirmation);
-        out.writeByteArray(mLeSecureConnectionsRandom);
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        // Both
+        // Required
+        out.writeByteArray(mDeviceAddressWithType);
+        // Required
+        out.writeByteArray(mConfirmationHash);
+        // Optional
+        out.writeByteArray(mRandomizerHash);
+        // Optional
+        out.writeByteArray(mDeviceName);
+
+        // Classic
+        // Required
+        out.writeByteArray(mClassicLength);
+        // Optional
+        out.writeByteArray(mClassOfDevice);
+
+        // LE
+        // Required
+        out.writeInt(mLeDeviceRole);
+        // Required
+        out.writeByteArray(mLeTemporaryKey);
+        // Optional
+        out.writeByteArray(mLeAppearance);
+        // Optional
+        out.writeInt(mLeFlags);
     }
 
+    // For Parcelable
     public static final @android.annotation.NonNull Parcelable.Creator<OobData> CREATOR =
             new Parcelable.Creator<OobData>() {
         public OobData createFromParcel(Parcel in) {
@@ -108,4 +969,47 @@
             return new OobData[size];
         }
     };
+
+    /**
+     * @return a {@link String} representation of the OobData object.
+     *
+     * @hide
+     */
+    @Override
+    @NonNull
+    public String toString() {
+        return "OobData: \n\t"
+            // Both
+            + "Device Address With Type: " +  toHexString(mDeviceAddressWithType) + "\n\t"
+            + "Confirmation: " + toHexString(mConfirmationHash) + "\n\t"
+            + "Randomizer: " + toHexString(mRandomizerHash) + "\n\t"
+            + "Device Name: " + toHexString(mDeviceName) + "\n\t"
+            // Classic
+            + "OobData Length: " +  toHexString(mClassicLength) + "\n\t"
+            + "Class of Device: " +  toHexString(mClassOfDevice) + "\n\t"
+            // LE
+            + "LE Device Role: " + toHexString(mLeDeviceRole) + "\n\t"
+            + "LE Temporary Key: " + toHexString(mLeTemporaryKey) + "\n\t"
+            + "LE Appearance: " + toHexString(mLeAppearance) + "\n\t"
+            + "LE Flags: " + toHexString(mLeFlags) + "\n\t";
+    }
+
+    @NonNull
+    private String toHexString(@NonNull int b) {
+        return toHexString(new byte[] {(byte) b});
+    }
+
+    @NonNull
+    private String toHexString(@NonNull byte b) {
+        return toHexString(new byte[] {b});
+    }
+
+    @NonNull
+    private String toHexString(@NonNull byte[] array) {
+        StringBuilder builder = new StringBuilder(array.length * 2);
+        for (byte b: array) {
+            builder.append(String.format("%02x", b));
+        }
+        return builder.toString();
+    }
 }
diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java
index 7511fd0..8672150 100644
--- a/core/java/android/bluetooth/le/ScanFilter.java
+++ b/core/java/android/bluetooth/le/ScanFilter.java
@@ -16,15 +16,19 @@
 
 package android.bluetooth.le;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothDevice.AddressType;
 import android.os.Parcel;
 import android.os.ParcelUuid;
 import android.os.Parcelable;
 
 import com.android.internal.util.BitUtils;
+import com.android.internal.util.Preconditions;
 
 import java.util.Arrays;
 import java.util.List;
@@ -53,6 +57,11 @@
     @Nullable
     private final String mDeviceAddress;
 
+    private final @AddressType int mAddressType;
+
+    @Nullable
+    private final byte[] mIrk;
+
     @Nullable
     private final ParcelUuid mServiceUuid;
     @Nullable
@@ -79,12 +88,12 @@
     /** @hide */
     public static final ScanFilter EMPTY = new ScanFilter.Builder().build();
 
-
     private ScanFilter(String name, String deviceAddress, ParcelUuid uuid,
             ParcelUuid uuidMask, ParcelUuid solicitationUuid,
             ParcelUuid solicitationUuidMask, ParcelUuid serviceDataUuid,
             byte[] serviceData, byte[] serviceDataMask,
-            int manufacturerId, byte[] manufacturerData, byte[] manufacturerDataMask) {
+            int manufacturerId, byte[] manufacturerData, byte[] manufacturerDataMask,
+            @AddressType int addressType, @Nullable byte[] irk) {
         mDeviceName = name;
         mServiceUuid = uuid;
         mServiceUuidMask = uuidMask;
@@ -97,6 +106,8 @@
         mManufacturerId = manufacturerId;
         mManufacturerData = manufacturerData;
         mManufacturerDataMask = manufacturerDataMask;
+        mAddressType = addressType;
+        mIrk = irk;
     }
 
     @Override
@@ -280,6 +291,23 @@
         return mDeviceAddress;
     }
 
+    /**
+     * @hide
+     */
+    @SystemApi
+    public @AddressType int getAddressType() {
+        return mAddressType;
+    }
+
+    /**
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public byte[] getIrk() {
+        return mIrk;
+    }
+
     @Nullable
     public byte[] getServiceData() {
         return mServiceData;
@@ -516,8 +544,16 @@
      */
     public static final class Builder {
 
+        /**
+         * @hide
+         */
+        @SystemApi
+        public static final int LEN_IRK_OCTETS = 16;
+
         private String mDeviceName;
         private String mDeviceAddress;
+        private @AddressType int mAddressType = BluetoothDevice.ADDRESS_TYPE_PUBLIC;
+        private byte[] mIrk;
 
         private ParcelUuid mServiceUuid;
         private ParcelUuid mUuidMask;
@@ -546,14 +582,130 @@
          *
          * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the
          * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link
-         * BluetoothAdapter#checkBluetoothAddress}.
+         * BluetoothAdapter#checkBluetoothAddress}.  The @AddressType is defaulted to {@link
+         * BluetoothDevice#ADDRESS_TYPE_PUBLIC}
          * @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
          */
         public Builder setDeviceAddress(String deviceAddress) {
-            if (deviceAddress != null && !BluetoothAdapter.checkBluetoothAddress(deviceAddress)) {
+            return setDeviceAddress(mDeviceAddress, BluetoothDevice.ADDRESS_TYPE_PUBLIC);
+        }
+
+        /**
+         * Set filter on Address with AddressType
+         *
+         * <p>This key is used to resolve a private address from a public address.
+         *
+         * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the
+         * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link
+         * BluetoothAdapter#checkBluetoothAddress}. May be any type of address.
+         * @param addressType indication of the type of address
+         * e.g. {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC}
+         * or {@link BluetoothDevice#ADDRESS_TYPE_RANDOM}
+         *
+         * @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
+         * @throws IllegalArgumentException If the {@code addressType} is invalid length
+         * @throws NullPointerException if {@code deviceAddress} is null.
+         *
+         * @hide
+         */
+        @NonNull
+        @SystemApi
+        public Builder setDeviceAddress(@NonNull String deviceAddress,
+                                        @AddressType int addressType) {
+            return setDeviceAddressInternal(deviceAddress, addressType, null);
+        }
+
+        /**
+         * Set filter on Address with AddressType and the Identity Resolving Key (IRK).
+         *
+         * <p>The IRK is used to resolve a {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC} from
+         * a PRIVATE_ADDRESS type.
+         *
+         * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the
+         * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link
+         * BluetoothAdapter#checkBluetoothAddress}.  This Address type must only be PUBLIC OR RANDOM
+         * STATIC.
+         * @param addressType indication of the type of address
+         * e.g. {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC}
+         * or {@link BluetoothDevice#ADDRESS_TYPE_RANDOM}
+         * @param irk non-null byte array representing the Identity Resolving Key
+         *
+         * @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
+         * @throws IllegalArgumentException if the {@code irk} is invalid length.
+         * @throws IllegalArgumentException If the {@code addressType} is invalid length or is not
+         * PUBLIC or RANDOM STATIC when an IRK is present.
+         * @throws NullPointerException if {@code deviceAddress} or {@code irk} is null.
+         *
+         * @hide
+         */
+        @NonNull
+        @SystemApi
+        public Builder setDeviceAddress(@NonNull String deviceAddress,
+                                        @AddressType int addressType,
+                                        @NonNull byte[] irk) {
+            Preconditions.checkNotNull(irk);
+            if (irk.length != LEN_IRK_OCTETS) {
+                throw new IllegalArgumentException("'irk' is invalid length!");
+            }
+            return setDeviceAddressInternal(deviceAddress, addressType, irk);
+        }
+
+        /**
+         * Set filter on Address with AddressType and the Identity Resolving Key (IRK).
+         *
+         * <p>Internal setter for the device address
+         *
+         * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the
+         * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link
+         * BluetoothAdapter#checkBluetoothAddress}.
+         * @param addressType indication of the type of address
+         * e.g. {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC}
+         * @param irk non-null byte array representing the Identity Resolving Address; nullable
+         * internally.
+         *
+         * @throws IllegalArgumentException If the {@code deviceAddress} is invalid.
+         * @throws IllegalArgumentException If the {@code addressType} is invalid length.
+         * @throws NullPointerException if {@code deviceAddress} is null.
+         *
+         * @hide
+         */
+        @NonNull
+        private Builder setDeviceAddressInternal(@NonNull String deviceAddress,
+                                                 @AddressType int addressType,
+                                                 @Nullable byte[] irk) {
+
+            // Make sure our deviceAddress is valid!
+            Preconditions.checkNotNull(deviceAddress);
+            if (!BluetoothAdapter.checkBluetoothAddress(deviceAddress)) {
                 throw new IllegalArgumentException("invalid device address " + deviceAddress);
             }
+
+            // Verify type range
+            if (addressType < BluetoothDevice.ADDRESS_TYPE_PUBLIC
+                || addressType > BluetoothDevice.ADDRESS_TYPE_RANDOM) {
+                throw new IllegalArgumentException("'addressType' is invalid!");
+            }
+
+            // IRK can only be used for a PUBLIC or RANDOM (STATIC) Address.
+            if (addressType == BluetoothDevice.ADDRESS_TYPE_RANDOM) {
+                // Don't want a bad combination of address and irk!
+                if (irk != null) {
+                    // Since there are 3 possible RANDOM subtypes we must check to make sure
+                    // the correct type of address is used.
+                    if (!BluetoothAdapter.isAddressRandomStatic(deviceAddress)) {
+                        throw new IllegalArgumentException(
+                                "Invalid combination: IRK requires either a PUBLIC or "
+                                + "RANDOM (STATIC) Address");
+                    }
+                }
+            }
+
+            // PUBLIC doesn't require extra work
+            // Without an IRK any address may be accepted
+
             mDeviceAddress = deviceAddress;
+            mAddressType = addressType;
+            mIrk = irk;
             return this;
         }
 
@@ -727,7 +879,8 @@
                     mServiceUuid, mUuidMask, mServiceSolicitationUuid,
                     mServiceSolicitationUuidMask,
                     mServiceDataUuid, mServiceData, mServiceDataMask,
-                    mManufacturerId, mManufacturerData, mManufacturerDataMask);
+                    mManufacturerId, mManufacturerData, mManufacturerDataMask,
+                    mAddressType, mIrk);
         }
     }
 }
diff --git a/core/java/android/bluetooth/le/ScanSettings.java b/core/java/android/bluetooth/le/ScanSettings.java
index 504118e..368d1ee 100644
--- a/core/java/android/bluetooth/le/ScanSettings.java
+++ b/core/java/android/bluetooth/le/ScanSettings.java
@@ -52,6 +52,16 @@
     public static final int SCAN_MODE_LOW_LATENCY = 2;
 
     /**
+     * Perform Bluetooth LE scan in ambient discovery mode. This mode has lower duty cycle and more
+     * aggressive scan interval than balanced mode that provides a good trade-off between scan
+     * latency and power consumption.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int SCAN_MODE_AMBIENT_DISCOVERY = 3;
+
+    /**
      * Trigger a callback for every Bluetooth advertisement found that matches the filter criteria.
      * If no filter is active, all advertisement packets are reported.
      */
@@ -276,10 +286,17 @@
          * @throws IllegalArgumentException If the {@code scanMode} is invalid.
          */
         public Builder setScanMode(int scanMode) {
-            if (scanMode < SCAN_MODE_OPPORTUNISTIC || scanMode > SCAN_MODE_LOW_LATENCY) {
-                throw new IllegalArgumentException("invalid scan mode " + scanMode);
+            switch (scanMode) {
+                case SCAN_MODE_OPPORTUNISTIC:
+                case SCAN_MODE_LOW_POWER:
+                case SCAN_MODE_BALANCED:
+                case SCAN_MODE_LOW_LATENCY:
+                case SCAN_MODE_AMBIENT_DISCOVERY:
+                    mScanMode = scanMode;
+                    break;
+                default:
+                    throw new IllegalArgumentException("invalid scan mode " + scanMode);
             }
-            mScanMode = scanMode;
             return this;
         }
 
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 7f834af..933dee3 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -2024,7 +2024,9 @@
                 // Tell listeners that the cameras and torch modes are unavailable and schedule a
                 // reconnection to camera service. When camera service is reconnected, the camera
                 // and torch statuses will be updated.
-                for (int i = 0; i < mDeviceStatus.size(); i++) {
+                // Iterate from the end to the beginning befcause onStatusChangedLocked removes
+                // entries from the ArrayMap.
+                for (int i = mDeviceStatus.size() - 1; i >= 0; i--) {
                     String cameraId = mDeviceStatus.keyAt(i);
                     onStatusChangedLocked(ICameraServiceListener.STATUS_NOT_PRESENT, cameraId);
                 }
diff --git a/core/java/android/net/INetworkPolicyListener.aidl b/core/java/android/net/INetworkPolicyListener.aidl
index dfb1e99..00c6913 100644
--- a/core/java/android/net/INetworkPolicyListener.aidl
+++ b/core/java/android/net/INetworkPolicyListener.aidl
@@ -25,4 +25,5 @@
     void onUidPoliciesChanged(int uid, int uidPolicies);
     void onSubscriptionOverride(int subId, int overrideMask, int overrideValue, in int[] networkTypes);
     void onSubscriptionPlansChanged(int subId, in SubscriptionPlan[] plans);
+    void onBlockedReasonChanged(int uid, int oldBlockedReason, int newBlockedReason);
 }
diff --git a/core/java/android/net/INetworkPolicyManager.aidl b/core/java/android/net/INetworkPolicyManager.aidl
index 9bf791b..171c6a2 100644
--- a/core/java/android/net/INetworkPolicyManager.aidl
+++ b/core/java/android/net/INetworkPolicyManager.aidl
@@ -62,6 +62,7 @@
         3 - enabled
     */
     int getRestrictBackgroundByCaller();
+    int getRestrictBackgroundStatus(int uid);
 
     void setDeviceIdleMode(boolean enabled);
     void setWifiMeteredOverride(String networkId, int meteredOverride);
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index 1c56954..10be02c 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -23,6 +23,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
 import android.app.ActivityManager;
@@ -44,6 +45,8 @@
 import android.util.Pair;
 import android.util.Range;
 
+import com.android.internal.util.function.pooled.PooledLambda;
+
 import com.google.android.collect.Sets;
 
 import java.lang.annotation.Retention;
@@ -53,6 +56,7 @@
 import java.util.Iterator;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
 
 /**
  * Manager for creating and modifying network policy rules.
@@ -60,6 +64,7 @@
  * @hide
  */
 @TestApi
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
 @SystemService(Context.NETWORK_POLICY_SERVICE)
 public class NetworkPolicyManager {
 
@@ -198,12 +203,171 @@
     })
     public @interface SubscriptionOverrideMask {}
 
+    /**
+     * Flag to indicate that an app is not subject to any restrictions that could result in its
+     * network access blocked.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int BLOCKED_REASON_NONE = 0;
+
+    /**
+     * Flag to indicate that an app is subject to Battery saver restrictions that would
+     * result in its network access being blocked.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int BLOCKED_REASON_BATTERY_SAVER = 1 << 0;
+
+    /**
+     * Flag to indicate that an app is subject to Doze restrictions that would
+     * result in its network access being blocked.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int BLOCKED_REASON_DOZE = 1 << 1;
+
+    /**
+     * Flag to indicate that an app is subject to App Standby restrictions that would
+     * result in its network access being blocked.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int BLOCKED_REASON_APP_STANDBY = 1 << 2;
+
+    /**
+     * Flag to indicate that an app is subject to Restricted mode restrictions that would
+     * result in its network access being blocked.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int BLOCKED_REASON_RESTRICTED_MODE = 1 << 3;
+
+    /**
+     * Flag to indicate that an app is subject to Data saver restrictions that would
+     * result in its metered network access being blocked.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int BLOCKED_METERED_REASON_DATA_SAVER = 1 << 16;
+
+    /**
+     * Flag to indicate that an app is subject to user restrictions that would
+     * result in its metered network access being blocked.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int BLOCKED_METERED_REASON_USER_RESTRICTED = 1 << 17;
+
+    /**
+     * Flag to indicate that an app is subject to Device admin restrictions that would
+     * result in its metered network access being blocked.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int BLOCKED_METERED_REASON_ADMIN_DISABLED = 1 << 18;
+
+    /** @hide */
+    public static final int BLOCKED_METERED_REASON_MASK = 0xffff0000;
+
+    /**
+     * Flag to indicate that app is not exempt from any network restrictions.
+     *
+     * @hide
+     */
+    public static final int ALLOWED_REASON_NONE = 0;
+    /**
+     * Flag to indicate that app is exempt from certain network restrictions because of it being a
+     * system component.
+     *
+     * @hide
+     */
+    public static final int ALLOWED_REASON_SYSTEM = 1 << 0;
+    /**
+     * Flag to indicate that app is exempt from certain network restrictions because of it being
+     * in the foreground.
+     *
+     * @hide
+     */
+    public static final int ALLOWED_REASON_FOREGROUND = 1 << 1;
+    /**
+     * Flag to indicate that app is exempt from certain network restrictions because of it being
+     * in the {@code allow-in-power-save} list.
+     *
+     * @hide
+     */
+    public static final int ALLOWED_REASON_POWER_SAVE_ALLOWLIST = 1 << 2;
+    /**
+     * Flag to indicate that app is exempt from certain network restrictions because of it being
+     * in the {@code allow-in-power-save-except-idle} list.
+     *
+     * @hide
+     */
+    public static final int ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST = 1 << 3;
+    /**
+     * Flag to indicate that app is exempt from certain network restrictions because of it holding
+     * certain privileged permissions.
+     *
+     * @hide
+     */
+    public static final int ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS = 1 << 4;
+    /**
+     * Flag to indicate that app is exempt from certain metered network restrictions because user
+     * explicitly exempted it.
+     *
+     * @hide
+     */
+    public static final int ALLOWED_METERED_REASON_USER_EXEMPTED = 1 << 16;
+    /**
+     * Flag to indicate that app is exempt from certain metered network restrictions because of it
+     * being a system component.
+     *
+     * @hide
+     */
+    public static final int ALLOWED_METERED_REASON_SYSTEM = 1 << 17;
+    /**
+     * Flag to indicate that app is exempt from certain metered network restrictions because of it
+     * being in the foreground.
+     *
+     * @hide
+     */
+    public static final int ALLOWED_METERED_REASON_FOREGROUND = 1 << 18;
+
+    /** @hide */
+    public static final int ALLOWED_METERED_REASON_MASK = 0xffff0000;
+
+    /**
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = true, prefix = {"BLOCKED_"}, value = {
+            BLOCKED_REASON_NONE,
+            BLOCKED_REASON_BATTERY_SAVER,
+            BLOCKED_REASON_DOZE,
+            BLOCKED_REASON_APP_STANDBY,
+            BLOCKED_REASON_RESTRICTED_MODE,
+            BLOCKED_METERED_REASON_DATA_SAVER,
+            BLOCKED_METERED_REASON_USER_RESTRICTED,
+            BLOCKED_METERED_REASON_ADMIN_DISABLED,
+    })
+    public @interface BlockedReason {}
+
     private final Context mContext;
     @UnsupportedAppUsage
     private INetworkPolicyManager mService;
 
     private final Map<SubscriptionCallback, SubscriptionCallbackProxy>
-            mCallbackMap = new ConcurrentHashMap<>();
+            mSubscriptionCallbackMap = new ConcurrentHashMap<>();
+    private final Map<NetworkPolicyCallback, NetworkPolicyCallbackProxy>
+            mNetworkPolicyCallbackMap = new ConcurrentHashMap<>();
 
     /** @hide */
     public NetworkPolicyManager(Context context, INetworkPolicyManager service) {
@@ -318,7 +482,7 @@
         }
 
         final SubscriptionCallbackProxy callbackProxy = new SubscriptionCallbackProxy(callback);
-        if (null != mCallbackMap.putIfAbsent(callback, callbackProxy)) {
+        if (null != mSubscriptionCallbackMap.putIfAbsent(callback, callbackProxy)) {
             throw new IllegalArgumentException("Callback is already registered.");
         }
         registerListener(callbackProxy);
@@ -331,7 +495,7 @@
             throw new NullPointerException("Callback cannot be null.");
         }
 
-        final SubscriptionCallbackProxy callbackProxy = mCallbackMap.remove(callback);
+        final SubscriptionCallbackProxy callbackProxy = mSubscriptionCallbackMap.remove(callback);
         if (callbackProxy == null) return;
 
         unregisterListener(callbackProxy);
@@ -379,6 +543,26 @@
     }
 
     /**
+     * Determines if an UID is subject to metered network restrictions while running in background.
+     *
+     * @param uid The UID whose status needs to be checked.
+     * @return {@link ConnectivityManager#RESTRICT_BACKGROUND_STATUS_DISABLED},
+     *         {@link ConnectivityManager##RESTRICT_BACKGROUND_STATUS_ENABLED},
+     *         or {@link ConnectivityManager##RESTRICT_BACKGROUND_STATUS_WHITELISTED} to denote
+     *         the current status of the UID.
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    @RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
+    public int getRestrictBackgroundStatus(int uid) {
+        try {
+            return mService.getRestrictBackgroundStatus(uid);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Override connections to be temporarily marked as either unmetered or congested,
      * along with automatic timeouts if desired.
      *
@@ -460,9 +644,8 @@
      * @param meteredNetwork True if the network is metered.
      * @return true if networking is blocked for the given uid according to current networking
      *         policies.
-     *
-     * @hide
      */
+    @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY)
     public boolean isUidNetworkingBlocked(int uid, boolean meteredNetwork) {
         try {
             return mService.isUidNetworkingBlocked(uid, meteredNetwork);
@@ -501,9 +684,8 @@
      *
      * @param uid The target uid.
      * @return true if the given uid is restricted from doing networking on metered networks.
-     *
-     * @hide
      */
+    @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY)
     public boolean isUidRestrictedOnMeteredNetworks(int uid) {
         try {
             return mService.isUidRestrictedOnMeteredNetworks(uid);
@@ -513,11 +695,15 @@
     }
 
     /**
-     * Get multipath preference for the given network.
+     * Gets a hint on whether it is desirable to use multipath data transfer on the given network.
+     *
+     * @return One of the ConnectivityManager.MULTIPATH_PREFERENCE_* constants.
      *
      * @hide
      */
-    public int getMultipathPreference(Network network) {
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    @RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
+    public int getMultipathPreference(@NonNull Network network) {
         try {
             return mService.getMultipathPreference(network);
         } catch (RemoteException e) {
@@ -689,6 +875,142 @@
         return WifiInfo.sanitizeSsid(ssid);
     }
 
+    /**
+     * Returns whether network access of an UID is blocked or not based on {@code blockedReasons}
+     * corresponding to it.
+     *
+     * {@code blockedReasons} would be a bitwise {@code OR} combination of the
+     * {@code BLOCKED_REASON_*} and/or {@code BLOCKED_METERED_REASON_*} constants.
+     *
+     * @param blockedReasons Value indicating the reasons for why the network access of an UID is
+     *                       blocked. If the value is equal to {@link #BLOCKED_REASON_NONE}, then
+     *                       it indicates that an app's network access is not blocked.
+     * @param meteredNetwork Value indicating whether the network is metered or not.
+     * @return Whether network access is blocked or not.
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static boolean isUidBlocked(@BlockedReason int blockedReasons, boolean meteredNetwork) {
+        if (blockedReasons == BLOCKED_REASON_NONE) {
+            return false;
+        }
+        final int blockedOnAllNetworksReason = (blockedReasons & ~BLOCKED_METERED_REASON_MASK);
+        if (blockedOnAllNetworksReason != BLOCKED_REASON_NONE) {
+            return true;
+        }
+        if (meteredNetwork) {
+            return blockedReasons != BLOCKED_REASON_NONE;
+        }
+        return false;
+    }
+
+    /**
+     * Returns the {@code string} representation of {@code blockedReasons} argument.
+     *
+     * @param blockedReasons Value indicating the reasons for why the network access of an UID is
+     *                       blocked.
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    @NonNull
+    public static String blockedReasonsToString(@BlockedReason int blockedReasons) {
+        return DebugUtils.flagsToString(NetworkPolicyManager.class, "BLOCKED_", blockedReasons);
+    }
+
+    /**
+     * Register a {@link NetworkPolicyCallback} to listen for changes to network blocked status
+     * of apps.
+     *
+     * Note that when a caller tries to register a new callback, it might replace a previously
+     * registered callback if it is considered equal to the new one, based on the
+     * {@link Object#equals(Object)} check.
+     *
+     * @param executor The {@link Executor} to run the callback on.
+     * @param callback The {@link NetworkPolicyCallback} to be registered.
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY)
+    public void registerNetworkPolicyCallback(@Nullable Executor executor,
+            @NonNull NetworkPolicyCallback callback) {
+        if (callback == null) {
+            throw new NullPointerException("Callback cannot be null.");
+        }
+
+        final NetworkPolicyCallbackProxy callbackProxy = new NetworkPolicyCallbackProxy(
+                executor, callback);
+        registerListener(callbackProxy);
+        mNetworkPolicyCallbackMap.put(callback, callbackProxy);
+    }
+
+    /**
+     * Unregister a previously registered {@link NetworkPolicyCallback}.
+     *
+     * @param callback The {@link NetworkPolicyCallback} to be unregistered.
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY)
+    public void unregisterNetworkPolicyCallback(@NonNull NetworkPolicyCallback callback) {
+        if (callback == null) {
+            throw new NullPointerException("Callback cannot be null.");
+        }
+
+        final NetworkPolicyCallbackProxy callbackProxy = mNetworkPolicyCallbackMap.remove(callback);
+        if (callbackProxy == null) return;
+        unregisterListener(callbackProxy);
+    }
+
+    /**
+     * Interface for the callback to listen for changes to network blocked status of apps.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public interface NetworkPolicyCallback {
+        /**
+         * Called when the reason for why the network access of an UID is blocked changes.
+         *
+         * @param uid The UID for which the blocked status changed.
+         * @param blockedReasons Value indicating the reasons for why the network access of an
+         *                       UID is blocked.
+         * @hide
+         */
+        @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+        default void onUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons) {}
+    }
+
+    /** @hide */
+    public static class NetworkPolicyCallbackProxy extends Listener {
+        private final Executor mExecutor;
+        private final NetworkPolicyCallback mCallback;
+
+        NetworkPolicyCallbackProxy(@Nullable Executor executor,
+                @NonNull NetworkPolicyCallback callback) {
+            mExecutor = executor;
+            mCallback = callback;
+        }
+
+        @Override
+        public void onBlockedReasonChanged(int uid, @BlockedReason int oldBlockedReasons,
+                @BlockedReason int newBlockedReasons) {
+            if (oldBlockedReasons != newBlockedReasons) {
+                dispatchOnUidBlockedReasonChanged(mExecutor, mCallback, uid, newBlockedReasons);
+            }
+        }
+    }
+
+    private static void dispatchOnUidBlockedReasonChanged(@Nullable Executor executor,
+            @NonNull NetworkPolicyCallback callback, int uid, @BlockedReason int blockedReasons) {
+        if (executor == null) {
+            callback.onUidBlockedReasonChanged(uid, blockedReasons);
+        } else {
+            executor.execute(PooledLambda.obtainRunnable(
+                    NetworkPolicyCallback::onUidBlockedReasonChanged,
+                    callback, uid, blockedReasons).recycleOnUse());
+        }
+    }
+
     /** @hide */
     public static class SubscriptionCallback {
         /**
@@ -743,5 +1065,7 @@
         @Override public void onSubscriptionOverride(int subId, int overrideMask,
                 int overrideValue, int[] networkTypes) { }
         @Override public void onSubscriptionPlansChanged(int subId, SubscriptionPlan[] plans) { }
+        @Override public void onBlockedReasonChanged(int uid,
+                int oldBlockedReasons, int newBlockedReasons) { }
     }
 }
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index 9cb76c1..753abea 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -5284,7 +5284,8 @@
          * which network types are allowed for
          * {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_USER},
          * {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_POWER},
-         * {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_CARRIER}.
+         * {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_CARRIER},
+         * {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G}.
          * <P>Type: TEXT </P>
          *
          * @hide
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index fcb9288..bbb1d0ca 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -1577,7 +1577,7 @@
             // default implementation empty
         }
 
-        public void onAllowedNetworkTypesChanged(Map allowedNetworkTypesList) {
+        public void onAllowedNetworkTypesChanged(int reason, long allowedNetworkType) {
             // default implementation empty
         }
 
diff --git a/core/java/android/telephony/TelephonyCallback.java b/core/java/android/telephony/TelephonyCallback.java
index 0402ed0..e49c82c 100644
--- a/core/java/android/telephony/TelephonyCallback.java
+++ b/core/java/android/telephony/TelephonyCallback.java
@@ -544,9 +544,6 @@
     /**
      * Event for changes to allowed network list based on all active subscriptions.
      *
-     * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling
-     * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
-     *
      * @hide
      * @see AllowedNetworkTypesListener#onAllowedNetworkTypesChanged
      */
@@ -1287,30 +1284,34 @@
     public interface AllowedNetworkTypesListener {
         /**
          * Callback invoked when the current allowed network type list has changed on the
-         * registered subscription.
+         * registered subscription for a specified reason.
          * Note, the registered subscription is associated with {@link TelephonyManager} object
-         * on which
-         * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}
+         * on which {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}
          * was called.
          * If this TelephonyManager object was created with
          * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
          * given subscription ID. Otherwise, this callback applies to
          * {@link SubscriptionManager#getDefaultSubscriptionId()}.
          *
-         * @param allowedNetworkTypesList Map associating all allowed network type reasons
-         * ({@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_USER},
-         * {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_POWER},
-         * {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_CARRIER}, and
-         * {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G}) with reason's allowed
-         * network type values.
+         * @param reason an allowed network type reasons.
+         * @see TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_USER
+         * @see TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_POWER
+         * @see TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_CARRIER
+         * @see TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G
+         *
+         * @param allowedNetworkType an allowed network type bitmask value. (for example,
+         * the long bitmask value is {{@link TelephonyManager#NETWORK_TYPE_BITMASK_NR}|
+         * {@link TelephonyManager#NETWORK_TYPE_BITMASK_LTE}})
+         *
          * For example:
-         * map{{TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_USER, long type value},
-         *     {TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_POWER, long type value},
-         *     {TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_CARRIER, long type value},
-         *     {TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G, long type value}}
+         * If the latest allowed network type is changed by user, then the system
+         * notifies the {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_USER} and
+         * long type value}.
          */
         @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-        void onAllowedNetworkTypesChanged(@NonNull Map<Integer, Long> allowedNetworkTypesList);
+        void onAllowedNetworkTypesChanged(
+                @TelephonyManager.AllowedNetworkTypesReason int reason,
+                @TelephonyManager.NetworkTypeBitMask long allowedNetworkType);
     }
 
     /**
@@ -1741,14 +1742,15 @@
                             enabled, reason)));
         }
 
-        public void onAllowedNetworkTypesChanged(Map allowedNetworkTypesList) {
+        public void onAllowedNetworkTypesChanged(int reason, long allowedNetworkType) {
             AllowedNetworkTypesListener listener =
                     (AllowedNetworkTypesListener) mTelephonyCallbackWeakRef.get();
             if (listener == null) return;
 
             Binder.withCleanCallingIdentity(
                     () -> mExecutor.execute(
-                            () -> listener.onAllowedNetworkTypesChanged(allowedNetworkTypesList)));
+                            () -> listener.onAllowedNetworkTypesChanged(reason,
+                                    allowedNetworkType)));
         }
 
         public void onLinkCapacityEstimateChanged(
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index 5a8318f..b111ec3 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -825,16 +825,18 @@
     }
 
     /**
-     * Notify emergency number list changed on certain subscription.
-     *
-     * @param slotIndex for which emergency number list changed. Can be derived from subId except
-     * when subId is invalid.
-     * @param subId for which emergency number list changed.
+     * Notify the allowed network types has changed for a specific subscription and the specific
+     * reason.
+     * @param slotIndex for which allowed network types changed.
+     * @param subId for which allowed network types changed.
+     * @param reason an allowed network type reasons.
+     * @param allowedNetworkType an allowed network type bitmask value.
      */
     public void notifyAllowedNetworkTypesChanged(int slotIndex, int subId,
-            Map<Integer, Long> allowedNetworkTypeList) {
+            int reason, long allowedNetworkType) {
         try {
-            sRegistry.notifyAllowedNetworkTypesChanged(slotIndex, subId, allowedNetworkTypeList);
+            sRegistry.notifyAllowedNetworkTypesChanged(slotIndex, subId, reason,
+                    allowedNetworkType);
         } catch (RemoteException ex) {
             // system process is dead
         }
diff --git a/core/java/com/android/internal/app/OWNERS b/core/java/com/android/internal/app/OWNERS
index 7ade05c..e6c911e 100644
--- a/core/java/com/android/internal/app/OWNERS
+++ b/core/java/com/android/internal/app/OWNERS
@@ -3,6 +3,9 @@
 per-file *Chooser* = file:/packages/SystemUI/OWNERS
 per-file SimpleIconFactory.java = file:/packages/SystemUI/OWNERS
 per-file NetInitiatedActivity.java = file:/location/java/android/location/OWNERS
-per-file IVoice* = file:/core/java/android/service/voice/OWNERS
-per-file *Hotword* = file:/core/java/android/service/voice/OWNERS
 per-file *BatteryStats* = file:/BATTERY_STATS_OWNERS
+
+# Voice Interaction
+per-file *Assist* = file:/core/java/android/service/voice/OWNERS
+per-file *Hotword* = file:/core/java/android/service/voice/OWNERS
+per-file *Voice* = file:/core/java/android/service/voice/OWNERS
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index c220428..5fea76a 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -41,7 +41,6 @@
 import android.os.ZygoteProcess;
 import android.os.storage.StorageManager;
 import android.provider.DeviceConfig;
-import android.security.keystore.AndroidKeyStoreProvider;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
@@ -74,7 +73,6 @@
 import java.io.InputStreamReader;
 import java.security.Provider;
 import java.security.Security;
-import java.util.Optional;
 
 /**
  * Startup class for the zygote process.
@@ -227,17 +225,7 @@
         // AndroidKeyStoreProvider.install() manipulates the list of JCA providers to insert
         // preferred providers. Note this is not done via security.properties as the JCA providers
         // are not on the classpath in the case of, for example, raw dalvikvm runtimes.
-        // TODO b/171305684 This code is used to conditionally enable the installation of the
-        //      Keystore 2.0 provider to enable teams adjusting to Keystore 2.0 at their own
-        //      pace. This code will be removed when all calling code was adjusted to
-        //      Keystore 2.0.
-        Optional<Boolean> keystore2_enabled =
-                android.sysprop.Keystore2Properties.keystore2_enabled();
-        if (keystore2_enabled.isPresent() && keystore2_enabled.get()) {
-            android.security.keystore2.AndroidKeyStoreProvider.install();
-        } else {
-            AndroidKeyStoreProvider.install();
-        }
+        android.security.keystore2.AndroidKeyStoreProvider.install();
         Log.i(TAG, "Installed AndroidKeyStoreProvider in "
                 + (SystemClock.uptimeMillis() - startTime) + "ms.");
         Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
diff --git a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
index 3e7e5a5..b90722c 100644
--- a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -72,6 +72,6 @@
     void onBarringInfoChanged(in BarringInfo barringInfo);
     void onPhysicalChannelConfigChanged(in List<PhysicalChannelConfig> configs);
     void onDataEnabledChanged(boolean enabled, int reason);
-    void onAllowedNetworkTypesChanged(in Map allowedNetworkTypeList);
+    void onAllowedNetworkTypesChanged(in int reason, in long allowedNetworkType);
     void onLinkCapacityEstimateChanged(in List<LinkCapacityEstimate> linkCapacityEstimateList);
 }
diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 23dbf9a..0e35c84 100644
--- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -95,8 +95,7 @@
     void notifyPhysicalChannelConfigForSubscriber(in int subId,
             in List<PhysicalChannelConfig> configs);
     void notifyDataEnabled(in int phoneId, int subId, boolean enabled, int reason);
-    void notifyAllowedNetworkTypesChanged(in int phoneId, in int subId,
-            in Map allowedNetworkTypeList);
+    void notifyAllowedNetworkTypesChanged(in int phoneId, in int subId, in int reason, in long allowedNetworkType);
     void notifyLinkCapacityEstimateChanged(in int phoneId, in int subId,
             in List<LinkCapacityEstimate> linkCapacityEstimateList);
 }
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 065c79b..452f55a 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -1419,6 +1419,42 @@
     return nativeToJavaStatus(status);
 }
 
+static jint android_media_AudioTrack_getStartThresholdInFrames(JNIEnv *env, jobject thiz) {
+    sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+    if (lpTrack == nullptr) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                          "Unable to retrieve AudioTrack pointer for getStartThresholdInFrames()");
+        return (jint)AUDIO_JAVA_ERROR;
+    }
+    const ssize_t result = lpTrack->getStartThresholdInFrames();
+    if (result <= 0) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
+                             "Internal error detected in getStartThresholdInFrames() = %zd",
+                             result);
+        return (jint)AUDIO_JAVA_ERROR;
+    }
+    return (jint)result; // this should be a positive value.
+}
+
+static jint android_media_AudioTrack_setStartThresholdInFrames(JNIEnv *env, jobject thiz,
+                                                               jint startThresholdInFrames) {
+    sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+    if (lpTrack == nullptr) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                          "Unable to retrieve AudioTrack pointer for setStartThresholdInFrames()");
+        return (jint)AUDIO_JAVA_ERROR;
+    }
+    // non-positive values of startThresholdInFrames are not allowed by the Java layer.
+    const ssize_t result = lpTrack->setStartThresholdInFrames(startThresholdInFrames);
+    if (result <= 0) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
+                             "Internal error detected in setStartThresholdInFrames() = %zd",
+                             result);
+        return (jint)AUDIO_JAVA_ERROR;
+    }
+    return (jint)result; // this should be a positive value.
+}
+
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 static const JNINativeMethod gMethods[] = {
@@ -1496,6 +1532,10 @@
          (void *)android_media_AudioTrack_getAudioDescriptionMixLeveldB},
         {"native_set_dual_mono_mode", "(I)I", (void *)android_media_AudioTrack_setDualMonoMode},
         {"native_get_dual_mono_mode", "([I)I", (void *)android_media_AudioTrack_getDualMonoMode},
+        {"native_setStartThresholdInFrames", "(I)I",
+         (void *)android_media_AudioTrack_setStartThresholdInFrames},
+        {"native_getStartThresholdInFrames", "()I",
+         (void *)android_media_AudioTrack_getStartThresholdInFrames},
 };
 
 // field names found in android/media/AudioTrack.java
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 04faebc..6374305 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -52,6 +52,7 @@
 #include <string.h>
 #include <sys/epoll.h>
 #include <sys/errno.h>
+#include <sys/pidfd.h>
 #include <sys/resource.h>
 #include <sys/stat.h>
 #include <sys/syscall.h>
@@ -1290,14 +1291,8 @@
     return removeAllProcessGroups();
 }
 
-// Wrapper function to the syscall pidfd_open, which creates a file
-// descriptor that refers to the process whose PID is specified in pid.
-static inline int sys_pidfd_open(pid_t pid, unsigned int flags) {
-    return syscall(__NR_pidfd_open, pid, flags);
-}
-
 static jint android_os_Process_nativePidFdOpen(JNIEnv* env, jobject, jint pid, jint flags) {
-    int fd = sys_pidfd_open(pid, flags);
+    int fd = pidfd_open(pid, flags);
     if (fd < 0) {
         jniThrowErrnoException(env, "nativePidFdOpen", errno);
         return -1;
diff --git a/core/proto/android/net/networkcapabilities.proto b/core/proto/android/net/networkcapabilities.proto
new file mode 100644
index 0000000..edb6c04
--- /dev/null
+++ b/core/proto/android/net/networkcapabilities.proto
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package android.net;
+
+option java_multiple_files = true;
+
+import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/net/enums.proto";
+
+/**
+ * An android.net.NetworkCapabilities object.
+ */
+message NetworkCapabilitiesProto {
+    option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    repeated Transport transports = 1;
+
+    enum NetCapability {
+        // Indicates this is a network that has the ability to reach the
+        // carrier's MMSC for sending and receiving MMS messages.
+        NET_CAPABILITY_MMS = 0;
+        // Indicates this is a network that has the ability to reach the
+        // carrier's SUPL server, used to retrieve GPS information.
+        NET_CAPABILITY_SUPL = 1;
+        // Indicates this is a network that has the ability to reach the
+        // carrier's DUN or tethering gateway.
+        NET_CAPABILITY_DUN = 2;
+        // Indicates this is a network that has the ability to reach the
+        // carrier's FOTA portal, used for over the air updates.
+        NET_CAPABILITY_FOTA = 3;
+        // Indicates this is a network that has the ability to reach the
+        // carrier's IMS servers, used for network registration and signaling.
+        NET_CAPABILITY_IMS = 4;
+        // Indicates this is a network that has the ability to reach the
+        // carrier's CBS servers, used for carrier specific services.
+        NET_CAPABILITY_CBS = 5;
+        // Indicates this is a network that has the ability to reach a Wi-Fi
+        // direct peer.
+        NET_CAPABILITY_WIFI_P2P = 6;
+        // Indicates this is a network that has the ability to reach a carrier's
+        // Initial Attach servers.
+        NET_CAPABILITY_IA = 7;
+        // Indicates this is a network that has the ability to reach a carrier's
+        // RCS servers, used for Rich Communication Services.
+        NET_CAPABILITY_RCS = 8;
+        // Indicates this is a network that has the ability to reach a carrier's
+        // XCAP servers, used for configuration and control.
+        NET_CAPABILITY_XCAP = 9;
+        // Indicates this is a network that has the ability to reach a carrier's
+        // Emergency IMS servers or other services, used for network signaling
+        // during emergency calls.
+        NET_CAPABILITY_EIMS = 10;
+        // Indicates that this network is unmetered.
+        NET_CAPABILITY_NOT_METERED = 11;
+        // Indicates that this network should be able to reach the internet.
+        NET_CAPABILITY_INTERNET = 12;
+        // Indicates that this network is available for general use. If this is
+        // not set applications should not attempt to communicate on this
+        // network. Note that this is simply informative and not enforcement -
+        // enforcement is handled via other means. Set by default.
+        NET_CAPABILITY_NOT_RESTRICTED = 13;
+        // Indicates that the user has indicated implicit trust of this network.
+        // This generally means it's a sim-selected carrier, a plugged in
+        // ethernet, a paired BT device or a wifi the user asked to connect to.
+        // Untrusted networks are probably limited to unknown wifi AP. Set by
+        // default.
+        NET_CAPABILITY_TRUSTED = 14;
+        // Indicates that this network is not a VPN.  This capability is set by
+        // default and should be explicitly cleared for VPN networks.
+        NET_CAPABILITY_NOT_VPN = 15;
+        // Indicates that connectivity on this network was successfully
+        // validated. For example, for a network with NET_CAPABILITY_INTERNET,
+        // it means that Internet connectivity was successfully detected.
+        NET_CAPABILITY_VALIDATED = 16;
+        // Indicates that this network was found to have a captive portal in
+        // place last time it was probed.
+        NET_CAPABILITY_CAPTIVE_PORTAL = 17;
+        // Indicates that this network is not roaming.
+        NET_CAPABILITY_NOT_ROAMING = 18;
+        // Indicates that this network is available for use by apps, and not a
+        // network that is being kept up in the background to facilitate fast
+        // network switching.
+        NET_CAPABILITY_FOREGROUND = 19;
+    }
+    repeated NetCapability capabilities = 2;
+
+    // Passive link bandwidth. This is a rough guide of the expected peak
+    // bandwidth for the first hop on the given transport.  It is not measured,
+    // but may take into account link parameters (Radio technology, allocated
+    // channels, etc).
+    optional int32 link_up_bandwidth_kbps = 3;
+    optional int32 link_down_bandwidth_kbps = 4;
+
+    optional string network_specifier = 5 [ (.android.privacy).dest = DEST_EXPLICIT ];
+
+    // True if this object specifies a signal strength.
+    optional bool can_report_signal_strength = 6;
+    // This is a signed integer, and higher values indicate better signal. The
+    // exact units are bearer-dependent. For example, Wi-Fi uses RSSI.
+    // Only valid if can_report_signal_strength is true.
+    optional sint32 signal_strength = 7;
+}
diff --git a/core/proto/android/net/networkrequest.proto b/core/proto/android/net/networkrequest.proto
index 0041f19..57b9f71 100644
--- a/core/proto/android/net/networkrequest.proto
+++ b/core/proto/android/net/networkrequest.proto
@@ -20,8 +20,8 @@
 
 option java_multiple_files = true;
 
+import "frameworks/base/core/proto/android/net/networkcapabilities.proto";
 import "frameworks/base/core/proto/android/privacy.proto";
-import "frameworks/proto_logging/stats/enums/net/networkcapabilities.proto";
 
 /**
  * An android.net.NetworkRequest object.
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index e97b1a8..64cf75d 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -55,13 +55,13 @@
 import "frameworks/base/core/proto/android/service/procstats.proto";
 import "frameworks/base/core/proto/android/service/restricted_image.proto";
 import "frameworks/base/core/proto/android/service/sensor_service.proto";
+import "frameworks/base/core/proto/android/service/usb.proto";
 import "frameworks/base/core/proto/android/util/event_log_tags.proto";
 import "frameworks/base/core/proto/android/util/log.proto";
 import "frameworks/base/core/proto/android/util/textdump.proto";
 import "frameworks/base/core/proto/android/privacy.proto";
 import "frameworks/base/core/proto/android/section.proto";
 import "frameworks/base/proto/src/ipconnectivity.proto";
-import "frameworks/proto_logging/stats/enums/service/usb.proto";
 
 package android.os;
 
diff --git a/core/proto/android/service/enums.proto b/core/proto/android/service/enums.proto
deleted file mode 100644
index b64e685..0000000
--- a/core/proto/android/service/enums.proto
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto2";
-package android.service;
-
-option java_outer_classname = "ServiceProtoEnums";
-option java_multiple_files = true;
-
-enum UsbEndPointType {
-    USB_ENDPOINT_TYPE_XFER_CONTROL = 0;
-    USB_ENDPOINT_TYPE_XFER_ISOC = 1;
-    USB_ENDPOINT_TYPE_XFER_BULK = 2;
-    USB_ENDPOINT_TYPE_XFER_INT = 3;
-}
-
-enum UsbEndPointDirection {
-    USB_ENDPOINT_DIR_OUT = 0;
-    USB_ENDPOINT_DIR_IN = 0x80;
-}
-
-enum UsbConnectionRecordMode {
-    USB_CONNECTION_RECORD_MODE_CONNECT = 0;
-    USB_CONNECTION_RECORD_MODE_CONNECT_BADPARSE = 1;
-    USB_CONNECTION_RECORD_MODE_CONNECT_BADDEVICE = 2;
-    USB_CONNECTION_RECORD_MODE_DISCONNECT = -1;
-}
\ No newline at end of file
diff --git a/core/proto/android/service/usb.proto b/core/proto/android/service/usb.proto
new file mode 100644
index 0000000..dd313aa
--- /dev/null
+++ b/core/proto/android/service/usb.proto
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+package android.service.usb;
+
+option java_multiple_files = true;
+option java_outer_classname = "UsbServiceProto";
+
+import "frameworks/base/core/proto/android/content/component_name.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/proto_logging/stats/enums/service/enums.proto";
+
+message UsbServiceDumpProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional UsbDeviceManagerProto device_manager = 1;
+    optional UsbHostManagerProto host_manager = 2;
+    optional UsbPortManagerProto port_manager = 3;
+    optional UsbAlsaManagerProto alsa_manager = 4;
+    optional UsbSettingsManagerProto settings_manager = 5;
+    optional UsbPermissionsManagerProto permissions_manager = 6;
+}
+
+message UsbDeviceManagerProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional UsbHandlerProto handler = 1;
+    optional UsbDebuggingManagerProto debugging_manager = 2;
+}
+
+message UsbHandlerProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    /* Same as android.hardware.usb.gadget.V1_0.GadgetFunction.* */
+    enum Function {
+        FUNCTION_ADB = 1;
+        FUNCTION_ACCESSORY = 2;
+        FUNCTION_MTP = 4;
+        FUNCTION_MIDI = 8;
+        FUNCTION_PTP = 16;
+        FUNCTION_RNDIS = 32;
+        FUNCTION_AUDIO_SOURCE = 64;
+    }
+
+    repeated Function current_functions = 1;
+    optional bool current_functions_applied = 2;
+    repeated Function screen_unlocked_functions = 3;
+    optional bool screen_locked = 4;
+    optional bool connected = 5;
+    optional bool configured = 6;
+    optional UsbAccessoryProto current_accessory = 7;
+    optional bool host_connected = 8;
+    optional bool source_power = 9;
+    optional bool sink_power = 10;
+    optional bool usb_charging = 11;
+    optional bool hide_usb_notification = 12;
+    optional bool audio_accessory_connected = 13;
+    optional bool adb_enabled = 14;
+    optional string kernel_state = 15;
+    optional string kernel_function_list = 16;
+}
+
+message UsbAccessoryProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional string manufacturer = 1;
+    optional string model = 2;
+    // For "classical" USB-accessories the manufacturer bakes this into the
+    // firmware of the device. If an Android phone is configured as accessory, the
+    // app that sets up the accessory side of the connection set this. Either way,
+    // these are part of the detection protocol, and so they cannot be user set or
+    // unique.
+    optional string description = 3;
+    optional string version = 4;
+    optional string uri = 5 [ (android.privacy).dest = DEST_EXPLICIT ];
+    // Non-resettable hardware ID.
+    optional string serial = 6 [ (android.privacy).dest = DEST_LOCAL ];
+}
+
+message UsbDebuggingManagerProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional bool connected_to_adb = 1;
+    // A workstation that connects to the phone for debugging is identified by
+    // this key.
+    optional string last_key_received = 2 [ (android.privacy).dest = DEST_EXPLICIT ];
+    optional string user_keys = 3 [ (android.privacy).dest = DEST_LOCAL ];
+    optional string system_keys = 4 [ (android.privacy).dest = DEST_LOCAL ];
+}
+
+message UsbHostManagerProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional android.content.ComponentNameProto default_usb_host_connection_handler = 1;
+    repeated UsbDeviceProto devices = 2;
+    optional int32 num_connects = 3;
+    repeated UsbConnectionRecordProto connections = 4;
+}
+
+message UsbDeviceProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    // Generic USB name, not user-provided.
+    optional string name = 1;
+    // ID specific to the vendor, not the device.
+    optional int32 vendor_id = 2;
+    // ID of this product type: Each vendor gives each product a unique ID. E.g.
+    // all mice of the same model would have the same ID.
+    optional int32 product_id = 3;
+    optional int32 class = 4;
+    optional int32 subclass = 5;
+    optional int32 protocol = 6;
+    optional string manufacturer_name = 7;
+    optional string product_name = 8;
+    optional string version = 9;
+    // Non-resettable hardware ID.
+    optional string serial_number = 10 [ (android.privacy).dest = DEST_LOCAL ];
+    repeated UsbConfigurationProto configurations = 11;
+}
+
+message UsbConfigurationProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    // A single USB device can have several configurations and the app accessing
+    // the USB device can switch between them. At any time only one can be active.
+    // Each configuration can present completely different interfaces end
+    // endpoints, i.e. a completely different behavior.
+    optional int32 id = 1;
+    // Hardware-defined name, not set by the user.
+    optional string name = 2;
+    optional uint32 attributes = 3;
+    optional int32 max_power = 4;
+    repeated UsbInterfaceProto interfaces = 5;
+}
+
+message UsbInterfaceProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    // Hardware defined. This is the id used by the app to identify the interface.
+    optional int32 id = 1;
+    optional int32 alternate_settings = 2;
+    optional string name = 3;
+    optional int32 class = 4;
+    optional int32 subclass = 5;
+    optional int32 protocol = 6;
+    repeated UsbEndPointProto endpoints = 7;
+}
+
+message UsbEndPointProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional int32 endpoint_number = 1;
+    optional android.service.UsbEndPointDirection direction = 2;
+      // The address of the endpoint. Needed to read and write to the endpoint.
+    optional int32 address = 3;
+    optional android.service.UsbEndPointType type = 4;
+    optional uint32 attributes = 5;
+    optional int32 max_packet_size = 6;
+    optional int32 interval = 7;
+}
+
+message UsbConnectionRecordProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    // usb device's address, e.g. 001/002, nothing about the phone
+    optional string device_address = 1;
+    optional android.service.UsbConnectionRecordMode mode = 2;
+    optional int64 timestamp = 3;
+    optional int32 manufacturer = 4;
+    optional int32 product = 5;
+    optional UsbIsHeadsetProto is_headset = 6;
+}
+
+message UsbIsHeadsetProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional bool in = 1;
+    optional bool out = 2;
+}
+
+message UsbPortManagerProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional bool is_simulation_active = 1;
+    repeated UsbPortInfoProto usb_ports = 2;
+}
+
+message UsbPortInfoProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional UsbPortProto port = 1;
+    optional UsbPortStatusProto status = 2;
+    optional bool can_change_mode = 3;
+    optional bool can_change_power_role = 4;
+    optional bool can_change_data_role = 5;
+    optional int64 connected_at_millis = 6;
+    optional int64 last_connect_duration_millis = 7;
+}
+
+message UsbPortProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    /* Same as android.hardware.usb.V1_1.Constants.PortMode_1_1 */
+    enum Mode {
+        MODE_NONE = 0;
+        MODE_UFP = 1;
+        MODE_DFP = 2;
+        MODE_DRP = 3;
+        MODE_AUDIO_ACCESSORY = 4;
+        MODE_DEBUG_ACCESSORY = 8;
+    }
+
+    // ID of the port. A device (eg: Chromebooks) might have multiple ports.
+    optional string id = 1;
+    repeated Mode supported_modes = 2;
+}
+
+message UsbPortStatusProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    /* Same as android.hardware.usb.V1_0.Constants.PortPowerRole */
+    enum PowerRole {
+        POWER_ROLE_NONE = 0;
+        POWER_ROLE_SOURCE = 1;
+        POWER_ROLE_SINK = 2;
+    }
+
+    /* Same as android.hardware.usb.V1_0.Constants.PortDataRole */
+    enum DataRole {
+        DATA_ROLE_NONE = 0;
+        DATA_ROLE_HOST = 1;
+        DATA_ROLE_DEVICE = 2;
+    }
+
+    optional bool connected = 1;
+    optional UsbPortProto.Mode current_mode = 2;
+    optional PowerRole power_role = 3;
+    optional DataRole data_role = 4;
+    repeated UsbPortStatusRoleCombinationProto role_combinations = 5;
+    optional android.service.ContaminantPresenceStatus contaminant_presence_status = 6;
+}
+
+message UsbPortStatusRoleCombinationProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional UsbPortStatusProto.PowerRole power_role = 1;
+    optional UsbPortStatusProto.DataRole data_role = 2;
+}
+
+message UsbAlsaManagerProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional int32 cards_parser = 1;
+    repeated UsbAlsaDeviceProto alsa_devices = 2;
+    repeated UsbMidiDeviceProto midi_devices = 3;
+}
+
+message UsbAlsaDeviceProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional int32 card = 1;
+    optional int32 device = 2;
+    optional string name = 3;
+    optional bool has_playback = 4;
+    optional bool has_capture = 5;
+    // usb device's address, e.g. 001/002, nothing about the phone
+    optional string address = 6;
+}
+
+message UsbMidiDeviceProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional int32 card = 1;
+    optional int32 device = 2;
+    // usb device's address, e.g. 001/002, nothing about the phone
+    optional string device_address = 3;
+}
+
+message UsbSettingsManagerProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    repeated UsbUserSettingsManagerProto user_settings = 1;
+    repeated UsbProfileGroupSettingsManagerProto profile_group_settings = 2;
+}
+
+message UsbUserSettingsManagerProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional int32 user_id = 1;
+    reserved 2; // previously device_permissions, now unused
+    reserved 3; // previously accessory_permissions, now unused
+    repeated UsbDeviceAttachedActivities device_attached_activities = 4;
+    repeated UsbAccessoryAttachedActivities accessory_attached_activities = 5;
+}
+
+message UsbProfileGroupSettingsManagerProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    // The user id of the personal profile if the device has a work profile.
+    optional int32 parent_user_id = 1;
+    repeated UsbSettingsDevicePreferenceProto device_preferences = 2;
+    repeated UsbSettingsAccessoryPreferenceProto accessory_preferences = 3;
+}
+
+message UsbSettingsDevicePreferenceProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional UsbDeviceFilterProto filter = 1;
+    optional UserPackageProto user_package = 2;
+}
+
+message UsbPermissionsManagerProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    repeated UsbUserPermissionsManagerProto user_permissions = 1;
+}
+
+message UsbUserPermissionsManagerProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional int32 user_id = 1;
+
+    repeated UsbDevicePermissionProto device_permissions = 2;
+    repeated UsbAccessoryPermissionProto accessory_permissions = 3;
+
+    repeated UsbDevicePersistentPermissionProto device_persistent_permissions = 4;
+    repeated UsbAccessoryPersistentPermissionProto accessory_persistent_permissions = 5;
+}
+
+message UsbDevicePermissionProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    // Name of device set by manufacturer
+    // All devices of the same model have the same name
+    optional string device_name = 1;
+    repeated int32 uids = 2;
+}
+
+message UsbAccessoryPermissionProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    // Description of accessory set by manufacturer
+    // All accessories of the same model have the same description
+    optional string accessory_description = 1;
+    repeated int32 uids = 2;
+}
+
+message UsbDevicePersistentPermissionProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional UsbDeviceFilterProto device_filter = 1;
+    repeated UsbUidPermissionProto permission_values = 2;
+}
+
+message UsbAccessoryPersistentPermissionProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional UsbAccessoryFilterProto accessory_filter = 1;
+    repeated UsbUidPermissionProto permission_values = 2;
+}
+
+message UsbUidPermissionProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional int32 uid = 1;
+    optional bool is_granted = 2;
+}
+
+message UsbDeviceFilterProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    // Mirrors the vendor_id of UsbDeviceProto.
+    optional int32 vendor_id = 1;
+    optional int32 product_id = 2;
+    optional int32 class = 3;
+    optional int32 subclass = 4;
+    optional int32 protocol = 5;
+    optional string manufacturer_name = 6;
+    optional string product_name = 7;
+    optional string serial_number = 8 [ (android.privacy).dest = DEST_EXPLICIT ];
+}
+
+message UserPackageProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional int32 user_id = 1;
+    optional string package_name =2;
+}
+
+message UsbSettingsAccessoryPreferenceProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional UsbAccessoryFilterProto filter = 1;
+    optional UserPackageProto user_package = 2;
+}
+
+message UsbAccessoryFilterProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional string manufacturer = 1;
+    optional string model = 2;
+    optional string version = 3;
+}
+
+message UsbDeviceAttachedActivities {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional android.content.ComponentNameProto activity = 1;
+    repeated UsbDeviceFilterProto filters = 2;
+}
+
+message UsbAccessoryAttachedActivities {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    optional android.content.ComponentNameProto activity = 1;
+    repeated UsbAccessoryFilterProto filters = 2;
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 2f352e9..61e7d0a 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -5172,6 +5172,10 @@
     <permission android:name="android.permission.INPUT_CONSUMER"
                 android:protectionLevel="signature" />
 
+    <!-- @hide @SystemApi Allows an application to manage app hibernation state. -->
+    <permission android:name="android.permission.MANAGE_APP_HIBERNATION"
+                android:protectionLevel="signature|installer" />
+
     <!-- Attribution for Country Detector. -->
     <attribution android:tag="CountryDetector" android:label="@string/country_detector"/>
     <!-- Attribution for Location service. -->
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 354d83c..653e690 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -451,6 +451,7 @@
         <permission name="android.permission.MANAGE_SOUND_TRIGGER" />
         <permission name="android.permission.CAPTURE_AUDIO_HOTWORD" />
         <permission name="android.permission.MODIFY_QUIET_MODE" />
+        <permission name="android.permission.MANAGE_APP_HIBERNATION"/>
     </privapp-permissions>
 
     <privapp-permissions package="com.android.statementservice">
diff --git a/keystore/java/android/security/keystore/AttestationUtils.java b/keystore/java/android/security/keystore/AttestationUtils.java
index 11c3689..1eb8541 100644
--- a/keystore/java/android/security/keystore/AttestationUtils.java
+++ b/keystore/java/android/security/keystore/AttestationUtils.java
@@ -287,6 +287,8 @@
             keyStore.deleteEntry(keystoreAlias);
 
             return certificateChain;
+        } catch (SecurityException e) {
+            throw e;
         } catch (Exception e) {
             throw new DeviceIdAttestationException("Unable to perform attestation", e);
         }
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java b/keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java
index d9d5300..9d8a5ef 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreCipherSpiBase.java
@@ -124,7 +124,7 @@
         resetAll();
 
         // Public key operations get diverted to the default provider.
-        if (opmode == Cipher.ENCRYPT_MODE
+        if (!(key instanceof AndroidKeyStorePrivateKey)
                 && (key instanceof PrivateKey || key instanceof PublicKey)) {
             try {
                 mCipher = Cipher.getInstance(getTransform());
@@ -186,7 +186,7 @@
         resetAll();
 
         // Public key operations get diverted to the default provider.
-        if (opmode == Cipher.ENCRYPT_MODE
+        if (!(key instanceof AndroidKeyStorePrivateKey)
                 && (key instanceof PrivateKey || key instanceof PublicKey)) {
             try {
                 mCipher = Cipher.getInstance(getTransform());
@@ -216,7 +216,7 @@
         resetAll();
 
         // Public key operations get diverted to the default provider.
-        if (opmode == Cipher.ENCRYPT_MODE
+        if (!(key instanceof AndroidKeyStorePrivateKey)
                 && (key instanceof PrivateKey || key instanceof PublicKey)) {
             try {
                 mCipher = Cipher.getInstance(getTransform());
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 1b05c3b..b265ebf 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -2077,6 +2077,65 @@
     }
 
     /**
+     * Sets the streaming start threshold for an <code>AudioTrack</code>.
+     * <p> The streaming start threshold is the buffer level that the written audio
+     * data must reach for audio streaming to start after {@link #play()} is called.
+     * <p> For compressed streams, the size of a frame is considered to be exactly one byte.
+     *
+     * @param startThresholdInFrames the desired start threshold.
+     * @return the actual start threshold in frames value. This is
+     *         an integer between 1 to the buffer capacity
+     *         (see {@link #getBufferCapacityInFrames()}),
+     *         and might change if the output sink changes after track creation.
+     * @throws IllegalStateException if the track is not initialized or the
+     *         track transfer mode is not {@link #MODE_STREAM}.
+     * @throws IllegalArgumentException if startThresholdInFrames is not positive.
+     * @see #getStartThresholdInFrames()
+     */
+    public @IntRange(from = 1) int setStartThresholdInFrames(
+            @IntRange (from = 1) int startThresholdInFrames) {
+        if (mState != STATE_INITIALIZED) {
+            throw new IllegalStateException("AudioTrack is not initialized");
+        }
+        if (mDataLoadMode != MODE_STREAM) {
+            throw new IllegalStateException("AudioTrack must be a streaming track");
+        }
+        if (startThresholdInFrames < 1) {
+            throw new IllegalArgumentException("startThresholdInFrames "
+                    + startThresholdInFrames + " must be positive");
+        }
+        return native_setStartThresholdInFrames(startThresholdInFrames);
+    }
+
+    /**
+     * Returns the streaming start threshold of the <code>AudioTrack</code>.
+     * <p> The streaming start threshold is the buffer level that the written audio
+     * data must reach for audio streaming to start after {@link #play()} is called.
+     * When an <code>AudioTrack</code> is created, the streaming start threshold
+     * is the buffer capacity in frames. If the buffer size in frames is reduced
+     * by {@link #setBufferSizeInFrames(int)} to a value smaller than the start threshold
+     * then that value will be used instead for the streaming start threshold.
+     * <p> For compressed streams, the size of a frame is considered to be exactly one byte.
+     *
+     * @return the current start threshold in frames value. This is
+     *         an integer between 1 to the buffer capacity
+     *         (see {@link #getBufferCapacityInFrames()}),
+     *         and might change if the  output sink changes after track creation.
+     * @throws IllegalStateException if the track is not initialized or the
+     *         track is not {@link #MODE_STREAM}.
+     * @see #setStartThresholdInFrames(int)
+     */
+    public @IntRange (from = 1) int getStartThresholdInFrames() {
+        if (mState != STATE_INITIALIZED) {
+            throw new IllegalStateException("AudioTrack is not initialized");
+        }
+        if (mDataLoadMode != MODE_STREAM) {
+            throw new IllegalStateException("AudioTrack must be a streaming track");
+        }
+        return native_getStartThresholdInFrames();
+    }
+
+    /**
      *  Returns the frame count of the native <code>AudioTrack</code> buffer.
      *  @return current size in frames of the <code>AudioTrack</code> buffer.
      *  @throws IllegalStateException
@@ -4179,6 +4238,8 @@
     private native int native_get_audio_description_mix_level_db(float[] level);
     private native int native_set_dual_mono_mode(int dualMonoMode);
     private native int native_get_dual_mono_mode(int[] dualMonoMode);
+    private native int native_setStartThresholdInFrames(int startThresholdInFrames);
+    private native int native_getStartThresholdInFrames();
 
     //---------------------------------------------------------
     // Utility methods
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index f65dfdd..517e192 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -19,6 +19,7 @@
     name: "libmedia_jni",
 
     defaults: ["libcodec2-internal-defaults"],
+    min_sdk_version: "",
 
     srcs: [
         "android_media_ImageWriter.cpp",
diff --git a/packages/Connectivity/TEST_MAPPING b/packages/Connectivity/TEST_MAPPING
new file mode 100644
index 0000000..94f9232
--- /dev/null
+++ b/packages/Connectivity/TEST_MAPPING
@@ -0,0 +1,19 @@
+{
+  "imports": [
+    {
+      "path": "frameworks/base/core/java/android/net"
+    },
+    {
+      "path": "packages/modules/NetworkStack"
+    },
+    {
+      "path": "packages/modules/CaptivePortalLogin"
+    },
+    {
+      "path": "packages/modules/Connectivity"
+    },
+    {
+      "path": "packages/modules/Connectivity/Tethering"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/Connectivity/framework/Android.bp b/packages/Connectivity/framework/Android.bp
index 86433e1..017ff51 100644
--- a/packages/Connectivity/framework/Android.bp
+++ b/packages/Connectivity/framework/Android.bp
@@ -23,6 +23,25 @@
     default_applicable_licenses: ["frameworks_base_license"],
 }
 
+java_library {
+    name: "framework-connectivity-protos",
+    proto: {
+        type: "nano",
+    },
+    srcs: [
+        // TODO: consider moving relevant .proto files directly to the module directory
+        ":framework-javastream-protos",
+    ],
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.tethering",
+    ],
+    jarjar_rules: "jarjar-rules-proto.txt",
+    visibility: [
+        "//visibility:private",
+    ],
+}
+
 filegroup {
     name: "framework-connectivity-internal-sources",
     srcs: [
@@ -111,6 +130,7 @@
         "ServiceConnectivityResources",
     ],
     static_libs: [
+        "framework-connectivity-protos",
         "net-utils-device-common",
     ],
     jarjar_rules: "jarjar-rules.txt",
diff --git a/packages/Connectivity/framework/api/current.txt b/packages/Connectivity/framework/api/current.txt
index f22d4b7..e415e01 100644
--- a/packages/Connectivity/framework/api/current.txt
+++ b/packages/Connectivity/framework/api/current.txt
@@ -291,6 +291,7 @@
     ctor public NetworkCapabilities();
     ctor public NetworkCapabilities(android.net.NetworkCapabilities);
     method public int describeContents();
+    method @NonNull public int[] getCapabilities();
     method public int getLinkDownstreamBandwidthKbps();
     method public int getLinkUpstreamBandwidthKbps();
     method @Nullable public android.net.NetworkSpecifier getNetworkSpecifier();
diff --git a/packages/Connectivity/framework/api/module-lib-current.txt b/packages/Connectivity/framework/api/module-lib-current.txt
index 7a91f64..aa7a0ac 100644
--- a/packages/Connectivity/framework/api/module-lib-current.txt
+++ b/packages/Connectivity/framework/api/module-lib-current.txt
@@ -19,6 +19,7 @@
     method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setGlobalProxy(@Nullable android.net.ProxyInfo);
     method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setProfileNetworkPreference(@NonNull android.os.UserHandle, int, @Nullable java.util.concurrent.Executor, @Nullable Runnable);
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_TEST_NETWORKS, android.Manifest.permission.NETWORK_STACK}) public void simulateDataStall(int, long, @NonNull android.net.Network, @NonNull android.os.PersistableBundle);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void startCaptivePortalApp(@NonNull android.net.Network);
     method public void systemReady();
     field public static final String PRIVATE_DNS_MODE_OFF = "off";
     field public static final String PRIVATE_DNS_MODE_OPPORTUNISTIC = "opportunistic";
@@ -36,9 +37,24 @@
   }
 
   public final class NetworkCapabilities implements android.os.Parcelable {
+    ctor public NetworkCapabilities(@Nullable android.net.NetworkCapabilities, long);
+    method @Nullable public java.util.Set<android.util.Range<java.lang.Integer>> getUids();
+    field public static final long REDACT_ALL = -1L; // 0xffffffffffffffffL
+    field public static final long REDACT_FOR_ACCESS_FINE_LOCATION = 1L; // 0x1L
+    field public static final long REDACT_FOR_LOCAL_MAC_ADDRESS = 2L; // 0x2L
+    field public static final long REDACT_FOR_NETWORK_SETTINGS = 4L; // 0x4L
+    field public static final long REDACT_NONE = 0L; // 0x0L
     field public static final int TRANSPORT_TEST = 7; // 0x7
   }
 
+  public static final class NetworkCapabilities.Builder {
+    method @NonNull public android.net.NetworkCapabilities.Builder setUids(@Nullable java.util.Set<android.util.Range<java.lang.Integer>>);
+  }
+
+  public static class NetworkRequest.Builder {
+    method @NonNull public android.net.NetworkRequest.Builder setUids(@Nullable java.util.Set<android.util.Range<java.lang.Integer>>);
+  }
+
   public class ParseException extends java.lang.RuntimeException {
     ctor public ParseException(@NonNull String);
     ctor public ParseException(@NonNull String, @NonNull Throwable);
@@ -79,6 +95,11 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.net.TestNetworkSpecifier> CREATOR;
   }
 
+  public interface TransportInfo {
+    method public default long getApplicableRedactions();
+    method @NonNull public default android.net.TransportInfo makeCopy(long);
+  }
+
   public final class VpnTransportInfo implements android.os.Parcelable android.net.TransportInfo {
     ctor public VpnTransportInfo(int);
     method public int describeContents();
diff --git a/packages/Connectivity/framework/api/system-current.txt b/packages/Connectivity/framework/api/system-current.txt
index 8845225..703fca4 100644
--- a/packages/Connectivity/framework/api/system-current.txt
+++ b/packages/Connectivity/framework/api/system-current.txt
@@ -52,7 +52,7 @@
     method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void getLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEntitlementResultListener);
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported();
     method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_FACTORY}) public int registerNetworkProvider(@NonNull android.net.NetworkProvider);
-    method public void registerQosCallback(@NonNull android.net.QosSocketInfo, @NonNull android.net.QosCallback, @NonNull java.util.concurrent.Executor);
+    method public void registerQosCallback(@NonNull android.net.QosSocketInfo, @NonNull java.util.concurrent.Executor, @NonNull android.net.QosCallback);
     method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEventCallback);
     method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void requestNetwork(@NonNull android.net.NetworkRequest, int, int, @NonNull android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback);
     method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_AIRPLANE_MODE, android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void setAirplaneMode(boolean);
@@ -261,7 +261,6 @@
   }
 
   public final class NetworkCapabilities implements android.os.Parcelable {
-    ctor public NetworkCapabilities(@Nullable android.net.NetworkCapabilities, boolean);
     method @NonNull public int[] getAdministratorUids();
     method @Nullable public String getSsid();
     method @NonNull public int[] getTransportTypes();
@@ -435,11 +434,6 @@
     field public final int tcpWindowScale;
   }
 
-  public interface TransportInfo {
-    method public default boolean hasLocationSensitiveFields();
-    method @NonNull public default android.net.TransportInfo makeCopy(boolean);
-  }
-
 }
 
 package android.net.apf {
diff --git a/packages/Connectivity/framework/jarjar-rules-proto.txt b/packages/Connectivity/framework/jarjar-rules-proto.txt
new file mode 100644
index 0000000..37b4dec1
--- /dev/null
+++ b/packages/Connectivity/framework/jarjar-rules-proto.txt
@@ -0,0 +1,3 @@
+keep android.net.NetworkCapabilitiesProto
+keep android.net.NetworkProto
+keep android.net.NetworkRequestProto
diff --git a/packages/Connectivity/framework/jarjar-rules.txt b/packages/Connectivity/framework/jarjar-rules.txt
index 381a4ac..0959840 100644
--- a/packages/Connectivity/framework/jarjar-rules.txt
+++ b/packages/Connectivity/framework/jarjar-rules.txt
@@ -5,3 +5,6 @@
 zap com.android.net.module.annotation.**
 zap com.android.internal.annotations.**
 
+rule android.net.NetworkCapabilitiesProto* android.net.connectivity.proto.NetworkCapabilitiesProto@1
+rule android.net.NetworkProto* android.net.connectivity.proto.NetworkProto@1
+rule android.net.NetworkRequestProto* android.net.connectivity.proto.NetworkRequestProto@1
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityDiagnosticsManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityDiagnosticsManager.java
index 5234494..3598ebc 100644
--- a/packages/Connectivity/framework/src/android/net/ConnectivityDiagnosticsManager.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityDiagnosticsManager.java
@@ -28,7 +28,6 @@
 import android.os.RemoteException;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.Preconditions;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -70,8 +69,8 @@
 
     /** @hide */
     public ConnectivityDiagnosticsManager(Context context, IConnectivityManager service) {
-        mContext = Preconditions.checkNotNull(context, "missing context");
-        mService = Preconditions.checkNotNull(service, "missing IConnectivityManager");
+        mContext = Objects.requireNonNull(context, "missing context");
+        mService = Objects.requireNonNull(service, "missing IConnectivityManager");
     }
 
     /** @hide */
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
index f748159..30ccb20 100644
--- a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
@@ -62,7 +62,6 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
-import android.os.ServiceManager;
 import android.os.ServiceSpecificException;
 import android.os.UserHandle;
 import android.provider.Settings;
@@ -74,9 +73,7 @@
 import android.util.Range;
 import android.util.SparseIntArray;
 
-import com.android.connectivity.aidl.INetworkAgent;
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.Preconditions;
 
 import libcore.net.event.NetworkEventDispatcher;
 
@@ -842,7 +839,6 @@
 
     private final Context mContext;
 
-    private INetworkPolicyManager mNPManager;
     private final TetheringManager mTetheringManager;
 
     /**
@@ -1777,7 +1773,9 @@
         // Map from type to transports.
         final int NOT_FOUND = -1;
         final int transport = sLegacyTypeToTransport.get(type, NOT_FOUND);
-        Preconditions.checkArgument(transport != NOT_FOUND, "unknown legacy type: " + type);
+        if (transport == NOT_FOUND) {
+            throw new IllegalArgumentException("unknown legacy type: " + type);
+        }
         nc.addTransportType(transport);
 
         // Map from type to capabilities.
@@ -1882,8 +1880,8 @@
         }
 
         private PacketKeepalive(Network network, PacketKeepaliveCallback callback) {
-            Preconditions.checkNotNull(network, "network cannot be null");
-            Preconditions.checkNotNull(callback, "callback cannot be null");
+            Objects.requireNonNull(network, "network cannot be null");
+            Objects.requireNonNull(callback, "callback cannot be null");
             mNetwork = network;
             mExecutor = Executors.newSingleThreadExecutor();
             mCallback = new ISocketKeepaliveCallback.Stub() {
@@ -2258,7 +2256,9 @@
      */
     public void removeDefaultNetworkActiveListener(@NonNull OnNetworkActiveListener l) {
         INetworkActivityListener rl = mNetworkActivityListeners.get(l);
-        Preconditions.checkArgument(rl != null, "Listener was not registered.");
+        if (rl == null) {
+            throw new IllegalArgumentException("Listener was not registered.");
+        }
         try {
             mService.registerNetworkActivityListener(rl);
         } catch (RemoteException e) {
@@ -2286,8 +2286,8 @@
      * {@hide}
      */
     public ConnectivityManager(Context context, IConnectivityManager service) {
-        mContext = Preconditions.checkNotNull(context, "missing context");
-        mService = Preconditions.checkNotNull(service, "missing IConnectivityManager");
+        mContext = Objects.requireNonNull(context, "missing context");
+        mService = Objects.requireNonNull(service, "missing IConnectivityManager");
         mTetheringManager = (TetheringManager) mContext.getSystemService(Context.TETHERING_SERVICE);
         sInstance = this;
     }
@@ -2554,7 +2554,7 @@
     @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
     public void startTethering(int type, boolean showProvisioningUi,
             final OnStartTetheringCallback callback, Handler handler) {
-        Preconditions.checkNotNull(callback, "OnStartTetheringCallback cannot be null.");
+        Objects.requireNonNull(callback, "OnStartTetheringCallback cannot be null.");
 
         final Executor executor = new Executor() {
             @Override
@@ -2647,7 +2647,7 @@
     public void registerTetheringEventCallback(
             @NonNull @CallbackExecutor Executor executor,
             @NonNull final OnTetheringEventCallback callback) {
-        Preconditions.checkNotNull(callback, "OnTetheringEventCallback cannot be null.");
+        Objects.requireNonNull(callback, "OnTetheringEventCallback cannot be null.");
 
         final TetheringEventCallback tetherCallback =
                 new TetheringEventCallback() {
@@ -2945,7 +2945,7 @@
     public void getLatestTetheringEntitlementResult(int type, boolean showEntitlementUi,
             @NonNull @CallbackExecutor Executor executor,
             @NonNull final OnTetheringEntitlementResultListener listener) {
-        Preconditions.checkNotNull(listener, "TetheringEntitlementResultListener cannot be null.");
+        Objects.requireNonNull(listener, "TetheringEntitlementResultListener cannot be null.");
         ResultReceiver wrappedListener = new ResultReceiver(null) {
             @Override
             protected void onReceiveResult(int resultCode, Bundle resultData) {
@@ -3318,7 +3318,9 @@
         }
 
         public NetworkCallback(@Flag int flags) {
-            Preconditions.checkArgument((flags & VALID_FLAGS) == flags);
+            if ((flags & VALID_FLAGS) != flags) {
+                throw new IllegalArgumentException("Invalid flags");
+            }
             mFlags = flags;
         }
 
@@ -3604,7 +3606,7 @@
         }
 
         CallbackHandler(Handler handler) {
-            this(Preconditions.checkNotNull(handler, "Handler cannot be null.").getLooper());
+            this(Objects.requireNonNull(handler, "Handler cannot be null.").getLooper());
         }
 
         @Override
@@ -3702,9 +3704,9 @@
             int timeoutMs, NetworkRequest.Type reqType, int legacyType, CallbackHandler handler) {
         printStackTrace();
         checkCallbackNotNull(callback);
-        Preconditions.checkArgument(
-                reqType == TRACK_DEFAULT || reqType == TRACK_SYSTEM_DEFAULT || need != null,
-                "null NetworkCapabilities");
+        if (reqType != TRACK_DEFAULT && reqType != TRACK_SYSTEM_DEFAULT && need == null) {
+            throw new IllegalArgumentException("null NetworkCapabilities");
+        }
         final NetworkRequest request;
         final String callingPackageName = mContext.getOpPackageName();
         try {
@@ -4051,15 +4053,17 @@
     }
 
     private static void checkPendingIntentNotNull(PendingIntent intent) {
-        Preconditions.checkNotNull(intent, "PendingIntent cannot be null.");
+        Objects.requireNonNull(intent, "PendingIntent cannot be null.");
     }
 
     private static void checkCallbackNotNull(NetworkCallback callback) {
-        Preconditions.checkNotNull(callback, "null NetworkCallback");
+        Objects.requireNonNull(callback, "null NetworkCallback");
     }
 
     private static void checkTimeout(int timeoutMs) {
-        Preconditions.checkArgumentPositive(timeoutMs, "timeoutMs must be strictly positive.");
+        if (timeoutMs <= 0) {
+            throw new IllegalArgumentException("timeoutMs must be strictly positive.");
+        }
     }
 
     /**
@@ -4339,8 +4343,9 @@
         // Find all requests associated to this callback and stop callback triggers immediately.
         // Callback is reusable immediately. http://b/20701525, http://b/35921499.
         synchronized (sCallbacks) {
-            Preconditions.checkArgument(networkCallback.networkRequest != null,
-                    "NetworkCallback was not registered");
+            if (networkCallback.networkRequest == null) {
+                throw new IllegalArgumentException("NetworkCallback was not registered");
+            }
             if (networkCallback.networkRequest == ALREADY_UNREGISTERED) {
                 Log.d(TAG, "NetworkCallback was already unregistered");
                 return;
@@ -4461,12 +4466,20 @@
     /**
      * Requests that the system open the captive portal app on the specified network.
      *
+     * <p>This is to be used on networks where a captive portal was detected, as per
+     * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}.
+     *
      * @param network The network to log into.
      *
      * @hide
      */
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void startCaptivePortalApp(Network network) {
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.NETWORK_SETTINGS,
+            android.Manifest.permission.NETWORK_STACK,
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
+    })
+    public void startCaptivePortalApp(@NonNull Network network) {
         try {
             mService.startCaptivePortalApp(network);
         } catch (RemoteException e) {
@@ -4786,17 +4799,6 @@
     public @interface RestrictBackgroundStatus {
     }
 
-    private INetworkPolicyManager getNetworkPolicyManager() {
-        synchronized (this) {
-            if (mNPManager != null) {
-                return mNPManager;
-            }
-            mNPManager = INetworkPolicyManager.Stub.asInterface(ServiceManager
-                    .getService(Context.NETWORK_POLICY_SERVICE));
-            return mNPManager;
-        }
-    }
-
     /**
      * Determines if the calling application is subject to metered network restrictions while
      * running on background.
@@ -4807,7 +4809,7 @@
      */
     public @RestrictBackgroundStatus int getRestrictBackgroundStatus() {
         try {
-            return getNetworkPolicyManager().getRestrictBackgroundByCaller();
+            return mService.getRestrictBackgroundStatusByCaller();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -4937,20 +4939,20 @@
      * {@link QosCallback#onError(QosCallbackException)}.  see: {@link QosCallbackException}.
      *
      * @param socketInfo the socket information used to match QoS events
-     * @param callback receives qos events that satisfy socketInfo
      * @param executor The executor on which the callback will be invoked. The provided
      *                 {@link Executor} must run callback sequentially, otherwise the order of
-     *                 callbacks cannot be guaranteed.
+     *                 callbacks cannot be guaranteed.onQosCallbackRegistered
+     * @param callback receives qos events that satisfy socketInfo
      *
      * @hide
      */
     @SystemApi
     public void registerQosCallback(@NonNull final QosSocketInfo socketInfo,
-            @NonNull final QosCallback callback,
-            @CallbackExecutor @NonNull final Executor executor) {
+            @CallbackExecutor @NonNull final Executor executor,
+            @NonNull final QosCallback callback) {
         Objects.requireNonNull(socketInfo, "socketInfo must be non-null");
-        Objects.requireNonNull(callback, "callback must be non-null");
         Objects.requireNonNull(executor, "executor must be non-null");
+        Objects.requireNonNull(callback, "callback must be non-null");
 
         try {
             synchronized (mQosCallbackConnections) {
diff --git a/services/core/java/com/android/server/connectivity/ConnectivityResources.java b/packages/Connectivity/framework/src/android/net/ConnectivityResources.java
similarity index 69%
rename from services/core/java/com/android/server/connectivity/ConnectivityResources.java
rename to packages/Connectivity/framework/src/android/net/ConnectivityResources.java
index 45cf21e..18f0de0 100644
--- a/services/core/java/com/android/server/connectivity/ConnectivityResources.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityResources.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.connectivity;
+package android.net;
 
 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
 
@@ -27,13 +27,14 @@
 import android.content.res.Resources;
 import android.util.Log;
 
-import com.android.server.ConnectivityService;
+import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.List;
 
 /**
- * Utility to obtain the {@link ConnectivityService} {@link Resources}, in the
+ * Utility to obtain the {@link com.android.server.ConnectivityService} {@link Resources}, in the
  * ServiceConnectivityResources APK.
+ * @hide
  */
 public class ConnectivityResources {
     private static final String RESOURCES_APK_INTENT =
@@ -44,18 +45,35 @@
     private final Context mContext;
 
     @Nullable
-    private Resources mResources = null;
+    private Context mResourcesContext = null;
+
+    @Nullable
+    private static Context sTestResourcesContext = null;
 
     public ConnectivityResources(Context context) {
         mContext = context;
     }
 
     /**
-     * Get the {@link Resources} of the ServiceConnectivityResources APK.
+     * Convenience method to mock all resources for the duration of a test.
+     *
+     * Call with a null context to reset after the test.
      */
-    public synchronized Resources get() {
-        if (mResources != null) {
-            return mResources;
+    @VisibleForTesting
+    public static void setResourcesContextForTest(@Nullable Context testContext) {
+        sTestResourcesContext = testContext;
+    }
+
+    /**
+     * Get the {@link Context} of the resources package.
+     */
+    public synchronized Context getResourcesContext() {
+        if (sTestResourcesContext != null) {
+            return sTestResourcesContext;
+        }
+
+        if (mResourcesContext != null) {
+            return mResourcesContext;
         }
 
         final List<ResolveInfo> pkgs = mContext.getPackageManager()
@@ -77,7 +95,14 @@
             throw new IllegalStateException("Resolved package not found", e);
         }
 
-        mResources = pkgContext.getResources();
-        return mResources;
+        mResourcesContext = pkgContext;
+        return pkgContext;
+    }
+
+    /**
+     * Get the {@link Resources} of the ServiceConnectivityResources APK.
+     */
+    public Resources get() {
+        return getResourcesContext().getResources();
     }
 }
diff --git a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
index d83cc16..3300fa8 100644
--- a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
+++ b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
@@ -20,6 +20,7 @@
 import android.net.ConnectionInfo;
 import android.net.ConnectivityDiagnosticsManager;
 import android.net.IConnectivityDiagnosticsCallback;
+import android.net.INetworkAgent;
 import android.net.IOnCompleteListener;
 import android.net.INetworkActivityListener;
 import android.net.IQosCallback;
@@ -45,8 +46,6 @@
 import android.os.ResultReceiver;
 import android.os.UserHandle;
 
-import com.android.connectivity.aidl.INetworkAgent;
-
 /**
  * Interface that answers queries about, and allows changing, the
  * state of network connectivity.
@@ -220,4 +219,6 @@
 
     void setProfileNetworkPreference(in UserHandle profile, int preference,
             in IOnCompleteListener listener);
+
+    int getRestrictBackgroundStatusByCaller();
 }
diff --git a/packages/Connectivity/framework/src/com/android/connectivity/aidl/INetworkAgent.aidl b/packages/Connectivity/framework/src/android/net/INetworkAgent.aidl
similarity index 94%
rename from packages/Connectivity/framework/src/com/android/connectivity/aidl/INetworkAgent.aidl
rename to packages/Connectivity/framework/src/android/net/INetworkAgent.aidl
index 64b5567..1f66e18 100644
--- a/packages/Connectivity/framework/src/com/android/connectivity/aidl/INetworkAgent.aidl
+++ b/packages/Connectivity/framework/src/android/net/INetworkAgent.aidl
@@ -13,13 +13,13 @@
  * See the License for the specific language governing perNmissions and
  * limitations under the License.
  */
-package com.android.connectivity.aidl;
+package android.net;
 
 import android.net.NattKeepalivePacketData;
 import android.net.QosFilterParcelable;
 import android.net.TcpKeepalivePacketData;
 
-import com.android.connectivity.aidl.INetworkAgentRegistry;
+import android.net.INetworkAgentRegistry;
 
 /**
  * Interface to notify NetworkAgent of connectivity events.
diff --git a/packages/Connectivity/framework/src/com/android/connectivity/aidl/INetworkAgentRegistry.aidl b/packages/Connectivity/framework/src/android/net/INetworkAgentRegistry.aidl
similarity index 97%
rename from packages/Connectivity/framework/src/com/android/connectivity/aidl/INetworkAgentRegistry.aidl
rename to packages/Connectivity/framework/src/android/net/INetworkAgentRegistry.aidl
index 18d26a7..c5464d3 100644
--- a/packages/Connectivity/framework/src/com/android/connectivity/aidl/INetworkAgentRegistry.aidl
+++ b/packages/Connectivity/framework/src/android/net/INetworkAgentRegistry.aidl
@@ -13,7 +13,7 @@
  * See the License for the specific language governing perNmissions and
  * limitations under the License.
  */
-package com.android.connectivity.aidl;
+package android.net;
 
 import android.net.LinkProperties;
 import android.net.Network;
diff --git a/packages/Connectivity/framework/src/android/net/InetAddressCompat.java b/packages/Connectivity/framework/src/android/net/InetAddressCompat.java
index 8404441..6b7e75c 100644
--- a/packages/Connectivity/framework/src/android/net/InetAddressCompat.java
+++ b/packages/Connectivity/framework/src/android/net/InetAddressCompat.java
@@ -41,7 +41,12 @@
     public static void clearDnsCache() {
         try {
             InetAddress.class.getMethod("clearDnsCache").invoke(null);
-        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
+        } catch (InvocationTargetException e) {
+            if (e.getCause() instanceof RuntimeException) {
+                throw (RuntimeException) e.getCause();
+            }
+            throw new IllegalStateException("Unknown InvocationTargetException", e.getCause());
+        } catch (IllegalAccessException | NoSuchMethodException e) {
             Log.wtf(InetAddressCompat.class.getSimpleName(), "Error clearing DNS cache", e);
         }
     }
@@ -51,13 +56,7 @@
      */
     public static InetAddress[] getAllByNameOnNet(String host, int netId) throws
             UnknownHostException {
-        try {
-            return (InetAddress[]) InetAddress.class.getMethod("getAllByNameOnNet",
-                    String.class, int.class).invoke(null, host, netId);
-        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
-            Log.wtf(InetAddressCompat.class.getSimpleName(), "Error calling getAllByNameOnNet", e);
-            throw new IllegalStateException("Error querying via getAllNameOnNet", e);
-        }
+        return (InetAddress[]) callGetByNameMethod("getAllByNameOnNet", host, netId);
     }
 
     /**
@@ -65,12 +64,25 @@
      */
     public static InetAddress getByNameOnNet(String host, int netId) throws
             UnknownHostException {
+        return (InetAddress) callGetByNameMethod("getByNameOnNet", host, netId);
+    }
+
+    private static Object callGetByNameMethod(String method, String host, int netId)
+            throws UnknownHostException {
         try {
-            return (InetAddress) InetAddress.class.getMethod("getByNameOnNet",
-                    String.class, int.class).invoke(null, host, netId);
-        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
-            Log.wtf(InetAddressCompat.class.getSimpleName(), "Error calling getAllByNameOnNet", e);
-            throw new IllegalStateException("Error querying via getByNameOnNet", e);
+            return InetAddress.class.getMethod(method, String.class, int.class)
+                    .invoke(null, host, netId);
+        } catch (InvocationTargetException e) {
+            if (e.getCause() instanceof UnknownHostException) {
+                throw (UnknownHostException) e.getCause();
+            }
+            if (e.getCause() instanceof RuntimeException) {
+                throw (RuntimeException) e.getCause();
+            }
+            throw new IllegalStateException("Unknown InvocationTargetException", e.getCause());
+        } catch (IllegalAccessException | NoSuchMethodException e) {
+            Log.wtf(InetAddressCompat.class.getSimpleName(), "Error calling " + method, e);
+            throw new IllegalStateException("Error querying via " + method, e);
         }
     }
 }
diff --git a/packages/Connectivity/framework/src/android/net/MacAddress.java b/packages/Connectivity/framework/src/android/net/MacAddress.java
index c83c23a..26a504a 100644
--- a/packages/Connectivity/framework/src/android/net/MacAddress.java
+++ b/packages/Connectivity/framework/src/android/net/MacAddress.java
@@ -25,7 +25,6 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
-import com.android.internal.util.Preconditions;
 import com.android.net.module.util.MacAddressUtils;
 
 import java.lang.annotation.Retention;
@@ -34,6 +33,7 @@
 import java.net.UnknownHostException;
 import java.security.SecureRandom;
 import java.util.Arrays;
+import java.util.Objects;
 
 /**
  * Representation of a MAC address.
@@ -229,7 +229,7 @@
      * @hide
      */
     public static @NonNull byte[] byteAddrFromStringAddr(String addr) {
-        Preconditions.checkNotNull(addr);
+        Objects.requireNonNull(addr);
         String[] parts = addr.split(":");
         if (parts.length != ETHER_ADDR_LEN) {
             throw new IllegalArgumentException(addr + " was not a valid MAC address");
@@ -275,7 +275,7 @@
     // Internal conversion function equivalent to longAddrFromByteAddr(byteAddrFromStringAddr(addr))
     // that avoids the allocation of an intermediary byte[].
     private static long longAddrFromStringAddr(String addr) {
-        Preconditions.checkNotNull(addr);
+        Objects.requireNonNull(addr);
         String[] parts = addr.split(":");
         if (parts.length != ETHER_ADDR_LEN) {
             throw new IllegalArgumentException(addr + " was not a valid MAC address");
@@ -364,8 +364,8 @@
      *
      */
     public boolean matches(@NonNull MacAddress baseAddress, @NonNull MacAddress mask) {
-        Preconditions.checkNotNull(baseAddress);
-        Preconditions.checkNotNull(mask);
+        Objects.requireNonNull(baseAddress);
+        Objects.requireNonNull(mask);
         return (mAddr & mask.mAddr) == (baseAddress.mAddr & mask.mAddr);
     }
 
diff --git a/packages/Connectivity/framework/src/android/net/NetworkAgent.java b/packages/Connectivity/framework/src/android/net/NetworkAgent.java
index a127c6f..3863ed1 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkAgent.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkAgent.java
@@ -34,8 +34,6 @@
 import android.telephony.data.EpsBearerQosSessionAttributes;
 import android.util.Log;
 
-import com.android.connectivity.aidl.INetworkAgent;
-import com.android.connectivity.aidl.INetworkAgentRegistry;
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.lang.annotation.Retention;
@@ -436,7 +434,7 @@
         }
 
         mInitialConfiguration = new InitialConfiguration(context,
-                new NetworkCapabilities(nc, /* parcelLocationSensitiveFields */ true),
+                new NetworkCapabilities(nc, NetworkCapabilities.REDACT_NONE),
                 new LinkProperties(lp), score, config, ni);
     }
 
@@ -880,8 +878,7 @@
         mBandwidthUpdatePending.set(false);
         mLastBwRefreshTime = System.currentTimeMillis();
         final NetworkCapabilities nc =
-                new NetworkCapabilities(networkCapabilities,
-                        /* parcelLocationSensitiveFields */ true);
+                new NetworkCapabilities(networkCapabilities, NetworkCapabilities.REDACT_NONE);
         queueOrSendMessage(reg -> reg.sendNetworkCapabilities(nc));
     }
 
diff --git a/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java b/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java
index 664c265..5e50a64 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java
@@ -50,7 +50,8 @@
      * ap in the wifi settings to trigger a connection is explicit.  A 3rd party app asking to
      * connect to a particular access point is also explicit, though this may change in the future
      * as we want apps to use the multinetwork apis.
-     *
+     * TODO : this is a bad name, because it sounds like the user just tapped on the network.
+     * It's not necessarily the case ; auto-reconnection to WiFi has this true for example.
      * @hide
      */
     public boolean explicitlySelected;
diff --git a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
index 058f3c9..c9c0940 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
@@ -19,9 +19,11 @@
 import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
 
 import android.annotation.IntDef;
+import android.annotation.LongDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.net.ConnectivityManager.NetworkCallback;
@@ -32,10 +34,10 @@
 import android.os.Process;
 import android.text.TextUtils;
 import android.util.ArraySet;
+import android.util.Range;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.Preconditions;
 import com.android.net.module.util.CollectionUtils;
 import com.android.net.module.util.NetworkCapabilitiesUtils;
 
@@ -63,6 +65,68 @@
 public final class NetworkCapabilities implements Parcelable {
     private static final String TAG = "NetworkCapabilities";
 
+    /**
+     * Mechanism to support redaction of fields in NetworkCapabilities that are guarded by specific
+     * app permissions.
+     **/
+    /**
+     * Don't redact any fields since the receiving app holds all the necessary permissions.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final long REDACT_NONE = 0;
+
+    /**
+     * Redact any fields that need {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
+     * permission since the receiving app does not hold this permission or the location toggle
+     * is off.
+     *
+     * @see android.Manifest.permission#ACCESS_FINE_LOCATION
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final long REDACT_FOR_ACCESS_FINE_LOCATION = 1 << 0;
+
+    /**
+     * Redact any fields that need {@link android.Manifest.permission#LOCAL_MAC_ADDRESS}
+     * permission since the receiving app does not hold this permission.
+     *
+     * @see android.Manifest.permission#LOCAL_MAC_ADDRESS
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final long REDACT_FOR_LOCAL_MAC_ADDRESS = 1 << 1;
+
+    /**
+     *
+     * Redact any fields that need {@link android.Manifest.permission#NETWORK_SETTINGS}
+     * permission since the receiving app does not hold this permission.
+     *
+     * @see android.Manifest.permission#NETWORK_SETTINGS
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final long REDACT_FOR_NETWORK_SETTINGS = 1 << 2;
+
+    /**
+     * Redact all fields in this object that require any relevant permission.
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final long REDACT_ALL = -1L;
+
+    /** @hide */
+    @LongDef(flag = true, prefix = { "REDACT_" }, value = {
+            REDACT_NONE,
+            REDACT_FOR_ACCESS_FINE_LOCATION,
+            REDACT_FOR_LOCAL_MAC_ADDRESS,
+            REDACT_FOR_NETWORK_SETTINGS,
+            REDACT_ALL
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface RedactionType {}
+
     // Set to true when private DNS is broken.
     private boolean mPrivateDnsBroken;
 
@@ -77,32 +141,31 @@
     private String mRequestorPackageName;
 
     /**
-     * Indicates whether parceling should preserve fields that are set based on permissions of
-     * the process receiving the {@link NetworkCapabilities}.
+     * Indicates what fields should be redacted from this instance.
      */
-    private final boolean mParcelLocationSensitiveFields;
+    private final @RedactionType long mRedactions;
 
     public NetworkCapabilities() {
-        mParcelLocationSensitiveFields = false;
+        mRedactions = REDACT_ALL;
         clearAll();
         mNetworkCapabilities = DEFAULT_CAPABILITIES;
     }
 
     public NetworkCapabilities(NetworkCapabilities nc) {
-        this(nc, false /* parcelLocationSensitiveFields */);
+        this(nc, REDACT_ALL);
     }
 
     /**
      * Make a copy of NetworkCapabilities.
      *
      * @param nc Original NetworkCapabilities
-     * @param parcelLocationSensitiveFields Whether to parcel location sensitive data or not.
+     * @param redactions bitmask of redactions that needs to be performed on this new instance of
+     *                   {@link NetworkCapabilities}.
      * @hide
      */
-    @SystemApi
-    public NetworkCapabilities(
-            @Nullable NetworkCapabilities nc, boolean parcelLocationSensitiveFields) {
-        mParcelLocationSensitiveFields = parcelLocationSensitiveFields;
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public NetworkCapabilities(@Nullable NetworkCapabilities nc, @RedactionType long redactions) {
+        mRedactions = redactions;
         if (nc != null) {
             set(nc);
         }
@@ -114,11 +177,13 @@
      * @hide
      */
     public void clearAll() {
-        // Ensures that the internal copies maintained by the connectivity stack does not set
-        // this bit.
-        if (mParcelLocationSensitiveFields) {
+        // Ensures that the internal copies maintained by the connectivity stack does not set it to
+        // anything other than |REDACT_ALL|.
+        if (mRedactions != REDACT_ALL) {
+            // This is needed because the current redaction mechanism relies on redaction while
+            // parceling.
             throw new UnsupportedOperationException(
-                    "Cannot clear NetworkCapabilities when parcelLocationSensitiveFields is set");
+                    "Cannot clear NetworkCapabilities when mRedactions is set");
         }
         mNetworkCapabilities = mTransportTypes = mUnwantedNetworkCapabilities = 0;
         mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
@@ -148,12 +213,12 @@
         mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
         mNetworkSpecifier = nc.mNetworkSpecifier;
         if (nc.getTransportInfo() != null) {
-            setTransportInfo(nc.getTransportInfo().makeCopy(mParcelLocationSensitiveFields));
+            setTransportInfo(nc.getTransportInfo().makeCopy(mRedactions));
         } else {
             setTransportInfo(null);
         }
         mSignalStrength = nc.mSignalStrength;
-        setUids(nc.mUids); // Will make the defensive copy
+        mUids = (nc.mUids == null) ? null : new ArraySet<>(nc.mUids);
         setAdministratorUids(nc.getAdministratorUids());
         mOwnerUid = nc.mOwnerUid;
         mUnwantedNetworkCapabilities = nc.mUnwantedNetworkCapabilities;
@@ -609,10 +674,8 @@
      * Gets all the capabilities set on this {@code NetworkCapability} instance.
      *
      * @return an array of capability values for this instance.
-     * @hide
      */
-    @UnsupportedAppUsage
-    public @NetCapability int[] getCapabilities() {
+    public @NonNull @NetCapability int[] getCapabilities() {
         return NetworkCapabilitiesUtils.unpackBits(mNetworkCapabilities);
     }
 
@@ -1458,9 +1521,8 @@
      * @hide
      */
     public @NonNull NetworkCapabilities setSingleUid(int uid) {
-        final ArraySet<UidRange> identity = new ArraySet<>(1);
-        identity.add(new UidRange(uid, uid));
-        setUids(identity);
+        mUids = new ArraySet<>(1);
+        mUids.add(new UidRange(uid, uid));
         return this;
     }
 
@@ -1469,22 +1531,34 @@
      * This makes a copy of the set so that callers can't modify it after the call.
      * @hide
      */
-    public @NonNull NetworkCapabilities setUids(Set<UidRange> uids) {
-        if (null == uids) {
-            mUids = null;
-        } else {
-            mUids = new ArraySet<>(uids);
-        }
+    public @NonNull NetworkCapabilities setUids(@Nullable Set<Range<Integer>> uids) {
+        mUids = UidRange.fromIntRanges(uids);
         return this;
     }
 
     /**
      * Get the list of UIDs this network applies to.
      * This returns a copy of the set so that callers can't modify the original object.
+     *
+     * @return the list of UIDs this network applies to. If {@code null}, then the network applies
+     *         to all UIDs.
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    @SuppressLint("NullableCollection")
+    public @Nullable Set<Range<Integer>> getUids() {
+        return UidRange.toIntRanges(mUids);
+    }
+
+    /**
+     * Get the list of UIDs this network applies to.
+     * This returns a copy of the set so that callers can't modify the original object.
      * @hide
      */
-    public @Nullable Set<UidRange> getUids() {
-        return null == mUids ? null : new ArraySet<>(mUids);
+    public @Nullable Set<UidRange> getUidRanges() {
+        if (mUids == null) return null;
+
+        return new ArraySet<>(mUids);
     }
 
     /**
@@ -2099,8 +2173,9 @@
     }
 
     private static void checkValidTransportType(@Transport int transport) {
-        Preconditions.checkArgument(
-                isValidTransport(transport), "Invalid TransportType " + transport);
+        if (!isValidTransport(transport)) {
+            throw new IllegalArgumentException("Invalid TransportType " + transport);
+        }
     }
 
     private static boolean isValidCapability(@NetworkCapabilities.NetCapability int capability) {
@@ -2108,8 +2183,9 @@
     }
 
     private static void checkValidCapability(@NetworkCapabilities.NetCapability int capability) {
-        Preconditions.checkArgument(isValidCapability(capability),
-                "NetworkCapability " + capability + "out of range");
+        if (!isValidCapability(capability)) {
+            throw new IllegalArgumentException("NetworkCapability " + capability + "out of range");
+        }
     }
 
     /**
@@ -2338,6 +2414,23 @@
     }
 
     /**
+     * Returns a bitmask of all the applicable redactions (based on the permissions held by the
+     * receiving app) to be performed on this object.
+     *
+     * @return bitmask of redactions applicable on this instance.
+     * @hide
+     */
+    public @RedactionType long getApplicableRedactions() {
+        // Currently, there are no fields redacted in NetworkCapabilities itself, so we just
+        // passthrough the redactions required by the embedded TransportInfo. If this changes
+        // in the future, modify this method.
+        if (mTransportInfo == null) {
+            return NetworkCapabilities.REDACT_NONE;
+        }
+        return mTransportInfo.getApplicableRedactions();
+    }
+
+    /**
      * Builder class for NetworkCapabilities.
      *
      * This class is mainly for for {@link NetworkAgent} instances to use. Many fields in
@@ -2655,6 +2748,21 @@
         }
 
         /**
+         * Set the list of UIDs this network applies to.
+         *
+         * @param uids the list of UIDs this network applies to, or {@code null} if this network
+         *             applies to all UIDs.
+         * @return this builder
+         * @hide
+         */
+        @NonNull
+        @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+        public Builder setUids(@Nullable Set<Range<Integer>> uids) {
+            mCaps.setUids(uids);
+            return this;
+        }
+
+        /**
          * Builds the instance of the capabilities.
          *
          * @return the built instance of NetworkCapabilities.
diff --git a/packages/Connectivity/framework/src/android/net/NetworkRequest.java b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
index dbe3ecc..cf131f0 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkRequest.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
@@ -36,6 +36,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.net.NetworkCapabilities.NetCapability;
@@ -45,6 +46,7 @@
 import android.os.Parcelable;
 import android.os.Process;
 import android.text.TextUtils;
+import android.util.Range;
 import android.util.proto.ProtoOutputStream;
 
 import java.util.Arrays;
@@ -277,11 +279,14 @@
          * Set the watched UIDs for this request. This will be reset and wiped out unless
          * the calling app holds the CHANGE_NETWORK_STATE permission.
          *
-         * @param uids The watched UIDs as a set of UidRanges, or null for everything.
+         * @param uids The watched UIDs as a set of {@code Range<Integer>}, or null for everything.
          * @return The builder to facilitate chaining.
          * @hide
          */
-        public Builder setUids(Set<UidRange> uids) {
+        @NonNull
+        @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+        @SuppressLint("MissingGetterMatchingBuilder")
+        public Builder setUids(@Nullable Set<Range<Integer>> uids) {
             mNetworkCapabilities.setUids(uids);
             return this;
         }
diff --git a/packages/Connectivity/framework/src/android/net/NetworkScore.java b/packages/Connectivity/framework/src/android/net/NetworkScore.java
index e640737..eadcb2d 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkScore.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkScore.java
@@ -20,6 +20,8 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 /**
  * Object representing the quality of a network as perceived by the user.
  *
@@ -35,6 +37,10 @@
 
     // Agent-managed policies
     // TODO : add them here, starting from 1
+    /** @hide */
+    public static final int MIN_AGENT_MANAGED_POLICY = 0;
+    /** @hide */
+    public static final int MAX_AGENT_MANAGED_POLICY = -1;
 
     // Bitmask of all the policies applied to this score.
     private final long mPolicies;
@@ -54,6 +60,14 @@
         return mLegacyInt;
     }
 
+    /**
+     * @return whether this score has a particular policy.
+     */
+    @VisibleForTesting
+    public boolean hasPolicy(final int policy) {
+        return 0 != (mPolicies & (1L << policy));
+    }
+
     @Override
     public String toString() {
         return "Score(" + mLegacyInt + ")";
diff --git a/packages/Connectivity/framework/src/android/net/NetworkUtils.java b/packages/Connectivity/framework/src/android/net/NetworkUtils.java
index c0f2628..c4bebc0 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkUtils.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkUtils.java
@@ -323,22 +323,7 @@
      */
     @UnsupportedAppUsage
     public static String trimV4AddrZeros(String addr) {
-        if (addr == null) return null;
-        String[] octets = addr.split("\\.");
-        if (octets.length != 4) return addr;
-        StringBuilder builder = new StringBuilder(16);
-        String result = null;
-        for (int i = 0; i < 4; i++) {
-            try {
-                if (octets[i].length() > 3) return addr;
-                builder.append(Integer.parseInt(octets[i]));
-            } catch (NumberFormatException e) {
-                return addr;
-            }
-            if (i < 3) builder.append('.');
-        }
-        result = builder.toString();
-        return result;
+        return Inet4AddressUtils.trimAddressZeros(addr);
     }
 
     /**
diff --git a/packages/Connectivity/framework/src/android/net/StaticIpConfiguration.java b/packages/Connectivity/framework/src/android/net/StaticIpConfiguration.java
index ce54597..7904f7a 100644
--- a/packages/Connectivity/framework/src/android/net/StaticIpConfiguration.java
+++ b/packages/Connectivity/framework/src/android/net/StaticIpConfiguration.java
@@ -24,7 +24,6 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
-import com.android.internal.util.Preconditions;
 import com.android.net.module.util.InetAddressUtils;
 
 import java.net.InetAddress;
@@ -153,7 +152,7 @@
          * @return The {@link Builder} for chaining.
          */
         public @NonNull Builder setDnsServers(@NonNull Iterable<InetAddress> dnsServers) {
-            Preconditions.checkNotNull(dnsServers);
+            Objects.requireNonNull(dnsServers);
             mDnsServers = dnsServers;
             return this;
         }
diff --git a/packages/Connectivity/framework/src/android/net/TestNetworkManager.java b/packages/Connectivity/framework/src/android/net/TestNetworkManager.java
index a174a7b..a7a6235 100644
--- a/packages/Connectivity/framework/src/android/net/TestNetworkManager.java
+++ b/packages/Connectivity/framework/src/android/net/TestNetworkManager.java
@@ -21,10 +21,9 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 
-import com.android.internal.util.Preconditions;
-
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Objects;
 
 /**
  * Class that allows creation and management of per-app, test-only networks
@@ -50,7 +49,7 @@
 
     /** @hide */
     public TestNetworkManager(@NonNull ITestNetworkManager service) {
-        mService = Preconditions.checkNotNull(service, "missing ITestNetworkManager");
+        mService = Objects.requireNonNull(service, "missing ITestNetworkManager");
     }
 
     /**
@@ -93,7 +92,7 @@
      */
     public void setupTestNetwork(
             @NonNull LinkProperties lp, boolean isMetered, @NonNull IBinder binder) {
-        Preconditions.checkNotNull(lp, "Invalid LinkProperties");
+        Objects.requireNonNull(lp, "Invalid LinkProperties");
         setupTestNetwork(lp.getInterfaceName(), lp, isMetered, new int[0], binder);
     }
 
diff --git a/packages/Connectivity/framework/src/android/net/TestNetworkSpecifier.java b/packages/Connectivity/framework/src/android/net/TestNetworkSpecifier.java
index b7470a5..117457d 100644
--- a/packages/Connectivity/framework/src/android/net/TestNetworkSpecifier.java
+++ b/packages/Connectivity/framework/src/android/net/TestNetworkSpecifier.java
@@ -23,8 +23,6 @@
 import android.os.Parcelable;
 import android.text.TextUtils;
 
-import com.android.internal.util.Preconditions;
-
 import java.util.Objects;
 
 /**
@@ -43,7 +41,9 @@
     private final String mInterfaceName;
 
     public TestNetworkSpecifier(@NonNull String interfaceName) {
-        Preconditions.checkStringNotEmpty(interfaceName);
+        if (TextUtils.isEmpty(interfaceName)) {
+            throw new IllegalArgumentException("Empty interfaceName");
+        }
         mInterfaceName = interfaceName;
     }
 
diff --git a/packages/Connectivity/framework/src/android/net/TransportInfo.java b/packages/Connectivity/framework/src/android/net/TransportInfo.java
index aa4bbb0..fa889ea 100644
--- a/packages/Connectivity/framework/src/android/net/TransportInfo.java
+++ b/packages/Connectivity/framework/src/android/net/TransportInfo.java
@@ -29,35 +29,47 @@
 public interface TransportInfo {
 
     /**
-     * Create a copy of a {@link TransportInfo} that will preserve location sensitive fields that
-     * were set based on the permissions of the process that originally received it.
+     * Create a copy of a {@link TransportInfo} with some fields redacted based on the permissions
+     * held by the receiving app.
      *
-     * <p>By default {@link TransportInfo} does not preserve such fields during parceling, as
-     * they should not be shared outside of the process that receives them without appropriate
-     * checks.
+     * <p>
+     * Usage by connectivity stack:
+     * <ul>
+     * <li> Connectivity stack will invoke {@link #getApplicableRedactions()} to find the list
+     * of redactions that are required by this {@link TransportInfo} instance.</li>
+     * <li> Connectivity stack then loops through each bit in the bitmask returned and checks if the
+     * receiving app holds the corresponding permission.
+     * <ul>
+     * <li> If the app holds the corresponding permission, the bit is cleared from the
+     * |redactions| bitmask. </li>
+     * <li> If the app does not hold the corresponding permission, the bit is retained in the
+     * |redactions| bitmask. </li>
+     * </ul>
+     * <li> Connectivity stack then invokes {@link #makeCopy(long)} with the necessary |redactions|
+     * to create a copy to send to the corresponding app. </li>
+     * </ul>
+     * </p>
      *
-     * @param parcelLocationSensitiveFields Whether the location sensitive fields should be kept
-     *                                      when parceling
-     * @return Copy of this instance.
+     * @param redactions bitmask of redactions that needs to be performed on this instance.
+     * @return Copy of this instance with the necessary redactions.
      * @hide
      */
-    @SystemApi
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     @NonNull
-    default TransportInfo makeCopy(boolean parcelLocationSensitiveFields) {
+    default TransportInfo makeCopy(@NetworkCapabilities.RedactionType long redactions) {
         return this;
     }
 
     /**
-     * Returns whether this TransportInfo type has location sensitive fields or not (helps
-     * to determine whether to perform a location permission check or not before sending to
-     * apps).
+     * Returns a bitmask of all the applicable redactions (based on the permissions held by the
+     * receiving app) to be performed on this TransportInfo.
      *
-     * @return {@code true} if this instance contains location sensitive info, {@code false}
-     * otherwise.
+     * @return bitmask of redactions applicable on this instance.
+     * @see #makeCopy(long)
      * @hide
      */
-    @SystemApi
-    default boolean hasLocationSensitiveFields() {
-        return false;
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    default @NetworkCapabilities.RedactionType long getApplicableRedactions() {
+        return NetworkCapabilities.REDACT_NONE;
     }
 }
diff --git a/packages/Connectivity/framework/src/android/net/UidRange.java b/packages/Connectivity/framework/src/android/net/UidRange.java
index 26518d3..bc67c74 100644
--- a/packages/Connectivity/framework/src/android/net/UidRange.java
+++ b/packages/Connectivity/framework/src/android/net/UidRange.java
@@ -20,8 +20,11 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.UserHandle;
+import android.util.ArraySet;
+import android.util.Range;
 
 import java.util.Collection;
+import java.util.Set;
 
 /**
  * An inclusive range of UIDs.
@@ -149,4 +152,32 @@
         }
         return false;
     }
+
+    /**
+     *  Convert a set of {@code Range<Integer>} to a set of {@link UidRange}.
+     */
+    @Nullable
+    public static ArraySet<UidRange> fromIntRanges(@Nullable Set<Range<Integer>> ranges) {
+        if (null == ranges) return null;
+
+        final ArraySet<UidRange> uids = new ArraySet<>();
+        for (Range<Integer> range : ranges) {
+            uids.add(new UidRange(range.getLower(), range.getUpper()));
+        }
+        return uids;
+    }
+
+    /**
+     *  Convert a set of {@link UidRange} to a set of {@code Range<Integer>}.
+     */
+    @Nullable
+    public static ArraySet<Range<Integer>> toIntRanges(@Nullable Set<UidRange> ranges) {
+        if (null == ranges) return null;
+
+        final ArraySet<Range<Integer>> uids = new ArraySet<>();
+        for (UidRange range : ranges) {
+            uids.add(new Range<Integer>(range.start, range.stop));
+        }
+        return uids;
+    }
 }
diff --git a/packages/Connectivity/framework/src/android/net/apf/ApfCapabilities.java b/packages/Connectivity/framework/src/android/net/apf/ApfCapabilities.java
index bf5b26e..85b24713 100644
--- a/packages/Connectivity/framework/src/android/net/apf/ApfCapabilities.java
+++ b/packages/Connectivity/framework/src/android/net/apf/ApfCapabilities.java
@@ -19,12 +19,12 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.content.Context;
 import android.content.res.Resources;
+import android.net.ConnectivityResources;
 import android.os.Parcel;
 import android.os.Parcelable;
 
-import com.android.internal.R;
-
 /**
  * APF program support capabilities. APF stands for Android Packet Filtering and it is a flexible
  * way to drop unwanted network packets to save power.
@@ -36,6 +36,8 @@
  */
 @SystemApi
 public final class ApfCapabilities implements Parcelable {
+    private static ConnectivityResources sResources;
+
     /**
      * Version of APF instruction set supported for packet filtering. 0 indicates no support for
      * packet filtering using APF programs.
@@ -65,6 +67,14 @@
         apfPacketFormat = in.readInt();
     }
 
+    @NonNull
+    private static synchronized ConnectivityResources getResources(@NonNull Context ctx) {
+        if (sResources == null)  {
+            sResources = new ConnectivityResources(ctx);
+        }
+        return sResources;
+    }
+
 
     @Override
     public int describeContents() {
@@ -121,13 +131,43 @@
      * @return Whether the APF Filter in the device should filter out IEEE 802.3 Frames.
      */
     public static boolean getApfDrop8023Frames() {
-        return Resources.getSystem().getBoolean(R.bool.config_apfDrop802_3Frames);
+        // TODO(b/183076074): remove reading resources from system resources
+        final Resources systemRes = Resources.getSystem();
+        final int id = systemRes.getIdentifier("config_apfDrop802_3Frames", "bool", "android");
+        return systemRes.getBoolean(id);
+    }
+
+    /**
+     * @return Whether the APF Filter in the device should filter out IEEE 802.3 Frames.
+     * @hide
+     */
+    public static boolean getApfDrop8023Frames(@NonNull Context context) {
+        final ConnectivityResources res = getResources(context);
+        // TODO(b/183076074): use R.bool.config_apfDrop802_3Frames directly
+        final int id = res.get().getIdentifier("config_apfDrop802_3Frames", "bool",
+                res.getResourcesContext().getPackageName());
+        return res.get().getBoolean(id);
     }
 
     /**
      * @return An array of denylisted EtherType, packets with EtherTypes within it will be dropped.
      */
     public static @NonNull int[] getApfEtherTypeBlackList() {
-        return Resources.getSystem().getIntArray(R.array.config_apfEthTypeBlackList);
+        // TODO(b/183076074): remove reading resources from system resources
+        final Resources systemRes = Resources.getSystem();
+        final int id = systemRes.getIdentifier("config_apfEthTypeBlackList", "array", "android");
+        return systemRes.getIntArray(id);
+    }
+
+    /**
+     * @return An array of denylisted EtherType, packets with EtherTypes within it will be dropped.
+     * @hide
+     */
+    public static @NonNull int[] getApfEtherTypeDenyList(@NonNull Context context) {
+        final ConnectivityResources res = getResources(context);
+        // TODO(b/183076074): use R.array.config_apfEthTypeDenyList directly
+        final int id = res.get().getIdentifier("config_apfEthTypeDenyList", "array",
+                res.getResourcesContext().getPackageName());
+        return res.get().getIntArray(id);
     }
 }
diff --git a/packages/Connectivity/framework/src/android/net/util/KeepaliveUtils.java b/packages/Connectivity/framework/src/android/net/util/KeepaliveUtils.java
index bfc4563..8d7a0b3 100644
--- a/packages/Connectivity/framework/src/android/net/util/KeepaliveUtils.java
+++ b/packages/Connectivity/framework/src/android/net/util/KeepaliveUtils.java
@@ -19,12 +19,11 @@
 import android.annotation.NonNull;
 import android.content.Context;
 import android.content.res.Resources;
+import android.net.ConnectivityResources;
 import android.net.NetworkCapabilities;
 import android.text.TextUtils;
 import android.util.AndroidRuntimeException;
 
-import com.android.internal.R;
-
 /**
  * Collection of utilities for socket keepalive offload.
  *
@@ -52,8 +51,11 @@
     public static int[] getSupportedKeepalives(@NonNull Context context) {
         String[] res = null;
         try {
-            res = context.getResources().getStringArray(
-                    R.array.config_networkSupportedKeepaliveCount);
+            final ConnectivityResources connRes = new ConnectivityResources(context);
+            // TODO: use R.id.config_networkSupportedKeepaliveCount directly
+            final int id = connRes.get().getIdentifier("config_networkSupportedKeepaliveCount",
+                    "array", connRes.getResourcesContext().getPackageName());
+            res = new ConnectivityResources(context).get().getStringArray(id);
         } catch (Resources.NotFoundException unused) {
         }
         if (res == null) throw new KeepaliveDeviceConfigurationException("invalid resource");
diff --git a/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java b/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java
index 6a49aa2..0b42a00 100644
--- a/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java
+++ b/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java
@@ -27,6 +27,7 @@
 import android.content.IntentFilter;
 import android.content.res.Resources;
 import android.database.ContentObserver;
+import android.net.ConnectivityResources;
 import android.net.Uri;
 import android.os.Handler;
 import android.provider.Settings;
@@ -35,7 +36,6 @@
 import android.telephony.TelephonyManager;
 import android.util.Log;
 
-import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.Arrays;
@@ -64,6 +64,7 @@
     private static String TAG = MultinetworkPolicyTracker.class.getSimpleName();
 
     private final Context mContext;
+    private final ConnectivityResources mResources;
     private final Handler mHandler;
     private final Runnable mAvoidBadWifiCallback;
     private final List<Uri> mSettingsUris;
@@ -107,6 +108,7 @@
 
     public MultinetworkPolicyTracker(Context ctx, Handler handler, Runnable avoidBadWifiCallback) {
         mContext = ctx;
+        mResources = new ConnectivityResources(ctx);
         mHandler = handler;
         mAvoidBadWifiCallback = avoidBadWifiCallback;
         mSettingsUris = Arrays.asList(
@@ -160,12 +162,16 @@
      * Whether the device or carrier configuration disables avoiding bad wifi by default.
      */
     public boolean configRestrictsAvoidBadWifi() {
-        return (getResourcesForActiveSubId().getInteger(R.integer.config_networkAvoidBadWifi) == 0);
+        // TODO: use R.integer.config_networkAvoidBadWifi directly
+        final int id = mResources.get().getIdentifier("config_networkAvoidBadWifi",
+                "integer", mResources.getResourcesContext().getPackageName());
+        return (getResourcesForActiveSubId().getInteger(id) == 0);
     }
 
     @NonNull
     private Resources getResourcesForActiveSubId() {
-        return SubscriptionManager.getResourcesForSubId(mContext, mActiveSubId);
+        return SubscriptionManager.getResourcesForSubId(
+                mResources.getResourcesContext(), mActiveSubId);
     }
 
     /**
@@ -205,8 +211,10 @@
      * The default (device and carrier-dependent) value for metered multipath preference.
      */
     public int configMeteredMultipathPreference() {
-        return mContext.getResources().getInteger(
-                R.integer.config_networkMeteredMultipathPreference);
+        // TODO: use R.integer.config_networkMeteredMultipathPreference directly
+        final int id = mResources.get().getIdentifier("config_networkMeteredMultipathPreference",
+                "integer", mResources.getResourcesContext().getPackageName());
+        return mResources.get().getInteger(id);
     }
 
     public void updateMeteredMultipathPreference() {
diff --git a/packages/Connectivity/service/Android.bp b/packages/Connectivity/service/Android.bp
index f630cea..1330e71 100644
--- a/packages/Connectivity/service/Android.bp
+++ b/packages/Connectivity/service/Android.bp
@@ -68,6 +68,7 @@
         "net-utils-framework-common",
         "netd-client",
         "PlatformProperties",
+        "service-connectivity-protos",
     ],
     apex_available: [
         "//apex_available:platform",
@@ -76,6 +77,21 @@
 }
 
 java_library {
+    name: "service-connectivity-protos",
+    proto: {
+        type: "nano",
+    },
+    srcs: [
+        ":system-messages-proto-src",
+    ],
+    libs: ["libprotobuf-java-nano"],
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.tethering",
+    ],
+}
+
+java_library {
     name: "service-connectivity",
     installable: true,
     static_libs: [
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/Android.bp b/packages/Connectivity/service/ServiceConnectivityResources/Android.bp
index f2446b7..fa4501a 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/Android.bp
+++ b/packages/Connectivity/service/ServiceConnectivityResources/Android.bp
@@ -21,7 +21,7 @@
 
 android_app {
     name: "ServiceConnectivityResources",
-    sdk_version: "system_current",
+    sdk_version: "module_current",
     resource_dirs: [
         "res",
     ],
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-hdpi/stat_notify_rssi_in_range.png b/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-hdpi/stat_notify_rssi_in_range.png
new file mode 100644
index 0000000..74977e6
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-hdpi/stat_notify_rssi_in_range.png
Binary files differ
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-mdpi/stat_notify_rssi_in_range.png b/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-mdpi/stat_notify_rssi_in_range.png
new file mode 100644
index 0000000..62e4fe9
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-mdpi/stat_notify_rssi_in_range.png
Binary files differ
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-xhdpi/stat_notify_rssi_in_range.png b/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-xhdpi/stat_notify_rssi_in_range.png
new file mode 100644
index 0000000..c0586d8
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-xhdpi/stat_notify_rssi_in_range.png
Binary files differ
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-xxhdpi/stat_notify_rssi_in_range.png b/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-xxhdpi/stat_notify_rssi_in_range.png
new file mode 100644
index 0000000..86c34ed
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/drawable-xxhdpi/stat_notify_rssi_in_range.png
Binary files differ
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/drawable/stat_notify_wifi_in_range.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/drawable/stat_notify_wifi_in_range.xml
new file mode 100644
index 0000000..a271ca5
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/drawable/stat_notify_wifi_in_range.xml
@@ -0,0 +1,27 @@
+<!--
+Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="26.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="26.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#4DFFFFFF"
+        android:pathData="M19.1,14l-3.4,0l0,-1.5c0,-1.8 0.8,-2.8 1.5,-3.4C18.1,8.3 19.200001,8 20.6,8c1.2,0 2.3,0.3 3.1,0.8l1.9,-2.3C25.1,6.1 20.299999,2.1 13,2.1S0.9,6.1 0.4,6.5L13,22l0,0l0,0l0,0l0,0l6.5,-8.1L19.1,14z"/>
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M19.5,17.799999c0,-0.8 0.1,-1.3 0.2,-1.6c0.2,-0.3 0.5,-0.7 1.1,-1.2c0.4,-0.4 0.7,-0.8 1,-1.1s0.4,-0.8 0.4,-1.2c0,-0.5 -0.1,-0.9 -0.4,-1.2c-0.3,-0.3 -0.7,-0.4 -1.2,-0.4c-0.4,0 -0.8,0.1 -1.1,0.3c-0.3,0.2 -0.4,0.6 -0.4,1.1l-1.9,0c0,-1 0.3,-1.7 1,-2.2c0.6,-0.5 1.5,-0.8 2.5,-0.8c1.1,0 2,0.3 2.6,0.8c0.6,0.5 0.9,1.3 0.9,2.3c0,0.7 -0.2,1.3 -0.6,1.8c-0.4,0.6 -0.9,1.1 -1.5,1.6c-0.3,0.3 -0.5,0.5 -0.6,0.7c-0.1,0.2 -0.1,0.6 -0.1,1L19.5,17.700001zM21.4,21l-1.9,0l0,-1.8l1.9,0L21.4,21z"/>
+</vector>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-af/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-af/strings.xml
new file mode 100644
index 0000000..68720d5
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-af/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Meld aan by Wi-Fi-netwerk"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Meld by netwerk aan"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> het geen internettoegang nie"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Tik vir opsies"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Selnetwerk het nie internettoegang nie"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Netwerk het nie internettoegang nie"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Daar kan nie by private DNS-bediener ingegaan word nie"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> het beperkte konnektiwiteit"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Tik om in elk geval te koppel"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Het oorgeskakel na <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Toestel gebruik <xliff:g id="NEW_NETWORK">%1$s</xliff:g> wanneer <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> geen internettoegang het nie. Heffings kan geld."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Het oorgeskakel van <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"\'n onbekende netwerktipe"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"mobiele data"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-am/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-am/strings.xml
new file mode 100644
index 0000000..78d9283
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-am/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"ወደ Wi-Fi አውታረ መረብ በመለያ ግባ"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"ወደ አውታረ መረብ በመለያ ይግቡ"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ምንም የበይነ መረብ መዳረሻ የለም"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"ለአማራጮች መታ ያድርጉ"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"የተንቀሳቃሽ ስልክ አውታረ መረብ የበይነመረብ መዳረሻ የለውም"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"አውታረ መረብ የበይነመረብ መዳረሻ የለውም"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"የግል ዲኤንኤስ አገልጋይ ሊደረስበት አይችልም"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> የተገደበ ግንኙነት አለው"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"ለማንኛውም ለማገናኘት መታ ያድርጉ"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"ወደ <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ተቀይሯል"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ምንም ዓይነት የበይነመረብ ግንኙነት በማይኖረው ጊዜ መሣሪያዎች <xliff:g id="NEW_NETWORK">%1$s</xliff:g>ን ይጠቀማሉ። ክፍያዎች ተፈጻሚ ሊሆኑ ይችላሉ።"</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"ከ<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ወደ <xliff:g id="NEW_NETWORK">%2$s</xliff:g> ተቀይሯል"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"አንድ ያልታወቀ አውታረ መረብ ዓይነት"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"የተንቀሳቃሽ ስልክ ውሂብ"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"ብሉቱዝ"</item>
+    <item msgid="1616528372438698248">"ኤተርኔት"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ar/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ar/strings.xml
new file mode 100644
index 0000000..8698a7e
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ar/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"‏تسجيل الدخول إلى شبكة Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"تسجيل الدخول إلى الشبكة"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"لا يتوفّر في <xliff:g id="NETWORK_SSID">%1$s</xliff:g> إمكانية الاتصال بالإنترنت."</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"انقر للحصول على الخيارات."</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"شبكة الجوّال هذه غير متصلة بالإنترنت"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"الشبكة غير متصلة بالإنترنت"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"لا يمكن الوصول إلى خادم أسماء نظام نطاقات خاص"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"إمكانية اتصال <xliff:g id="NETWORK_SSID">%1$s</xliff:g> محدودة."</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"يمكنك النقر للاتصال على أي حال."</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"تم التبديل إلى <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"يستخدم الجهاز <xliff:g id="NEW_NETWORK">%1$s</xliff:g> عندما لا يتوفر اتصال بالإنترنت في شبكة <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>، ويمكن أن يتم فرض رسوم مقابل ذلك."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"تم التبديل من <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> إلى <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"نوع شبكة غير معروف"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"بيانات الجوّال"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"بلوتوث"</item>
+    <item msgid="1616528372438698248">"إيثرنت"</item>
+    <item msgid="9177085807664964627">"‏شبكة افتراضية خاصة (VPN)"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-as/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-as/strings.xml
new file mode 100644
index 0000000..10b234a
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-as/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"ৱাই-ফাই নেটৱৰ্কত ছাইন ইন কৰক"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"নেটৱৰ্কত ছাইন ইন কৰক"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>ৰ ইণ্টাৰনেটৰ এক্সেছ নাই"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"অধিক বিকল্পৰ বাবে টিপক"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"ম’বাইল নেটৱৰ্কৰ কোনো ইণ্টাৰনেটৰ এক্সেছ নাই"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"নেটৱৰ্কৰ কোনো ইণ্টাৰনেটৰ এক্সেছ নাই"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"ব্যক্তিগত DNS ছাৰ্ভাৰ এক্সেছ কৰিব নোৱাৰি"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>ৰ সকলো সেৱাৰ এক্সেছ নাই"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"যিকোনো প্ৰকাৰে সংযোগ কৰিবলৈ টিপক"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>লৈ সলনি কৰা হ’ল"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"যেতিয়া <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>ত ইণ্টাৰনেট নাথাকে, তেতিয়া ডিভাইচে <xliff:g id="NEW_NETWORK">%1$s</xliff:g>ক ব্যৱহাৰ কৰে। মাচুল প্ৰযোজ্য হ\'ব পাৰে।"</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>ৰ পৰা <xliff:g id="NEW_NETWORK">%2$s</xliff:g> লৈ সলনি কৰা হ’ল"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"অজ্ঞাত প্ৰকাৰৰ নেটৱৰ্ক"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"ম’বাইল ডেটা"</item>
+    <item msgid="5520925862115353992">"ৱাই-ফাই"</item>
+    <item msgid="1055487873974272842">"ব্লুটুথ"</item>
+    <item msgid="1616528372438698248">"ইথাৰনেট"</item>
+    <item msgid="9177085807664964627">"ভিপিএন"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-az/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-az/strings.xml
new file mode 100644
index 0000000..d75a204
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-az/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Wi-Fi şəbəkəsinə daxil ol"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Şəbəkəyə daxil olun"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> üçün internet girişi əlçatan deyil"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Seçimlər üçün tıklayın"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobil şəbəkənin internetə girişi yoxdur"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Şəbəkənin internetə girişi yoxdur"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Özəl DNS serverinə giriş mümkün deyil"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> bağlantını məhdudlaşdırdı"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"İstənilən halda klikləyin"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> şəbəkə növünə keçirildi"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> şəbəkəsinin internetə girişi olmadıqda, cihaz <xliff:g id="NEW_NETWORK">%1$s</xliff:g> şəbəkəsini istifadə edir. Xidmət haqqı tutula bilər."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> şəbəkəsindən <xliff:g id="NEW_NETWORK">%2$s</xliff:g> şəbəkəsinə keçirildi"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"naməlum şəbəkə növü"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"mobil data"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-b+sr+Latn/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..11e4957
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Prijavljivanje na WiFi mrežu"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Prijavite se na mrežu"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nema pristup internetu"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Dodirnite za opcije"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobilna mreža nema pristup internetu"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Mreža nema pristup internetu"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Pristup privatnom DNS serveru nije uspeo"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ima ograničenu vezu"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Dodirnite da biste se ipak povezali"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Prešli ste na tip mreže <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Uređaj koristi tip mreže <xliff:g id="NEW_NETWORK">%1$s</xliff:g> kada tip mreže <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nema pristup internetu. Možda će se naplaćivati troškovi."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Prešli ste sa tipa mreže <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na tip mreže <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"nepoznat tip mreže"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"mobilni podaci"</item>
+    <item msgid="5520925862115353992">"WiFi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Eternet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-be/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-be/strings.xml
new file mode 100644
index 0000000..6b0b1f1
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-be/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Уваход у сетку Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Увайдзіце ў сетку"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> не мае доступу ў інтэрнэт"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Дакраніцеся, каб убачыць параметры"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Мабільная сетка не мае доступу ў інтэрнэт"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Сетка не мае доступу ў інтэрнэт"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Не ўдалося атрымаць доступ да прыватнага DNS-сервера"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> мае абмежаваную магчымасць падключэння"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Націсніце, каб падключыцца"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Выкананы пераход да <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Прылада выкарыстоўвае сетку <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, калі ў сетцы <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> няма доступу да інтэрнэту. Можа спаганяцца плата."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Выкананы пераход з <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> да <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"невядомы тып сеткі"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"мабільная перадача даных"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-bg/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-bg/strings.xml
new file mode 100644
index 0000000..6427bd0
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-bg/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Влизане в Wi-Fi мрежа"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Вход в мрежата"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> няма достъп до интернет"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Докоснете за опции"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Мобилната мрежа няма достъп до интернет"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Мрежата няма достъп до интернет"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Не може да се осъществи достъп до частния DNS сървър"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> има ограничена свързаност"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Докоснете, за да се свържете въпреки това"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Превключи се към <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Устройството използва <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, когато <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> няма достъп до интернет. Възможно е да бъдете таксувани."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Превключи се от <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> към <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"неизвестен тип мрежа"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"мобилни данни"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"виртуална частна мрежа (VPN)"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-bn/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-bn/strings.xml
new file mode 100644
index 0000000..74d4cd6
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-bn/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"ওয়াই-ফাই নেটওয়ার্কে সাইন-ইন করুন"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"নেটওয়ার্কে সাইন-ইন করুন"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>-এর ইন্টারনেটে অ্যাক্সেস নেই"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"বিকল্পগুলির জন্য আলতো চাপুন"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"মোবাইল নেটওয়ার্কে কোনও ইন্টারনেট অ্যাক্সেস নেই"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"নেটওয়ার্কে কোনও ইন্টারনেট অ্যাক্সেস নেই"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"ব্যক্তিগত ডিএনএস সার্ভার অ্যাক্সেস করা যাবে না"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>-এর সীমিত কানেক্টিভিটি আছে"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"তবুও কানেক্ট করতে ট্যাপ করুন"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> এ পাল্টানো হয়েছে"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> এ ইন্টারনেট অ্যাক্সেস না থাকলে <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ব্যবহার করা হয়৷ ডেটা চার্জ প্রযোজ্য৷"</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> থেকে <xliff:g id="NEW_NETWORK">%2$s</xliff:g> এ পাল্টানো হয়েছে"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"এই নেটওয়ার্কের প্রকার অজানা"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"মোবাইল ডেটা"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"ব্লুটুথ"</item>
+    <item msgid="1616528372438698248">"ইথারনেট"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-bs/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-bs/strings.xml
new file mode 100644
index 0000000..19f6e1a
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-bs/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Prijavljivanje na WiFi mrežu"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Prijava na mrežu"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"Mreža <xliff:g id="NETWORK_SSID">%1$s</xliff:g> nema pristup internetu"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Dodirnite za opcije"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobilna mreža nema pristup internetu"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Mreža nema pristup internetu"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Nije moguće pristupiti privatnom DNS serveru"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"Mreža <xliff:g id="NETWORK_SSID">%1$s</xliff:g> ima ograničenu povezivost"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Dodirnite da se ipak povežete"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Prebačeno na: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Kada <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nema pristup internetu, uređaj koristi mrežu <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Moguća je naplata usluge."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Prebačeno iz mreže <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> u <xliff:g id="NEW_NETWORK">%2$s</xliff:g> mrežu"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"nepoznata vrsta mreže"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"prijenos podataka na mobilnoj mreži"</item>
+    <item msgid="5520925862115353992">"WiFi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ca/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ca/strings.xml
new file mode 100644
index 0000000..c55684d
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ca/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Inicia la sessió a la xarxa Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Inicia la sessió a la xarxa"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> no té accés a Internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Toca per veure les opcions"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"La xarxa mòbil no té accés a Internet"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"La xarxa no té accés a Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"No es pot accedir al servidor DNS privat"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> té una connectivitat limitada"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Toca per connectar igualment"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Actualment en ús: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"El dispositiu utilitza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> en cas que <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> no tingui accés a Internet. És possible que s\'hi apliquin càrrecs."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Abans es feia servir la xarxa <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>; ara s\'utilitza <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"una tipus de xarxa desconegut"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"dades mòbils"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-cs/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-cs/strings.xml
new file mode 100644
index 0000000..fa8c411
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-cs/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Přihlásit se k síti Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Přihlásit se k síti"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"Síť <xliff:g id="NETWORK_SSID">%1$s</xliff:g> nemá přístup k internetu"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Klepnutím zobrazíte možnosti"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobilní síť nemá přístup k internetu"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Síť nemá přístup k internetu"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Nelze získat přístup k soukromému serveru DNS"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"Síť <xliff:g id="NETWORK_SSID">%1$s</xliff:g> umožňuje jen omezené připojení"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Klepnutím se i přesto připojíte"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Přechod na síť <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Když síť <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nebude mít přístup k internetu, zařízení použije síť <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Mohou být účtovány poplatky."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Přechod ze sítě <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na síť <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"neznámý typ sítě"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"mobilní data"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-da/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-da/strings.xml
new file mode 100644
index 0000000..f7be6df
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-da/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Log ind på Wi-Fi-netværk"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Log ind på netværk"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har ingen internetforbindelse"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Tryk for at se valgmuligheder"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobilnetværket har ingen internetadgang"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Netværket har ingen internetadgang"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Der er ikke adgang til den private DNS-server"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har begrænset forbindelse"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Tryk for at oprette forbindelse alligevel"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Der blev skiftet til <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Enheden benytter <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, når der ikke er internetadgang via <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>. Der opkræves muligvis betaling."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Der blev skiftet fra <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> til <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"en ukendt netværkstype"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"mobildata"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-de/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-de/strings.xml
new file mode 100644
index 0000000..1e7b80c
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-de/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"In WLAN anmelden"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Im Netzwerk anmelden"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> hat keinen Internetzugriff"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Für Optionen tippen"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobiles Netzwerk hat keinen Internetzugriff"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Netzwerk hat keinen Internetzugriff"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Auf den privaten DNS-Server kann nicht zugegriffen werden"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"Schlechte Verbindung mit <xliff:g id="NETWORK_SSID">%1$s</xliff:g>"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Tippen, um die Verbindung trotzdem herzustellen"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Zu <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> gewechselt"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Auf dem Gerät werden <xliff:g id="NEW_NETWORK">%1$s</xliff:g> genutzt, wenn über <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> kein Internet verfügbar ist. Eventuell fallen Gebühren an."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Von \"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>\" zu \"<xliff:g id="NEW_NETWORK">%2$s</xliff:g>\" gewechselt"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"ein unbekannter Netzwerktyp"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"Mobile Daten"</item>
+    <item msgid="5520925862115353992">"WLAN"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-el/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-el/strings.xml
new file mode 100644
index 0000000..89647fdb
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-el/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Συνδεθείτε στο δίκτυο Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Σύνδεση στο δίκτυο"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"Η εφαρμογή <xliff:g id="NETWORK_SSID">%1$s</xliff:g> δεν έχει πρόσβαση στο διαδίκτυο"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Πατήστε για να δείτε τις επιλογές"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Το δίκτυο κινητής τηλεφωνίας δεν έχει πρόσβαση στο διαδίκτυο."</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Το δίκτυο δεν έχει πρόσβαση στο διαδίκτυο."</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Δεν είναι δυνατή η πρόσβαση στον ιδιωτικό διακομιστή DNS."</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"Το δίκτυο <xliff:g id="NETWORK_SSID">%1$s</xliff:g> έχει περιορισμένη συνδεσιμότητα"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Πατήστε για σύνδεση ούτως ή άλλως"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Μετάβαση σε δίκτυο <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Η συσκευή χρησιμοποιεί το δίκτυο <xliff:g id="NEW_NETWORK">%1$s</xliff:g> όταν το δίκτυο <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> δεν έχει πρόσβαση στο διαδίκτυο. Μπορεί να ισχύουν χρεώσεις."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Μετάβαση από το δίκτυο <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> στο δίκτυο <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"άγνωστος τύπος δικτύου"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"δεδομένα κινητής τηλεφωνίας"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rAU/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..d29e2ec
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rAU/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Sign in to a Wi-Fi network"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Sign in to network"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has no Internet access"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Tap for options"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobile network has no Internet access"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Network has no Internet access"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Private DNS server cannot be accessed"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has limited connectivity"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Tap to connect anyway"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Switched to <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Device uses <xliff:g id="NEW_NETWORK">%1$s</xliff:g> when <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> has no Internet access. Charges may apply."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Switched from <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> to <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"an unknown network type"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"mobile data"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rCA/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000..d29e2ec
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rCA/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Sign in to a Wi-Fi network"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Sign in to network"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has no Internet access"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Tap for options"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobile network has no Internet access"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Network has no Internet access"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Private DNS server cannot be accessed"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has limited connectivity"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Tap to connect anyway"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Switched to <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Device uses <xliff:g id="NEW_NETWORK">%1$s</xliff:g> when <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> has no Internet access. Charges may apply."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Switched from <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> to <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"an unknown network type"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"mobile data"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rGB/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..d29e2ec
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rGB/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Sign in to a Wi-Fi network"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Sign in to network"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has no Internet access"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Tap for options"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobile network has no Internet access"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Network has no Internet access"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Private DNS server cannot be accessed"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has limited connectivity"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Tap to connect anyway"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Switched to <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Device uses <xliff:g id="NEW_NETWORK">%1$s</xliff:g> when <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> has no Internet access. Charges may apply."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Switched from <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> to <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"an unknown network type"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"mobile data"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rIN/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..d29e2ec
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rIN/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Sign in to a Wi-Fi network"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Sign in to network"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has no Internet access"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Tap for options"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobile network has no Internet access"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Network has no Internet access"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Private DNS server cannot be accessed"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> has limited connectivity"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Tap to connect anyway"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Switched to <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Device uses <xliff:g id="NEW_NETWORK">%1$s</xliff:g> when <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> has no Internet access. Charges may apply."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Switched from <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> to <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"an unknown network type"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"mobile data"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rXC/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..cd69133
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-en-rXC/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‎‏‎‎‏‎‎‏‏‏‎‎‎‏‏‏‎‎‏‏‏‎‎‏‎‏‎‏‎‏‎‏‏‏‏‎‎‏‎‏‎‏‎‏‏‎‏‎‏‏‏‎‎‏‎‏‎Sign in to Wi-Fi network‎‏‎‎‏‎"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‏‏‎‎‏‎‏‎‏‎‏‏‏‎‏‎‎‎‎‏‎‎‏‏‎‎‎‎‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‎‏‎‏‎‏‎‎Sign in to network‎‏‎‎‏‎"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‎‏‏‏‎‏‏‎‎‏‏‎‏‎‎‏‏‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="NETWORK_SSID">%1$s</xliff:g>‎‏‎‎‏‏‏‎ has no internet access‎‏‎‎‏‎"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‎‏‏‎‏‎‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‎‎Tap for options‎‏‎‎‏‎"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‏‏‎‎‎‏‏‎‏‎‏‏‎‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‏‎‏‎‎‎‎‏‎‏‎‏‎Mobile network has no internet access‎‏‎‎‏‎"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‎‏‏‎‎‏‎‎‏‎‎‎‏‎‏‎‏‏‎‎‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‎Network has no internet access‎‏‎‎‏‎"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‏‎‏‏‎‎‏‏‏‎‎‎‏‎‎‏‎‏‎‎‎‎‏‏‏‎Private DNS server cannot be accessed‎‏‎‎‏‎"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‎‎‎‎‏‎‏‏‎‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="NETWORK_SSID">%1$s</xliff:g>‎‏‎‎‏‏‏‎ has limited connectivity‎‏‎‎‏‎"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‏‎‏‏‎‏‎‏‎‎‏‏‎‎‏‎‏‏‎‏‏‎‎‎‎‎‎‎‎‏‏‏‎‎‎‎‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‎‎‎‎Tap to connect anyway‎‏‎‎‏‎"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‏‎‎‎‎‏‎‎‏‎‎‏‎‏‏‎‎‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‎‎‏‎‎‎‏‎‎‏‏‏‏‎‎‎‎Switched to ‎‏‎‎‏‏‎<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‎‏‏‎‏‎‎‎‏‏‎‎‎‎‎‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‏‎‎‎‏‎‏‏‎‏‎‏‏‎‎‏‎‎‏‎‎Device uses ‎‏‎‎‏‏‎<xliff:g id="NEW_NETWORK">%1$s</xliff:g>‎‏‎‎‏‏‏‎ when ‎‏‎‎‏‏‎<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>‎‏‎‎‏‏‏‎ has no internet access. Charges may apply.‎‏‎‎‏‎"</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‏‏‏‏‏‎‎‏‎‏‎‏‏‏‎‏‎‎‏‎‏‎‏‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‏‏‎Switched from ‎‏‎‎‏‏‎<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>‎‏‎‎‏‏‏‎ to ‎‏‎‎‏‏‎<xliff:g id="NEW_NETWORK">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‏‏‏‏‏‎‎‏‎‏‎‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‎‏‎‏‎‎‎‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎an unknown network type‎‏‎‎‏‎"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‏‎‎‎‎‎‎‎‏‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‏‎‎‏‏‏‏‎‎‏‎‎‎‏‏‏‏‎‏‎mobile data‎‏‎‎‏‎"</item>
+    <item msgid="5520925862115353992">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‏‏‏‎‎‏‎‎‎‏‎‎‏‏‎‏‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎‎‏‎‎‎‎Wi-Fi‎‏‎‎‏‎"</item>
+    <item msgid="1055487873974272842">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‏‎‏‏‏‎‏‏‎‎‎‏‎‏‎‎‎‎‏‎‎‎‏‎‎‎‎‏‏‏‏‏‎‎‎‎‎‎‎‎‎‏‏‎‏‎‎‏‎‏‎‎Bluetooth‎‏‎‎‏‎"</item>
+    <item msgid="1616528372438698248">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‎‏‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‎‎‏‎‎‎‏‎‎‏‎‎‎‎‏‎‎‎‎Ethernet‎‏‎‎‏‎"</item>
+    <item msgid="9177085807664964627">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‎‏‏‏‎‏‏‏‎‏‎‏‏‎‏‏‏‎‏‏‏‎‎‏‎‎‏‏‎‎‎‏‎‎‏‎‎‎‎‎‏‎‎‏‏‎VPN‎‏‎‎‏‎"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-es-rUS/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..9102dc0
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-es-rUS/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Accede a una red Wi-Fi."</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Acceder a la red"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>no tiene acceso a Internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Presiona para ver opciones"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"La red móvil no tiene acceso a Internet"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"La red no tiene acceso a Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"No se puede acceder al servidor DNS privado"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tiene conectividad limitada"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Presiona para conectarte de todas formas"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Se cambió a <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"El dispositivo usa <xliff:g id="NEW_NETWORK">%1$s</xliff:g> cuando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> no tiene acceso a Internet. Es posible que se apliquen cargos."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Se cambió de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> a <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"un tipo de red desconocido"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"Datos móviles"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-es/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-es/strings.xml
new file mode 100644
index 0000000..4c15566
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-es/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Iniciar sesión en red Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Iniciar sesión en la red"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> no tiene acceso a Internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Toca para ver opciones"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"La red móvil no tiene acceso a Internet"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"La red no tiene acceso a Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"No se ha podido acceder al servidor DNS privado"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tiene una conectividad limitada"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Toca para conectarte de todas formas"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Se ha cambiado a <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"El dispositivo utiliza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> cuando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> no tiene acceso a Internet. Es posible que se apliquen cargos."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Se ha cambiado de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> a <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"tipo de red desconocido"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"datos móviles"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-et/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-et/strings.xml
new file mode 100644
index 0000000..398223a
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-et/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Logi sisse WiFi-võrku"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Võrku sisselogimine"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"Võrgul <xliff:g id="NETWORK_SSID">%1$s</xliff:g> puudub Interneti-ühendus"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Puudutage valikute nägemiseks"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobiilsidevõrgul puudub Interneti-ühendus"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Võrgul puudub Interneti-ühendus"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Privaatsele DNS-serverile ei pääse juurde"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"Võrgu <xliff:g id="NETWORK_SSID">%1$s</xliff:g> ühendus on piiratud"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Puudutage, kui soovite siiski ühenduse luua"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Lülitati võrgule <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Seade kasutab võrku <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, kui võrgul <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> puudub juurdepääs Internetile. Rakenduda võivad tasud."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Lülitati võrgult <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> võrgule <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"tundmatu võrgutüüp"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"mobiilne andmeside"</item>
+    <item msgid="5520925862115353992">"WiFi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-eu/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-eu/strings.xml
new file mode 100644
index 0000000..dd70316
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-eu/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Hasi saioa Wi-Fi sarean"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Hasi saioa sarean"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"Ezin da konektatu Internetera <xliff:g id="NETWORK_SSID">%1$s</xliff:g> sarearen bidez"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Sakatu aukerak ikusteko"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Sare mugikorra ezin da konektatu Internetera"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Sarea ezin da konektatu Internetera"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Ezin da atzitu DNS zerbitzari pribatua"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> sareak konektagarritasun murriztua du"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Sakatu hala ere konektatzeko"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> erabiltzen ari zara orain"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> Internetera konektatzeko gauza ez denean, <xliff:g id="NEW_NETWORK">%1$s</xliff:g> erabiltzen du gailuak. Agian kostuak ordaindu beharko dituzu."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> erabiltzen ari zinen, baina <xliff:g id="NEW_NETWORK">%2$s</xliff:g> erabiltzen ari zara orain"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"sare mota ezezaguna"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"datu-konexioa"</item>
+    <item msgid="5520925862115353992">"Wifia"</item>
+    <item msgid="1055487873974272842">"Bluetooth-a"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-fa/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-fa/strings.xml
new file mode 100644
index 0000000..46a946c
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-fa/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"‏ورود به شبکه Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"ورود به سیستم شبکه"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> به اینترنت دسترسی ندارد"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"برای گزینه‌ها ضربه بزنید"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"شبکه تلفن همراه به اینترنت دسترسی ندارد"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"شبکه به اینترنت دسترسی ندارد"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"‏سرور DNS خصوصی قابل دسترسی نیست"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> اتصال محدودی دارد"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"به‌هرصورت، برای اتصال ضربه بزنید"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"به <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> تغییر کرد"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"وقتی <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> به اینترنت دسترسی نداشته باشد، دستگاه از <xliff:g id="NEW_NETWORK">%1$s</xliff:g> استفاده می‌کند. ممکن است هزینه‌هایی اعمال شود."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"از <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> به <xliff:g id="NEW_NETWORK">%2$s</xliff:g> تغییر کرد"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"نوع شبکه نامشخص"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"داده تلفن همراه"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"بلوتوث"</item>
+    <item msgid="1616528372438698248">"اترنت"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-fi/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-fi/strings.xml
new file mode 100644
index 0000000..dd94441
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-fi/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Kirjaudu Wi-Fi-verkkoon"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Kirjaudu verkkoon"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ei ole yhteydessä internetiin"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Näytä vaihtoehdot napauttamalla."</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobiiliverkko ei ole yhteydessä internetiin"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Verkko ei ole yhteydessä internetiin"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Ei pääsyä yksityiselle DNS-palvelimelle"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> toimii rajoitetulla yhteydellä"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Yhdistä napauttamalla"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> otettiin käyttöön"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="NEW_NETWORK">%1$s</xliff:g> otetaan käyttöön, kun <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ei voi muodostaa yhteyttä internetiin. Veloitukset ovat mahdollisia."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> poistettiin käytöstä ja <xliff:g id="NEW_NETWORK">%2$s</xliff:g> otettiin käyttöön."</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"tuntematon verkon tyyppi"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"mobiilidata"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-fr-rCA/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..02ef50b
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-fr-rCA/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Connectez-vous au réseau Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Connectez-vous au réseau"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"Le réseau <xliff:g id="NETWORK_SSID">%1$s</xliff:g> n\'offre aucun accès à Internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Touchez pour afficher les options"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Le réseau cellulaire n\'offre aucun accès à Internet"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Le réseau n\'offre aucun accès à Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Impossible d\'accéder au serveur DNS privé"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"Le réseau <xliff:g id="NETWORK_SSID">%1$s</xliff:g> offre une connectivité limitée"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Touchez pour vous connecter quand même"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Passé au réseau <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"L\'appareil utilise <xliff:g id="NEW_NETWORK">%1$s</xliff:g> quand <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> n\'a pas d\'accès à Internet. Des frais peuvent s\'appliquer."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Passé du réseau <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> au <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"un type de réseau inconnu"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"données cellulaires"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"RPV"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-fr/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-fr/strings.xml
new file mode 100644
index 0000000..08c9d81
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-fr/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Connectez-vous au réseau Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Se connecter au réseau"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"Aucune connexion à Internet pour <xliff:g id="NETWORK_SSID">%1$s</xliff:g>"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Appuyez ici pour afficher des options."</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Le réseau mobile ne dispose d\'aucun accès à Internet"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Le réseau ne dispose d\'aucun accès à Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Impossible d\'accéder au serveur DNS privé"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"La connectivité de <xliff:g id="NETWORK_SSID">%1$s</xliff:g> est limitée"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Appuyer pour se connecter quand même"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Nouveau réseau : <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"L\'appareil utilise <xliff:g id="NEW_NETWORK">%1$s</xliff:g> lorsque <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> n\'a pas de connexion Internet. Des frais peuvent s\'appliquer."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Ancien réseau : <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>. Nouveau réseau : <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"type de réseau inconnu"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"données mobiles"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-gl/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-gl/strings.xml
new file mode 100644
index 0000000..9f98055
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-gl/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Inicia sesión na rede wifi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Inicia sesión na rede"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> non ten acceso a Internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Toca para ver opcións."</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"A rede de telefonía móbil non ten acceso a Internet"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"A rede non ten acceso a Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Non se puido acceder ao servidor DNS privado"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"A conectividade de <xliff:g id="NETWORK_SSID">%1$s</xliff:g> é limitada"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Toca para conectarte de todas formas"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Cambiouse a: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"O dispositivo utiliza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> cando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> non ten acceso a Internet. Pódense aplicar cargos."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Cambiouse de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> a <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"un tipo de rede descoñecido"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"datos móbiles"</item>
+    <item msgid="5520925862115353992">"wifi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-gu/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-gu/strings.xml
new file mode 100644
index 0000000..4ae5a2c
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-gu/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"વાઇ-ફાઇ નેટવર્ક પર સાઇન ઇન કરો"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"નેટવર્ક પર સાઇન ઇન કરો"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ઇન્ટરનેટ ઍક્સેસ ધરાવતું નથી"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"વિકલ્પો માટે ટૅપ કરો"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"મોબાઇલ નેટવર્ક કોઈ ઇન્ટરનેટ ઍક્સેસ ધરાવતું નથી"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"નેટવર્ક કોઈ ઇન્ટરનેટ ઍક્સેસ ધરાવતું નથી"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"ખાનગી DNS સર્વર ઍક્સેસ કરી શકાતા નથી"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> મર્યાદિત કનેક્ટિવિટી ધરાવે છે"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"છતાં કનેક્ટ કરવા માટે ટૅપ કરો"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> પર સ્વિચ કર્યું"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"જ્યારે <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> પાસે કોઈ ઇન્ટરનેટ ઍક્સેસ ન હોય ત્યારે ઉપકરણ <xliff:g id="NEW_NETWORK">%1$s</xliff:g>નો ઉપયોગ કરે છે. શુલ્ક લાગુ થઈ શકે છે."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> પરથી <xliff:g id="NEW_NETWORK">%2$s</xliff:g> પર સ્વિચ કર્યું"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"અજાણ્યો નેટવર્ક પ્રકાર"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"મોબાઇલ ડેટા"</item>
+    <item msgid="5520925862115353992">"વાઇ-ફાઇ"</item>
+    <item msgid="1055487873974272842">"બ્લૂટૂથ"</item>
+    <item msgid="1616528372438698248">"ઇથરનેટ"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-hi/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-hi/strings.xml
new file mode 100644
index 0000000..eff1b60
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-hi/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"वाई-फ़ाई  नेटवर्क में साइन इन करें"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"नेटवर्क में साइन इन करें"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> का इंटरनेट नहीं चल रहा है"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"विकल्पों के लिए टैप करें"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"मोबाइल नेटवर्क पर इंटरनेट ऐक्सेस नहीं है"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"इस नेटवर्क पर इंटरनेट ऐक्सेस नहीं है"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"निजी डीएनएस सर्वर को ऐक्सेस नहीं किया जा सकता"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> की कनेक्टिविटी सीमित है"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"फिर भी कनेक्ट करने के लिए टैप करें"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> पर ले जाया गया"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> में इंटरनेट की सुविधा नहीं होने पर डिवाइस <xliff:g id="NEW_NETWORK">%1$s</xliff:g> का इस्तेमाल करता है. इसके लिए शुल्क लिया जा सकता है."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> से <xliff:g id="NEW_NETWORK">%2$s</xliff:g> पर ले जाया गया"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"अज्ञात नेटवर्क प्रकार"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"मोबाइल डेटा"</item>
+    <item msgid="5520925862115353992">"वाई-फ़ाई"</item>
+    <item msgid="1055487873974272842">"ब्लूटूथ"</item>
+    <item msgid="1616528372438698248">"ईथरनेट"</item>
+    <item msgid="9177085807664964627">"वीपीएन"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-hr/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-hr/strings.xml
new file mode 100644
index 0000000..52bfb93
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-hr/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Prijava na Wi-Fi mrežu"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Prijava na mrežu"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nema pristup internetu"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Dodirnite za opcije"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobilna mreža nema pristup internetu"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Mreža nema pristup internetu"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Nije moguće pristupiti privatnom DNS poslužitelju"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ima ograničenu povezivost"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Dodirnite da biste se ipak povezali"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Prelazak na drugu mrežu: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Kada <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nema pristup internetu, na uređaju se upotrebljava <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Moguća je naplata naknade."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Mreža je promijenjena: <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> &gt; <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"nepoznata vrsta mreže"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"mobilni podaci"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-hu/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-hu/strings.xml
new file mode 100644
index 0000000..2ff59b5
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-hu/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Bejelentkezés Wi-Fi hálózatba"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Bejelentkezés a hálózatba"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"A(z) <xliff:g id="NETWORK_SSID">%1$s</xliff:g> hálózaton nincs internet-hozzáférés"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Koppintson a beállítások megjelenítéséhez"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"A mobilhálózaton nincs internet-hozzáférés"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"A hálózaton nincs internet-hozzáférés"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"A privát DNS-kiszolgálóhoz nem lehet hozzáférni"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"A(z) <xliff:g id="NETWORK_SSID">%1$s</xliff:g> hálózat korlátozott kapcsolatot biztosít"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Koppintson, ha mindenképpen csatlakozni szeretne"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Átváltva erre: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="NEW_NETWORK">%1$s</xliff:g> használata, ha nincs internet-hozzáférés <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>-kapcsolaton keresztül. A szolgáltató díjat számíthat fel."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Átváltva <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>-hálózatról erre: <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"ismeretlen hálózati típus"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"mobiladatok"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-hy/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-hy/strings.xml
new file mode 100644
index 0000000..b35d31c
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-hy/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Մուտք գործեք Wi-Fi ցանց"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Մուտք գործեք ցանց"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ցանցը չունի մուտք ինտերնետին"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Հպեք՝ ընտրանքները տեսնելու համար"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Բջջային ցանցը չի ապահովում ինտերնետ կապ"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Ցանցը միացված չէ ինտերնետին"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Մասնավոր DNS սերվերն անհասանելի է"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ցանցի կապը սահմանափակ է"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Հպեք՝ միանալու համար"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Անցել է <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ցանցի"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Երբ <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ցանցում ինտերնետ կապ չի լինում, սարքն անցնում է <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ցանցի: Նման դեպքում կարող են վճարներ գանձվել:"</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ցանցից անցել է <xliff:g id="NEW_NETWORK">%2$s</xliff:g> ցանցի"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"ցանցի անհայտ տեսակ"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"բջջային ինտերնետ"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-in/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-in/strings.xml
new file mode 100644
index 0000000..27d7d89
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-in/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Login ke jaringan Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Login ke jaringan"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tidak memiliki akses internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Ketuk untuk melihat opsi"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Jaringan seluler tidak memiliki akses internet"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Jaringan tidak memiliki akses internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Server DNS pribadi tidak dapat diakses"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> memiliki konektivitas terbatas"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Ketuk untuk tetap menyambungkan"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Dialihkan ke <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Perangkat menggunakan <xliff:g id="NEW_NETWORK">%1$s</xliff:g> jika <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> tidak memiliki akses internet. Tarif mungkin berlaku."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Dialihkan dari <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ke <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"jenis jaringan yang tidak dikenal"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"data seluler"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-is/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-is/strings.xml
new file mode 100644
index 0000000..97f42dc
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-is/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Skrá inn á Wi-Fi net"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Skrá inn á net"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> er ekki með internetaðgang"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Ýttu til að sjá valkosti"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Farsímakerfið er ekki tengt við internetið"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Netkerfið er ekki tengt við internetið"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Ekki næst í DNS-einkaþjón"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"Tengigeta <xliff:g id="NETWORK_SSID">%1$s</xliff:g> er takmörkuð"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Ýttu til að tengjast samt"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Skipt yfir á <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Tækið notar <xliff:g id="NEW_NETWORK">%1$s</xliff:g> þegar <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> er ekki með internetaðgang. Gjöld kunna að eiga við."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Skipt úr <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> yfir í <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"óþekkt tegund netkerfis"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"farsímagögn"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-it/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-it/strings.xml
new file mode 100644
index 0000000..7836101
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-it/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Accedi a rete Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Accedi alla rete"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> non ha accesso a Internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Tocca per le opzioni"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"La rete mobile non ha accesso a Internet"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"La rete non ha accesso a Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Non è possibile accedere al server DNS privato"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ha una connettività limitata"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Tocca per connettere comunque"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Passato a <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Il dispositivo utilizza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> quando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> non ha accesso a Internet. Potrebbero essere applicati costi."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Passato da <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> a <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"tipo di rete sconosciuto"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"dati mobili"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-iw/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-iw/strings.xml
new file mode 100644
index 0000000..f322b99
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-iw/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"‏היכנס לרשת Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"היכנס לרשת"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"ל-<xliff:g id="NETWORK_SSID">%1$s</xliff:g> אין גישה לאינטרנט"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"הקש לקבלת אפשרויות"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"לרשת הסלולרית אין גישה לאינטרנט"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"לרשת אין גישה לאינטרנט"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"‏לא ניתן לגשת לשרת DNS הפרטי"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"הקישוריות של <xliff:g id="NETWORK_SSID">%1$s</xliff:g> מוגבלת"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"כדי להתחבר למרות זאת יש להקיש"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"מעבר אל <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"המכשיר משתמש ברשת <xliff:g id="NEW_NETWORK">%1$s</xliff:g> כשלרשת <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> אין גישה לאינטרנט. עשויים לחול חיובים."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"עבר מרשת <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> לרשת <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"סוג רשת לא מזוהה"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"חבילת גלישה"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ja/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ja/strings.xml
new file mode 100644
index 0000000..1aa3216
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ja/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Wi-Fiネットワークにログイン"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"ネットワークにログインしてください"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> はインターネットにアクセスできません"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"タップしてその他のオプションを表示"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"モバイル ネットワークがインターネットに接続されていません"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"ネットワークがインターネットに接続されていません"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"プライベート DNS サーバーにアクセスできません"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> の接続が制限されています"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"接続するにはタップしてください"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"「<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>」に切り替えました"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"デバイスで「<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>」によるインターネット接続ができない場合に「<xliff:g id="NEW_NETWORK">%1$s</xliff:g>」を使用します。通信料が発生することがあります。"</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"「<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>」から「<xliff:g id="NEW_NETWORK">%2$s</xliff:g>」に切り替えました"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"不明なネットワーク タイプ"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"モバイルデータ"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"イーサネット"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ka/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ka/strings.xml
new file mode 100644
index 0000000..61d21b5
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ka/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Wi-Fi ქსელთან დაკავშირება"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"ქსელში შესვლა"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>-ს არ აქვს ინტერნეტზე წვდომა"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"შეეხეთ ვარიანტების სანახავად"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"მობილურ ქსელს არ აქვს ინტერნეტზე წვდომა"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"ქსელს არ აქვს ინტერნეტზე წვდომა"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"პირად DNS სერვერზე წვდომა შეუძლებელია"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>-ის კავშირები შეზღუდულია"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"შეეხეთ, თუ მაინც გსურთ დაკავშირება"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"ახლა გამოიყენება <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"თუ <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ინტერნეტთან კავშირს დაკარგავს, მოწყობილობის მიერ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> იქნება გამოყენებული, რამაც შეიძლება დამატებითი ხარჯები გამოიწვიოს."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"ახლა გამოიყენება <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> (გამოიყენებოდა <xliff:g id="NEW_NETWORK">%2$s</xliff:g>)"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"უცნობი ტიპის ქსელი"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"მობილური ინტერნეტი"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-kk/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-kk/strings.xml
new file mode 100644
index 0000000..969aaef
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-kk/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Wi-Fi желісіне кіру"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Желіге кіру"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> желісінің интернетті пайдалану мүмкіндігі шектеулі."</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Опциялар үшін түртіңіз"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Мобильдік желі интернетке қосылмаған."</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Желі интернетке қосылмаған."</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Жеке DNS серверіне кіру мүмкін емес."</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> желісінің қосылу мүмкіндігі шектеулі."</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Бәрібір жалғау үшін түртіңіз."</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> желісіне ауысты"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Құрылғы <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> желісінде интернетпен байланыс жоғалған жағдайда <xliff:g id="NEW_NETWORK">%1$s</xliff:g> желісін пайдаланады. Деректер ақысы алынуы мүмкін."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> желісінен <xliff:g id="NEW_NETWORK">%2$s</xliff:g> желісіне ауысты"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"желі түрі белгісіз"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"мобильдік деректер"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-km/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-km/strings.xml
new file mode 100644
index 0000000..da3c337
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-km/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"ចូល​បណ្ដាញ​វ៉ាយហ្វាយ"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"ចូលទៅបណ្តាញ"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> មិនមាន​ការតភ្ជាប់អ៊ីនធឺណិត​ទេ"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"ប៉ះសម្រាប់ជម្រើស"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"បណ្ដាញ​ទូរសព្ទ​ចល័ត​មិនមានការតភ្ជាប់​អ៊ីនធឺណិតទេ"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"បណ្ដាញ​មិនមាន​ការតភ្ជាប់​អ៊ីនធឺណិតទេ"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"មិនអាច​ចូលប្រើ​ម៉ាស៊ីនមេ DNS ឯកជន​បានទេ"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> មានការតភ្ជាប់​មានកម្រិត"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"មិន​អី​ទេ ចុច​​ភ្ជាប់​ចុះ"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"បានប្តូរទៅ <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"ឧបករណ៍​ប្រើ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> នៅ​ពេល​ដែល <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> មិនមាន​ការ​តភ្ជាប់​អ៊ីនធឺណិត។ អាច​គិតថ្លៃ​លើការ​ប្រើប្រាស់​ទិន្នន័យ។"</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"បានប្តូរពី <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ទៅ <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"ប្រភេទបណ្តាញមិនស្គាល់"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"ទិន្នន័យ​ទូរសព្ទចល័ត"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"ប៊្លូធូស"</item>
+    <item msgid="1616528372438698248">"អ៊ីសឺរណិត"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-kn/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-kn/strings.xml
new file mode 100644
index 0000000..3b5e047
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-kn/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"ವೈ-ಫೈ ನೆಟ್‍ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಸಂಪರ್ಕವನ್ನು ಹೊಂದಿಲ್ಲ"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"ಆಯ್ಕೆಗಳಿಗೆ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"ಮೊಬೈಲ್ ನೆಟ್‌ವರ್ಕ್‌ ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿಲ್ಲ"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"ನೆಟ್‌ವರ್ಕ್‌ ಇಂಟರ್ನೆಟ್‌ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿಲ್ಲ"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"ಖಾಸಗಿ DNS ಸರ್ವರ್ ಅನ್ನು ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ಸೀಮಿತ ಸಂಪರ್ಕ ಕಲ್ಪಿಸುವಿಕೆಯನ್ನು ಹೊಂದಿದೆ"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"ಹೇಗಾದರೂ ಸಂಪರ್ಕಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ಗೆ ಬದಲಾಯಿಸಲಾಗಿದೆ"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶ ಹೊಂದಿಲ್ಲದಿರುವಾಗ, ಸಾಧನವು <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ಬಳಸುತ್ತದೆ. ಶುಲ್ಕಗಳು ಅನ್ವಯವಾಗಬಹುದು."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ರಿಂದ <xliff:g id="NEW_NETWORK">%2$s</xliff:g> ಗೆ ಬದಲಾಯಿಸಲಾಗಿದೆ"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"ಅಪರಿಚಿತ ನೆಟ್‌ವರ್ಕ್ ಪ್ರಕಾರ"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"ಮೊಬೈಲ್ ಡೇಟಾ"</item>
+    <item msgid="5520925862115353992">"ವೈ-ಫೈ"</item>
+    <item msgid="1055487873974272842">"ಬ್ಲೂಟೂತ್‌"</item>
+    <item msgid="1616528372438698248">"ಇಥರ್ನೆಟ್"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ko/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ko/strings.xml
new file mode 100644
index 0000000..874bd75
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ko/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Wi-Fi 네트워크에 로그인"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"네트워크에 로그인"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>이(가) 인터넷에 액세스할 수 없습니다."</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"탭하여 옵션 보기"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"모바일 네트워크에 인터넷이 연결되어 있지 않습니다."</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"네트워크에 인터넷이 연결되어 있지 않습니다."</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"비공개 DNS 서버에 액세스할 수 없습니다."</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>에서 연결을 제한했습니다."</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"계속 연결하려면 탭하세요."</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>(으)로 전환"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>(으)로 인터넷에 연결할 수 없는 경우 기기에서 <xliff:g id="NEW_NETWORK">%1$s</xliff:g>이(가) 사용됩니다. 요금이 부과될 수 있습니다."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>에서 <xliff:g id="NEW_NETWORK">%2$s</xliff:g>(으)로 전환"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"알 수 없는 네트워크 유형"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"모바일 데이터"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"블루투스"</item>
+    <item msgid="1616528372438698248">"이더넷"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ky/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ky/strings.xml
new file mode 100644
index 0000000..1ace4dc
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ky/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Wi-Fi түйүнүнө кирүү"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Тармакка кирүү"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> Интернетке туташуусу жок"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Параметрлерди ачуу үчүн таптап коюңуз"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Мобилдик Интернет жок"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Тармактын Интернет жок"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Жеке DNS сервери жеткиликсиз"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> байланышы чектелген"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Баары бир туташуу үчүн таптаңыз"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> тармагына которуштурулду"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> тармагы Интернетке туташпай турганда, түзмөгүңүз <xliff:g id="NEW_NETWORK">%1$s</xliff:g> тармагын колдонот. Акы алынышы мүмкүн."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> дегенден <xliff:g id="NEW_NETWORK">%2$s</xliff:g> тармагына которуштурулду"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"белгисиз тармак түрү"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"мобилдик трафик"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-lo/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-lo/strings.xml
new file mode 100644
index 0000000..3db497e
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-lo/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"ເຂົ້າສູ່ລະບົບເຄືອຂ່າຍ Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"ລົງຊື່ເຂົ້າເຄືອຂ່າຍ"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ບໍ່ມີການເຊື່ອມຕໍ່ອິນເຕີເນັດ"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"ແຕະເພື່ອເບິ່ງຕົວເລືອກ"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"ເຄືອຂ່າຍມືຖືບໍ່ສາມາດເຂົ້າເຖິງອິນເຕີເນັດໄດ້"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"ເຄືອຂ່າຍບໍ່ສາມາດເຂົ້າເຖິງອິນເຕີເນັດໄດ້"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"ບໍ່ສາມາດເຂົ້າເຖິງເຊີບເວີ DNS ສ່ວນຕົວໄດ້"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ມີການເຊື່ອມຕໍ່ທີ່ຈຳກັດ"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"ແຕະເພື່ອຢືນຢັນການເຊື່ອມຕໍ່"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"ສະຫຼັບໄປໃຊ້ <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ແລ້ວ"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"ອຸປະກອນຈະໃຊ້ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ເມື່ອ <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ບໍ່ມີການເຊື່ອມຕໍ່ອິນເຕີເນັດ. ອາດມີການຮຽກເກັບຄ່າບໍລິການ."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"ສະຫຼັບຈາກ <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ໄປໃຊ້ <xliff:g id="NEW_NETWORK">%2$s</xliff:g> ແລ້ວ"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"ບໍ່ຮູ້ຈັກປະເພດເຄືອຂ່າຍ"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"ອິນເຕີເນັດມືຖື"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"ອີເທີເນັດ"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-lt/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-lt/strings.xml
new file mode 100644
index 0000000..c639c1f
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-lt/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Prisijungti prie „Wi-Fi“ tinklo"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Prisijungti prie tinklo"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"„<xliff:g id="NETWORK_SSID">%1$s</xliff:g>“ negali pasiekti interneto"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Palieskite, kad būtų rodomos parinktys."</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobiliojo ryšio tinkle nėra prieigos prie interneto"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Tinkle nėra prieigos prie interneto"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Privataus DNS serverio negalima pasiekti"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"„<xliff:g id="NETWORK_SSID">%1$s</xliff:g>“ ryšys apribotas"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Palieskite, jei vis tiek norite prisijungti"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Perjungta į tinklą <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Įrenginyje naudojamas kitas tinklas (<xliff:g id="NEW_NETWORK">%1$s</xliff:g>), kai dabartiniame tinkle (<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>) nėra interneto ryšio. Gali būti taikomi mokesčiai."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Perjungta iš tinklo <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> į tinklą <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"nežinomas tinklo tipas"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"mobiliojo ryšio duomenys"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Eternetas"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-lv/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-lv/strings.xml
new file mode 100644
index 0000000..5774603
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-lv/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Pierakstieties Wi-Fi tīklā"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Pierakstīšanās tīklā"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"Tīklā <xliff:g id="NETWORK_SSID">%1$s</xliff:g> nav piekļuves internetam"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Pieskarieties, lai skatītu iespējas."</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobilajā tīklā nav piekļuves internetam."</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Tīklā nav piekļuves internetam."</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Nevar piekļūt privātam DNS serverim."</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"Tīklā <xliff:g id="NETWORK_SSID">%1$s</xliff:g> ir ierobežota savienojamība"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Lai tik un tā izveidotu savienojumu, pieskarieties"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Pārslēdzās uz tīklu <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Kad vienā tīklā (<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>) nav piekļuves internetam, ierīcē tiek izmantots cits tīkls (<xliff:g id="NEW_NETWORK">%1$s</xliff:g>). Var tikt piemērota maksa."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Pārslēdzās no tīkla <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> uz tīklu <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"nezināms tīkla veids"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"mobilie dati"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mcc204-mnc04/config.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mcc204-mnc04/config.xml
new file mode 100644
index 0000000..7e7025f
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mcc204-mnc04/config.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!-- Configuration values for ConnectivityService
+     DO NOT EDIT THIS FILE for specific device configuration; instead, use a Runtime Resources
+     Overlay package following the overlayable.xml configuration in the same directory:
+     https://source.android.com/devices/architecture/rros -->
+<resources>
+    <!-- Whether the device should automatically switch away from Wi-Fi networks that lose
+         Internet access. Actual device behaviour is controlled by
+         Settings.Global.NETWORK_AVOID_BAD_WIFI. This is the default value of that setting. -->
+    <integer translatable="false" name="config_networkAvoidBadWifi">0</integer>
+</resources>
\ No newline at end of file
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mcc310-mnc004/config.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mcc310-mnc004/config.xml
new file mode 100644
index 0000000..7e7025f
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mcc310-mnc004/config.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!-- Configuration values for ConnectivityService
+     DO NOT EDIT THIS FILE for specific device configuration; instead, use a Runtime Resources
+     Overlay package following the overlayable.xml configuration in the same directory:
+     https://source.android.com/devices/architecture/rros -->
+<resources>
+    <!-- Whether the device should automatically switch away from Wi-Fi networks that lose
+         Internet access. Actual device behaviour is controlled by
+         Settings.Global.NETWORK_AVOID_BAD_WIFI. This is the default value of that setting. -->
+    <integer translatable="false" name="config_networkAvoidBadWifi">0</integer>
+</resources>
\ No newline at end of file
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mcc311-mnc480/config.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mcc311-mnc480/config.xml
new file mode 100644
index 0000000..7e7025f
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mcc311-mnc480/config.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!-- Configuration values for ConnectivityService
+     DO NOT EDIT THIS FILE for specific device configuration; instead, use a Runtime Resources
+     Overlay package following the overlayable.xml configuration in the same directory:
+     https://source.android.com/devices/architecture/rros -->
+<resources>
+    <!-- Whether the device should automatically switch away from Wi-Fi networks that lose
+         Internet access. Actual device behaviour is controlled by
+         Settings.Global.NETWORK_AVOID_BAD_WIFI. This is the default value of that setting. -->
+    <integer translatable="false" name="config_networkAvoidBadWifi">0</integer>
+</resources>
\ No newline at end of file
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mk/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mk/strings.xml
new file mode 100644
index 0000000..053c7cf
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mk/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Најавете се на мрежа на Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Најавете се на мрежа"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> нема интернет-пристап"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Допрете за опции"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Мобилната мрежа нема интернет-пристап"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Мрежата нема интернет-пристап"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Не може да се пристапи до приватниот DNS-сервер"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> има ограничена поврзливост"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Допрете за да се поврзете и покрај тоа"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Префрлено на <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Уредот користи <xliff:g id="NEW_NETWORK">%1$s</xliff:g> кога <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> нема пристап до интернет. Може да се наплатат трошоци."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Префрлено од <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> на <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"непознат тип мрежа"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"мобилен интернет"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Етернет"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ml/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ml/strings.xml
new file mode 100644
index 0000000..3e80cf1
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ml/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"വൈഫൈ നെറ്റ്‌വർക്കിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"നെറ്റ്‌വർക്കിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> എന്നതിന് ഇന്റർനെറ്റ് ആക്‌സസ് ഇല്ല"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"ഓപ്ഷനുകൾക്ക് ടാപ്പുചെയ്യുക"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"മൊബെെൽ നെറ്റ്‌വർക്കിന് ഇന്റർനെറ്റ് ആക്‌സസ് ഇല്ല"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"നെറ്റ്‌വർക്കിന് ഇന്റർനെറ്റ് ആക്‌സസ് ഇല്ല"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"സ്വകാര്യ DNS സെർവർ ആക്‌സസ് ചെയ്യാനാവില്ല"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> എന്നതിന് പരിമിതമായ കണക്റ്റിവിറ്റി ഉണ്ട്"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"ഏതുവിധേനയും കണക്‌റ്റ് ചെയ്യാൻ ടാപ്പ് ചെയ്യുക"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> എന്നതിലേക്ക് മാറി"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>-ന് ഇന്റർനെറ്റ് ആക്‌സസ് ഇല്ലാത്തപ്പോൾ ഉപകരണം <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ഉപയോഗിക്കുന്നു. നിരക്കുകൾ ബാധകമായേക്കാം."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> നെറ്റ്‌വർക്കിൽ നിന്ന് <xliff:g id="NEW_NETWORK">%2$s</xliff:g> നെറ്റ്‌വർക്കിലേക്ക് മാറി"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"തിരിച്ചറിയാനാകാത്ത ഒരു നെറ്റ്‌വർക്ക് തരം"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"മൊബൈൽ ഡാറ്റ"</item>
+    <item msgid="5520925862115353992">"വൈഫൈ"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"ഇതര്‍നെറ്റ്"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mn/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mn/strings.xml
new file mode 100644
index 0000000..214fc0c
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mn/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Wi-Fi сүлжээнд нэвтэрнэ үү"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Сүлжээнд нэвтэрнэ үү"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>-д интернэтийн хандалт алга"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Сонголт хийхийн тулд товшино уу"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Мобайл сүлжээнд интернэт хандалт байхгүй байна"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Сүлжээнд интернэт хандалт байхгүй байна"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Хувийн DNS серверт хандах боломжгүй байна"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> зарим үйлчилгээнд хандах боломжгүй байна"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Ямар ч тохиолдолд холбогдохын тулд товших"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> руу шилжүүлсэн"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> интернет холболтгүй үед төхөөрөмж <xliff:g id="NEW_NETWORK">%1$s</xliff:g>-г ашигладаг. Төлбөр гарч болзошгүй."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>-с <xliff:g id="NEW_NETWORK">%2$s</xliff:g> руу шилжүүлсэн"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"сүлжээний тодорхойгүй төрөл"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"мобайл дата"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Этернэт"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-mr/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mr/strings.xml
new file mode 100644
index 0000000..c4b1998
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-mr/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"वाय-फाय नेटवर्कमध्‍ये साइन इन करा"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"नेटवर्कवर साइन इन करा"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ला इंटरनेट अ‍ॅक्सेस नाही"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"पर्यायांसाठी टॅप करा"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"मोबाइल नेटवर्कला इंटरनेट ॲक्सेस नाही"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"नेटवर्कला इंटरनेट ॲक्सेस नाही"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"खाजगी DNS सर्व्हर ॲक्सेस करू शकत नाही"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ला मर्यादित कनेक्टिव्हिटी आहे"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"तरीही कनेक्ट करण्यासाठी टॅप करा"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> वर स्विच केले"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> कडे इंटरनेटचा अ‍ॅक्सेस नसताना डिव्हाइस <xliff:g id="NEW_NETWORK">%1$s</xliff:g> वापरते. शुल्क लागू शकते."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> वरून <xliff:g id="NEW_NETWORK">%2$s</xliff:g> वर स्विच केले"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"अज्ञात नेटवर्क प्रकार"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"मोबाइल डेटा"</item>
+    <item msgid="5520925862115353992">"वाय-फाय"</item>
+    <item msgid="1055487873974272842">"ब्लूटूथ"</item>
+    <item msgid="1616528372438698248">"इथरनेट"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ms/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ms/strings.xml
new file mode 100644
index 0000000..529d0bd
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ms/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Log masuk ke rangkaian Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Log masuk ke rangkaian"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tiada akses Internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Ketik untuk mendapatkan pilihan"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Rangkaian mudah alih tiada akses Internet"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Rangkaian tiada akses Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Pelayan DNS peribadi tidak boleh diakses"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> mempunyai kesambungan terhad"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Ketik untuk menyambung juga"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Beralih kepada <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Peranti menggunakan <xliff:g id="NEW_NETWORK">%1$s</xliff:g> apabila <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> tiada akses Internet. Bayaran mungkin dikenakan."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Beralih daripada <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> kepada <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"jenis rangkaian tidak diketahui"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"data mudah alih"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-my/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-my/strings.xml
new file mode 100644
index 0000000..50590fa
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-my/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"ဝိုင်ဖိုင်ကွန်ရက်သို့ လက်မှတ်ထိုးဝင်ပါ"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"ကွန်ယက်သို့ လက်မှတ်ထိုးဝင်ရန်"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> တွင် အင်တာနက်အသုံးပြုခွင့် မရှိပါ"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"အခြားရွေးချယ်စရာများကိုကြည့်ရန် တို့ပါ"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"မိုဘိုင်းကွန်ရက်တွင် အင်တာနက်ချိတ်ဆက်မှု မရှိပါ"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"ကွန်ရက်တွင် အင်တာနက်အသုံးပြုခွင့် မရှိပါ"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"သီးသန့် ဒီအန်အက်စ် (DNS) ဆာဗာကို သုံး၍မရပါ။"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> တွင် ချိတ်ဆက်မှုကို ကန့်သတ်ထားသည်"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"မည်သို့ပင်ဖြစ်စေ ချိတ်ဆက်ရန် တို့ပါ"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> သို့ ပြောင်းလိုက်ပြီ"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ဖြင့် အင်တာနက် အသုံးမပြုနိုင်သည့်အချိန်တွင် စက်ပစ္စည်းသည် <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ကို သုံးပါသည်။ ဒေတာသုံးစွဲခ ကျသင့်နိုင်ပါသည်။"</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> မှ <xliff:g id="NEW_NETWORK">%2$s</xliff:g> သို့ ပြောင်းလိုက်ပြီ"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"အမည်မသိကွန်ရက်အမျိုးအစား"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"မိုဘိုင်းဒေတာ"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"ဘလူးတုသ်"</item>
+    <item msgid="1616528372438698248">"အီသာနက်"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-nb/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-nb/strings.xml
new file mode 100644
index 0000000..b89d198
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-nb/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Logg på Wi-Fi-nettverket"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Logg på nettverk"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har ingen internettilkobling"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Trykk for å få alternativer"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobilnettverket har ingen internettilgang"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Nettverket har ingen internettilgang"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Den private DNS-tjeneren kan ikke nås"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har begrenset tilkobling"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Trykk for å koble til likevel"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Byttet til <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Enheten bruker <xliff:g id="NEW_NETWORK">%1$s</xliff:g> når <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ikke har Internett-tilgang. Avgifter kan påløpe."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Byttet fra <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> til <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"en ukjent nettverkstype"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"mobildata"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ne/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ne/strings.xml
new file mode 100644
index 0000000..bdcfa3b
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ne/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Wi-Fi नेटवर्कमा साइन इन गर्नुहोस्"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"सञ्जालमा साइन इन गर्नुहोस्"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> को इन्टरनेटमाथि पहुँच छैन"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"विकल्पहरूका लागि ट्याप गर्नुहोस्"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"मोबाइल नेटवर्कको इन्टरनेटमाथि पहुँच छैन"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"नेटवर्कको इन्टरनेटमाथि पहुँच छैन"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"निजी DNS सर्भरमाथि पहुँच प्राप्त गर्न सकिँदैन"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> को जडान सीमित छ"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"जसरी भए पनि जडान गर्न ट्याप गर्नुहोस्"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> मा बदल्नुहोस्"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> मार्फत इन्टरनेटमाथि पहुँच राख्न नसकेको अवस्थामा यन्त्रले <xliff:g id="NEW_NETWORK">%1$s</xliff:g> प्रयोग गर्दछ। शुल्क लाग्न सक्छ।"</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> बाट <xliff:g id="NEW_NETWORK">%2$s</xliff:g> मा परिवर्तन गरियो"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"नेटवर्कको कुनै अज्ञात प्रकार"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"मोबाइल डेटा"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"ब्लुटुथ"</item>
+    <item msgid="1616528372438698248">"इथरनेट"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-nl/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-nl/strings.xml
new file mode 100644
index 0000000..8ecff6e
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-nl/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Inloggen bij wifi-netwerk"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Inloggen bij netwerk"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> heeft geen internettoegang"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Tik voor opties"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobiel netwerk heeft geen internettoegang"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Netwerk heeft geen internettoegang"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Geen toegang tot privé-DNS-server"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> heeft beperkte connectiviteit"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Tik om toch verbinding te maken"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Overgeschakeld naar <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Apparaat gebruikt <xliff:g id="NEW_NETWORK">%1$s</xliff:g> wanneer <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> geen internetverbinding heeft. Er kunnen kosten in rekening worden gebracht."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Overgeschakeld van <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> naar <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"een onbekend netwerktype"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"mobiele data"</item>
+    <item msgid="5520925862115353992">"Wifi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-or/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-or/strings.xml
new file mode 100644
index 0000000..6ec1f9d
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-or/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"ୱାଇ-ଫାଇ ନେଟୱର୍କରେ ସାଇନ୍‍-ଇନ୍‍ କରନ୍ତୁ"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"ନେଟ୍‌ୱର୍କରେ ସାଇନ୍‍ ଇନ୍‍ କରନ୍ତୁ"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>ର ଇଣ୍ଟର୍ନେଟ୍ ଆକ୍ସେସ୍ ନାହିଁ"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"ବିକଳ୍ପ ପାଇଁ ଟାପ୍‍ କରନ୍ତୁ"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"ମୋବାଇଲ୍ ନେଟ୍‌ୱାର୍କରେ ଇଣ୍ଟର୍ନେଟ୍ ଆକ୍ସେସ୍ ନାହିଁ"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"ନେଟ୍‌ୱାର୍କରେ ଇଣ୍ଟର୍ନେଟ୍ ଆକ୍ସେସ୍ ନାହିଁ"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"ବ୍ୟକ୍ତିଗତ DNS ସର୍ଭର୍ ଆକ୍ସେସ୍ କରିହେବ ନାହିଁ"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>ର ସୀମିତ ସଂଯୋଗ ଅଛି"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"ତଥାପି ଯୋଗାଯୋଗ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>କୁ ବଦଳାଗଲା"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>ର ଇଣ୍ଟରନେଟ୍‍ ଆକ୍ସେସ୍ ନଥିବାବେଳେ ଡିଭାଇସ୍‍ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ବ୍ୟବହାର କରିଥାଏ। ଶୁଳ୍କ ଲାଗୁ ହୋଇପାରେ।"</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ରୁ <xliff:g id="NEW_NETWORK">%2$s</xliff:g>କୁ ବଦଳାଗଲା"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"ଏକ ଅଜଣା ନେଟ୍‌ୱର୍କ ପ୍ରକାର"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"ମୋବାଇଲ୍‌ ଡାଟା"</item>
+    <item msgid="5520925862115353992">"ୱାଇ-ଫାଇ"</item>
+    <item msgid="1055487873974272842">"ବ୍ଲୁଟୁଥ"</item>
+    <item msgid="1616528372438698248">"ଇଥରନେଟ୍‌"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pa/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pa/strings.xml
new file mode 100644
index 0000000..e948193
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pa/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ \'ਤੇ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"ਨੈੱਟਵਰਕ \'ਤੇ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ਕੋਲ ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"ਵਿਕਲਪਾਂ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਕੋਲ ਇੰਟਰਨੈੱਟ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"ਨੈੱਟਵਰਕ ਕੋਲ ਇੰਟਰਨੈੱਟ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"ਨਿੱਜੀ ਡੋਮੇਨ ਨਾਮ ਪ੍ਰਣਾਲੀ (DNS) ਸਰਵਰ \'ਤੇ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕੀ"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ਕੋਲ ਸੀਮਤ ਕਨੈਕਟੀਵਿਟੀ ਹੈ"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"ਫਿਰ ਵੀ ਕਨੈਕਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"ਬਦਲਕੇ <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ਲਿਆਂਦਾ ਗਿਆ"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ਦੀ ਇੰਟਰਨੈੱਟ \'ਤੇ ਪਹੁੰਚ ਨਾ ਹੋਣ \'ਤੇ ਡੀਵਾਈਸ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ। ਖਰਚੇ ਲਾਗੂ ਹੋ ਸਕਦੇ ਹਨ।"</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ਤੋਂ ਬਦਲਕੇ <xliff:g id="NEW_NETWORK">%2$s</xliff:g> \'ਤੇ ਕੀਤਾ ਗਿਆ"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"ਇੱਕ ਅਗਿਆਤ ਨੈੱਟਵਰਕ ਕਿਸਮ"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"ਮੋਬਾਈਲ ਡਾਟਾ"</item>
+    <item msgid="5520925862115353992">"ਵਾਈ-ਫਾਈ"</item>
+    <item msgid="1055487873974272842">"ਬਲੂਟੁੱਥ"</item>
+    <item msgid="1616528372438698248">"ਈਥਰਨੈੱਟ"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pl/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pl/strings.xml
new file mode 100644
index 0000000..038328f
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pl/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Zaloguj się w sieci Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Zaloguj się do sieci"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nie ma dostępu do internetu"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Kliknij, by wyświetlić opcje"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Sieć komórkowa nie ma dostępu do internetu"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Sieć nie ma dostępu do internetu"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Brak dostępu do prywatnego serwera DNS"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ma ograniczoną łączność"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Kliknij, by mimo to nawiązać połączenie"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Zmieniono na połączenie typu <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Urządzenie korzysta z połączenia typu <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, gdy <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nie dostępu do internetu. Mogą zostać naliczone opłaty."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Przełączono z połączenia typu <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na <xliff:g id="NEW_NETWORK">%2$s</xliff:g>."</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"nieznany typ sieci"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"mobilna transmisja danych"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt-rBR/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..fe37405
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt-rBR/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Fazer login na rede Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Fazer login na rede"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> não tem acesso à Internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Toque para ver opções"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"A rede móvel não tem acesso à Internet"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"A rede não tem acesso à Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Não é possível acessar o servidor DNS privado"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tem conectividade limitada"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Toque para conectar mesmo assim"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Alternado para <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"O dispositivo usa <xliff:g id="NEW_NETWORK">%1$s</xliff:g> quando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> não tem acesso à Internet. Esse serviço pode ser cobrado."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Alternado de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> para <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"um tipo de rede desconhecido"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"dados móveis"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt-rPT/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..69060f7
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt-rPT/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Iniciar sessão na rede Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Início de sessão na rede"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> não tem acesso à Internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Toque para obter mais opções"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"A rede móvel não tem acesso à Internet"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"A rede não tem acesso à Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Não é possível aceder ao servidor DNS."</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tem conetividade limitada."</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Toque para ligar mesmo assim."</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Mudou para <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"O dispositivo utiliza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> quando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> não tem acesso à Internet. Podem aplicar-se custos."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Mudou de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> para <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"um tipo de rede desconhecido"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"dados móveis"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt/strings.xml
new file mode 100644
index 0000000..fe37405
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-pt/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Fazer login na rede Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Fazer login na rede"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> não tem acesso à Internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Toque para ver opções"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"A rede móvel não tem acesso à Internet"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"A rede não tem acesso à Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Não é possível acessar o servidor DNS privado"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tem conectividade limitada"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Toque para conectar mesmo assim"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Alternado para <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"O dispositivo usa <xliff:g id="NEW_NETWORK">%1$s</xliff:g> quando <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> não tem acesso à Internet. Esse serviço pode ser cobrado."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Alternado de <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> para <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"um tipo de rede desconhecido"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"dados móveis"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ro/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ro/strings.xml
new file mode 100644
index 0000000..227b7be
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ro/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Conectați-vă la rețeaua Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Conectați-vă la rețea"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nu are acces la internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Atingeți pentru opțiuni"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Rețeaua mobilă nu are acces la internet"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Rețeaua nu are acces la internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Serverul DNS privat nu poate fi accesat"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> are conectivitate limitată"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Atingeți pentru a vă conecta oricum"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"S-a comutat la <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Dispozitivul folosește <xliff:g id="NEW_NETWORK">%1$s</xliff:g> când <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nu are acces la internet. Se pot aplica taxe."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"S-a comutat de la <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> la <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"un tip de rețea necunoscut"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"date mobile"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ru/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ru/strings.xml
new file mode 100644
index 0000000..18acf81
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ru/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Подключение к Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Регистрация в сети"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"Сеть \"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>\" не подключена к Интернету"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Нажмите, чтобы показать варианты."</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Мобильная сеть не подключена к Интернету"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Сеть не подключена к Интернету"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Доступа к частному DNS-серверу нет."</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"Подключение к сети \"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>\" ограничено"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Нажмите, чтобы подключиться"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Новое подключение: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Устройство использует <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, если подключение к сети <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> недоступно. Может взиматься плата за передачу данных."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Устройство отключено от сети <xliff:g id="NEW_NETWORK">%2$s</xliff:g> и теперь использует <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"неизвестный тип сети"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"мобильный Интернет"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-si/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-si/strings.xml
new file mode 100644
index 0000000..6307c2b
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-si/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Wi-Fi ජාලයට පුරනය වන්න"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"ජාලයට පුරනය වන්න"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> හට අන්තර්ජාල ප්‍රවේශය නැත"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"විකල්ප සඳහා තට්ටු කරන්න"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"ජංගම ජාලවලට අන්තර්ජාල ප්‍රවේශය නැත"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"ජාලයට අන්තර්ජාල ප්‍රවේශය නැත"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"පුද්ගලික DNS සේවාදායකයට ප්‍රවේශ වීමට නොහැකිය"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> හට සීමිත සබැඳුම් හැකියාවක් ඇත"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"කෙසේ වෙතත් ඉදිරියට යාමට තට්ටු කරන්න"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> වෙත මාරු විය"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"උපාංගය <xliff:g id="NEW_NETWORK">%1$s</xliff:g> <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> සඳහා අන්තර්ජාල ප්‍රවේශය නැති විට භාවිත කරයි. ගාස්තු අදාළ විය හැකිය."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> සිට <xliff:g id="NEW_NETWORK">%2$s</xliff:g> වෙත මාරු විය"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"නොදන්නා ජාල වර්ගයකි"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"ජංගම දත්ත"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"බ්ලූටූත්"</item>
+    <item msgid="1616528372438698248">"ඊතර්නෙට්"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sk/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sk/strings.xml
new file mode 100644
index 0000000..e894fef
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sk/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Prihlásiť sa do siete Wi‑Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Prihlásenie do siete"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nemá prístup k internetu"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Klepnutím získate možnosti"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobilná sieť nemá prístup k internetu"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Sieť nemá prístup k internetu"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"K súkromnému serveru DNS sa nepodarilo získať prístup"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> má obmedzené pripojenie"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Ak sa chcete aj napriek tomu pripojiť, klepnite"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Prepnuté na sieť: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Keď <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nemá prístup k internetu, zariadenie používa <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Môžu sa účtovať poplatky."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Prepnuté zo siete <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na sieť <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"neznámy typ siete"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"mobilné dáta"</item>
+    <item msgid="5520925862115353992">"Wi‑Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sl/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sl/strings.xml
new file mode 100644
index 0000000..954b324
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sl/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Prijavite se v omrežje Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Prijava v omrežje"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"Omrežje <xliff:g id="NETWORK_SSID">%1$s</xliff:g> nima dostopa do interneta"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Dotaknite se za možnosti"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobilno omrežje nima dostopa do interneta"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Omrežje nima dostopa do interneta"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Do zasebnega strežnika DNS ni mogoče dostopati"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"Povezljivost omrežja <xliff:g id="NETWORK_SSID">%1$s</xliff:g> je omejena"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Dotaknite se, da kljub temu vzpostavite povezavo"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Preklopljeno na omrežje vrste <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Naprava uporabi omrežje vrste <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, ko omrežje vrste <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nima dostopa do interneta. Prenos podatkov se lahko zaračuna."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Preklopljeno z omrežja vrste <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na omrežje vrste <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"neznana vrsta omrežja"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"prenos podatkov v mobilnem omrežju"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sq/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sq/strings.xml
new file mode 100644
index 0000000..bd5d052
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sq/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Identifikohu në rrjetin Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Identifikohu në rrjet"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nuk ka qasje në internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Trokit për opsionet"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Rrjeti celular nuk ka qasje në internet"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Rrjeti nuk ka qasje në internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Serveri privat DNS nuk mund të qaset"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ka lidhshmëri të kufizuar"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Trokit për t\'u lidhur gjithsesi"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Kaloi te <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Pajisja përdor <xliff:g id="NEW_NETWORK">%1$s</xliff:g> kur <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> nuk ka qasje në internet. Mund të zbatohen tarifa."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Kaloi nga <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> te <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"një lloj rrjeti i panjohur"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"të dhënat celulare"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Eternet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sr/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sr/strings.xml
new file mode 100644
index 0000000..8bedbff
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sr/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Пријављивање на WiFi мрежу"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Пријавите се на мрежу"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> нема приступ интернету"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Додирните за опције"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Мобилна мрежа нема приступ интернету"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Мрежа нема приступ интернету"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Приступ приватном DNS серверу није успео"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> има ограничену везу"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Додирните да бисте се ипак повезали"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Прешли сте на тип мреже <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Уређај користи тип мреже <xliff:g id="NEW_NETWORK">%1$s</xliff:g> када тип мреже <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> нема приступ интернету. Можда ће се наплаћивати трошкови."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Прешли сте са типа мреже <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> на тип мреже <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"непознат тип мреже"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"мобилни подаци"</item>
+    <item msgid="5520925862115353992">"WiFi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Етернет"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sv/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sv/strings.xml
new file mode 100644
index 0000000..b3f1763
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sv/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Logga in på ett Wi-Fi-nätverk"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Logga in på nätverket"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har ingen internetanslutning"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Tryck för alternativ"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobilnätverket har ingen internetanslutning"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Nätverket har ingen internetanslutning"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Det går inte att komma åt den privata DNS-servern."</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> har begränsad anslutning"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Tryck för att ansluta ändå"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Byte av nätverk till <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="NEW_NETWORK">%1$s</xliff:g> används på enheten när det inte finns internetåtkomst via <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>. Avgifter kan tillkomma."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Byte av nätverk från <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> till <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"en okänd nätverkstyp"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"mobildata"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-sw/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sw/strings.xml
new file mode 100644
index 0000000..9674654
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-sw/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Ingia kwa mtandao wa Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Ingia katika mtandao"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> haina uwezo wa kufikia intaneti"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Gusa ili upate chaguo"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mtandao wa simu hauna uwezo wa kufikia intaneti"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Mtandao hauna uwezo wa kufikia intaneti"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Seva ya faragha ya DNS haiwezi kufikiwa"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ina muunganisho unaofikia huduma chache."</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Gusa ili uunganishe tu"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Sasa inatumia <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Kifaa hutumia <xliff:g id="NEW_NETWORK">%1$s</xliff:g> wakati <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> haina intaneti. Huenda ukalipishwa."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Imebadilisha mtandao kutoka <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> na sasa inatumia <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"aina ya mtandao isiyojulikana"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"data ya simu"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethaneti"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ta/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ta/strings.xml
new file mode 100644
index 0000000..12604cb
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ta/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"வைஃபை நெட்வொர்க்கில் உள்நுழையவும்"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"நெட்வொர்க்கில் உள்நுழையவும்"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> நெட்வொர்க்கிற்கு இணைய அணுகல் இல்லை"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"விருப்பங்களுக்கு, தட்டவும்"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"மொபைல் நெட்வொர்க்கிற்கு இணைய அணுகல் இல்லை"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"நெட்வொர்க்கிற்கு இணைய அணுகல் இல்லை"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"தனிப்பட்ட DNS சேவையகத்தை அணுக இயலாது"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> வரம்பிற்கு உட்பட்ட இணைப்புநிலையைக் கொண்டுள்ளது"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"எப்படியேனும் இணைப்பதற்குத் தட்டவும்"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>க்கு மாற்றப்பட்டது"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> நெட்வொர்க்கில் இண்டர்நெட் அணுகல் இல்லாததால், சாதனமானது <xliff:g id="NEW_NETWORK">%1$s</xliff:g> நெட்வொர்க்கைப் பயன்படுத்துகிறது. கட்டணங்கள் விதிக்கப்படலாம்."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> இலிருந்து <xliff:g id="NEW_NETWORK">%2$s</xliff:g>க்கு மாற்றப்பட்டது"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"தெரியாத நெட்வொர்க் வகை"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"மொபைல் டேட்டா"</item>
+    <item msgid="5520925862115353992">"வைஃபை"</item>
+    <item msgid="1055487873974272842">"புளூடூத்"</item>
+    <item msgid="1616528372438698248">"ஈத்தர்நெட்"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-te/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-te/strings.xml
new file mode 100644
index 0000000..84a8640
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-te/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Wi-Fi నెట్‌వర్క్‌కి సైన్ ఇన్ చేయండి"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"నెట్‌వర్క్‌కి సైన్ ఇన్ చేయండి"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>కి ఇంటర్నెట్ యాక్సెస్ లేదు"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"ఎంపికల కోసం నొక్కండి"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"మొబైల్ నెట్‌వర్క్‌కు ఇంటర్నెట్ యాక్సెస్ లేదు"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"నెట్‌వర్క్‌కు ఇంటర్నెట్ యాక్సెస్ లేదు"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"ప్రైవేట్ DNS సర్వర్‌ను యాక్సెస్ చేయడం సాధ్యపడదు"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> పరిమిత కనెక్టివిటీని కలిగి ఉంది"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"ఏదేమైనా కనెక్ట్ చేయడానికి నొక్కండి"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>కి మార్చబడింది"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"పరికరం <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>కి ఇంటర్నెట్ యాక్సెస్ లేనప్పుడు <xliff:g id="NEW_NETWORK">%1$s</xliff:g>ని ఉపయోగిస్తుంది. ఛార్జీలు వర్తించవచ్చు."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> నుండి <xliff:g id="NEW_NETWORK">%2$s</xliff:g>కి మార్చబడింది"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"తెలియని నెట్‌వర్క్ రకం"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"మొబైల్ డేటా"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"బ్లూటూత్"</item>
+    <item msgid="1616528372438698248">"ఈథర్‌నెట్"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-th/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-th/strings.xml
new file mode 100644
index 0000000..1616e51
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-th/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"ลงชื่อเข้าใช้เครือข่าย WiFi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"ลงชื่อเข้าใช้เครือข่าย"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> เข้าถึงอินเทอร์เน็ตไม่ได้"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"แตะเพื่อดูตัวเลือก"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"เครือข่ายมือถือไม่มีการเข้าถึงอินเทอร์เน็ต"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"เครือข่ายไม่มีการเข้าถึงอินเทอร์เน็ต"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"เข้าถึงเซิร์ฟเวอร์ DNS ไม่ได้"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> มีการเชื่อมต่อจำกัด"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"แตะเพื่อเชื่อมต่อ"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"เปลี่ยนเป็น <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"อุปกรณ์จะใช้ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> เมื่อ <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> เข้าถึงอินเทอร์เน็ตไม่ได้ โดยอาจมีค่าบริการ"</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"เปลี่ยนจาก <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> เป็น <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"ประเภทเครือข่ายที่ไม่รู้จัก"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"เน็ตมือถือ"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"บลูทูธ"</item>
+    <item msgid="1616528372438698248">"อีเทอร์เน็ต"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-tl/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-tl/strings.xml
new file mode 100644
index 0000000..3bf1ce4
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-tl/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Mag-sign in sa Wi-Fi network"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Mag-sign in sa network"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"Walang access sa internet ang <xliff:g id="NETWORK_SSID">%1$s</xliff:g>"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"I-tap para sa mga opsyon"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Walang access sa internet ang mobile network"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Walang access sa internet ang network"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Hindi ma-access ang pribadong DNS server"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"Limitado ang koneksyon ng <xliff:g id="NETWORK_SSID">%1$s</xliff:g>"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"I-tap para kumonekta pa rin"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Lumipat sa <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Ginagamit ng device ang <xliff:g id="NEW_NETWORK">%1$s</xliff:g> kapag walang access sa internet ang <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>. Maaaring may mga malapat na singilin."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Lumipat sa <xliff:g id="NEW_NETWORK">%2$s</xliff:g> mula sa <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"isang hindi kilalang uri ng network"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"mobile data"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-tr/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-tr/strings.xml
new file mode 100644
index 0000000..5c326e5
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-tr/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Kablosuz ağda oturum açın"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Ağda oturum açın"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ağının internet bağlantısı yok"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Seçenekler için dokunun"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobil ağın internet bağlantısı yok"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Ağın internet bağlantısı yok"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Gizli DNS sunucusuna erişilemiyor"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> sınırlı bağlantıya sahip"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Yine de bağlanmak için dokunun"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> ağına geçildi"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> ağının internet erişimi olmadığında cihaz <xliff:g id="NEW_NETWORK">%1$s</xliff:g> ağını kullanır. Bunun için ödeme alınabilir."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> ağından <xliff:g id="NEW_NETWORK">%2$s</xliff:g> ağına geçildi"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"bilinmeyen ağ türü"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"mobil veri"</item>
+    <item msgid="5520925862115353992">"Kablosuz"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-uk/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-uk/strings.xml
new file mode 100644
index 0000000..d1382da
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-uk/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Вхід у мережу Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Вхід у мережу"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"Мережа <xliff:g id="NETWORK_SSID">%1$s</xliff:g> не має доступу до Інтернету"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Торкніться, щоб відкрити опції"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Мобільна мережа не має доступу до Інтернету"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Мережа не має доступу до Інтернету"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Немає доступу до приватного DNS-сервера"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"Підключення до мережі <xliff:g id="NETWORK_SSID">%1$s</xliff:g> обмежено"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Натисніть, щоб усе одно підключитися"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Пристрій перейшов на мережу <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Коли мережа <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> не має доступу до Інтернету, використовується <xliff:g id="NEW_NETWORK">%1$s</xliff:g>. Може стягуватися плата."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Пристрій перейшов з мережі <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> на мережу <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"невідомий тип мережі"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"мобільне передавання даних"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"Мережа VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-ur/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ur/strings.xml
new file mode 100644
index 0000000..3c031ad
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-ur/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"‏Wi-Fi نیٹ ورک میں سائن ان کریں"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"نیٹ ورک میں سائن ان کریں"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> کو انٹرنیٹ تک رسائی حاصل نہیں ہے"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"اختیارات کیلئے تھپتھپائیں"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"موبائل نیٹ ورک کو انٹرنیٹ تک رسائی حاصل نہیں ہے"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"نیٹ ورک کو انٹرنیٹ تک رسائی حاصل نہیں ہے"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"‏نجی DNS سرور تک رسائی حاصل نہیں کی جا سکی"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> کی کنیکٹوٹی محدود ہے"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"بہر حال منسلک کرنے کے لیے تھپتھپائیں"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> پر سوئچ ہو گیا"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"جب <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> کو انٹرنیٹ تک رسائی نہیں ہوتی ہے تو آلہ <xliff:g id="NEW_NETWORK">%1$s</xliff:g> کا استعمال کرتا ہے۔ چارجز لاگو ہو سکتے ہیں۔"</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> سے <xliff:g id="NEW_NETWORK">%2$s</xliff:g> پر سوئچ ہو گیا"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"نیٹ ورک کی نامعلوم قسم"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"موبائل ڈیٹا"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"بلوٹوتھ"</item>
+    <item msgid="1616528372438698248">"ایتھرنیٹ"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-uz/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-uz/strings.xml
new file mode 100644
index 0000000..7518db3
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-uz/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Wi-Fi tarmoqqa kirish"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Tarmoqqa kirish"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nomli tarmoqda internetga ruxsati yoʻq"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Variantlarni ko‘rsatish uchun bosing"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mobil tarmoq internetga ulanmagan"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Tarmoq internetga ulanmagan"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Xususiy DNS server ishlamayapti"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nomli tarmoqda aloqa cheklangan"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Baribir ulash uchun bosing"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Yangi ulanish: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Agar <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> tarmoqda internet uzilsa, qurilma <xliff:g id="NEW_NETWORK">%1$s</xliff:g>ga ulanadi. Sarflangan trafik uchun haq olinishi mumkin."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> tarmog‘idan <xliff:g id="NEW_NETWORK">%2$s</xliff:g> tarmog‘iga o‘tildi"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"noma’lum tarmoq turi"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"mobil internet"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-vi/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-vi/strings.xml
new file mode 100644
index 0000000..d2284d4
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-vi/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Đăng nhập vào mạng Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Đăng nhập vào mạng"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> không có quyền truy cập Internet"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Nhấn để biết tùy chọn"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Mạng di động không có quyền truy cập Internet"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Mạng không có quyền truy cập Internet"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Không thể truy cập máy chủ DNS riêng tư"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> có khả năng kết nối giới hạn"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Nhấn để tiếp tục kết nối"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Đã chuyển sang <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Thiết bị sử dụng <xliff:g id="NEW_NETWORK">%1$s</xliff:g> khi <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> không có quyền truy cập Internet. Bạn có thể phải trả phí."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Đã chuyển từ <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> sang <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"loại mạng không xác định"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"dữ liệu di động"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"Bluetooth"</item>
+    <item msgid="1616528372438698248">"Ethernet"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rCN/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..813482b
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rCN/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"登录到WLAN网络"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"登录到网络"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> 无法访问互联网"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"点按即可查看相关选项"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"此移动网络无法访问互联网"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"此网络无法访问互联网"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"无法访问私人 DNS 服务器"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> 的连接受限"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"点按即可继续连接"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"已切换至<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"设备会在<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>无法访问互联网时使用<xliff:g id="NEW_NETWORK">%1$s</xliff:g>(可能需要支付相应的费用)。"</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"已从<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>切换至<xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"未知网络类型"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"移动数据"</item>
+    <item msgid="5520925862115353992">"WLAN"</item>
+    <item msgid="1055487873974272842">"蓝牙"</item>
+    <item msgid="1616528372438698248">"以太网"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rHK/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..676404f
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rHK/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"登入 Wi-Fi 網絡"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"登入網絡"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>未有連接至互聯網"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"輕按即可查看選項"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"流動網絡並未連接互聯網"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"網絡並未連接互聯網"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"無法存取私人 DNS 伺服器"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>連線受限"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"仍要輕按以連結至此網絡"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"已切換至<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"裝置會在 <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> 無法連線至互聯網時使用<xliff:g id="NEW_NETWORK">%1$s</xliff:g> (可能需要支付相關費用)。"</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"已從<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>切換至<xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"不明網絡類型"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"流動數據"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"藍牙"</item>
+    <item msgid="1616528372438698248">"以太網"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rTW/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..f355138
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-zh-rTW/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"登入 Wi-Fi 網路"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"登入網路"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> 沒有網際網路連線"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"輕觸即可查看選項"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"這個行動網路沒有網際網路連線"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"這個網路沒有網際網路連線"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"無法存取私人 DNS 伺服器"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> 的連線能力受限"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"輕觸即可繼續連線"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"已切換至<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"裝置會在無法連上「<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g>」時切換至「<xliff:g id="NEW_NETWORK">%1$s</xliff:g>」(可能需要支付相關費用)。"</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"已從 <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> 切換至<xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"不明的網路類型"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"行動數據"</item>
+    <item msgid="5520925862115353992">"Wi-Fi"</item>
+    <item msgid="1055487873974272842">"藍牙"</item>
+    <item msgid="1616528372438698248">"乙太網路"</item>
+    <item msgid="9177085807664964627">"VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values-zu/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values-zu/strings.xml
new file mode 100644
index 0000000..55fefb7
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values-zu/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_available_sign_in" msgid="381054692557675237">"Ngena ngemvume kunethiwekhi ye-Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="1520342291829283114">"Ngena ngemvume kunethiwekhi"</string>
+    <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
+    <string name="wifi_no_internet" msgid="1386911698276448061">"I-<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ayinakho ukufinyelela kwe-inthanethi"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"Thepha ukuze uthole izinketho"</string>
+    <string name="mobile_no_internet" msgid="4014455157529909781">"Inethiwekhi yeselula ayinakho ukufinyelela kwe-inthanethi"</string>
+    <string name="other_networks_no_internet" msgid="6698711684200067033">"Inethiwekhi ayinakho ukufinyelela kwenethiwekhi"</string>
+    <string name="private_dns_broken_detailed" msgid="3709388271074611847">"Iseva eyimfihlo ye-DNS ayikwazi ukufinyelelwa"</string>
+    <string name="network_partial_connectivity" msgid="4791024923851432291">"I-<xliff:g id="NETWORK_SSID">%1$s</xliff:g> inokuxhumeka okukhawulelwe"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"Thepha ukuze uxhume noma kunjalo"</string>
+    <string name="network_switch_metered" msgid="1531869544142283384">"Kushintshelwe ku-<xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
+    <string name="network_switch_metered_detail" msgid="1358296010128405906">"Idivayisi isebenzisa i-<xliff:g id="NEW_NETWORK">%1$s</xliff:g> uma i-<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> inganakho ukufinyelela kwe-inthanethi. Kungasebenza izindleko."</string>
+    <string name="network_switch_metered_toast" msgid="501662047275723743">"Kushintshelewe kusuka ku-<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> kuya ku-<xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
+    <string name="network_switch_type_name_unknown" msgid="3665696841646851068">"uhlobo olungaziwa lwenethiwekhi"</string>
+  <string-array name="network_switch_type_name">
+    <item msgid="2255670471736226365">"idatha yeselula"</item>
+    <item msgid="5520925862115353992">"I-Wi-Fi"</item>
+    <item msgid="1055487873974272842">"I-Bluetooth"</item>
+    <item msgid="1616528372438698248">"I-Ethernet"</item>
+    <item msgid="9177085807664964627">"I-VPN"</item>
+  </string-array>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values/config.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values/config.xml
index 06c8192..71674e4 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values/config.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values/config.xml
@@ -52,4 +52,41 @@
         <item>12,60000</item><!-- mobile_cbs -->
     </string-array>
 
-</resources>
\ No newline at end of file
+    <!-- Whether the APF Filter in the device should filter out IEEE 802.3 Frames
+         Those frames are identified by the field Eth-type having values
+         less than 0x600 -->
+    <bool translatable="false" name="config_apfDrop802_3Frames">true</bool>
+
+    <!-- An array of Denylisted EtherType, packets with EtherTypes within this array
+         will be dropped
+         TODO: need to put proper values, these are for testing purposes only -->
+    <integer-array translatable="false" name="config_apfEthTypeDenyList">
+        <item>0x88A2</item>
+        <item>0x88A4</item>
+        <item>0x88B8</item>
+        <item>0x88CD</item>
+        <item>0x88E3</item>
+    </integer-array>
+
+    <!-- Default supported concurrent socket keepalive slots per transport type, used by
+         ConnectivityManager.createSocketKeepalive() for calculating the number of keepalive
+         offload slots that should be reserved for privileged access. This string array should be
+         overridden by the device to present the capability of creating socket keepalives. -->
+    <!-- An Array of "[NetworkCapabilities.TRANSPORT_*],[supported keepalives] -->
+    <string-array translatable="false" name="config_networkSupportedKeepaliveCount">
+        <item>0,1</item>
+        <item>1,3</item>
+    </string-array>
+
+
+    <!-- Default value for ConnectivityManager.getMultipathPreference() on metered networks. Actual
+         device behaviour is controlled by the metered multipath preference in
+         ConnectivitySettingsManager. This is the default value of that setting. -->
+    <integer translatable="false" name="config_networkMeteredMultipathPreference">0</integer>
+
+    <!-- Whether the device should automatically switch away from Wi-Fi networks that lose
+         Internet access. Actual device behaviour is controlled by
+         Settings.Global.NETWORK_AVOID_BAD_WIFI. This is the default value of that setting. -->
+    <integer translatable="false" name="config_networkAvoidBadWifi">1</integer>
+
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values/overlayable.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values/overlayable.xml
index da8aee5..25e19ce 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values/overlayable.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values/overlayable.xml
@@ -21,6 +21,11 @@
             <item type="string" name="config_networkCaptivePortalServerUrl"/>
             <item type="integer" name="config_networkTransitionTimeout"/>
             <item type="array" name="config_wakeonlan_supported_interfaces"/>
+            <item type="bool" name="config_apfDrop802_3Frames"/>
+            <item type="array" name="config_apfEthTypeDenyList"/>
+            <item type="integer" name="config_networkMeteredMultipathPreference"/>
+            <item type="array" name="config_networkSupportedKeepaliveCount"/>
+            <item type="integer" name="config_networkAvoidBadWifi"/>
 
         </policy>
     </overlayable>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values/strings.xml
index 2c7b992..b2fa5f5 100644
--- a/packages/Connectivity/service/ServiceConnectivityResources/res/values/strings.xml
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values/strings.xml
@@ -14,9 +14,61 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<resources>
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <!-- The System Connectivity Resources package is an internal system package that provides
          configuration values for system networking that were pre-configured in the device. This
          is the name of the package to display in the list of system apps. [CHAR LIMIT=40] -->
     <string name="connectivityResourcesAppLabel">System Connectivity Resources</string>
-</resources>
\ No newline at end of file
+
+    <!-- A notification is shown when a wifi captive portal network is detected.  This is the notification's title. -->
+    <string name="wifi_available_sign_in">Sign in to Wi-Fi network</string>
+
+    <!-- A notification is shown when a captive portal network is detected.  This is the notification's title. -->
+    <string name="network_available_sign_in">Sign in to network</string>
+
+    <!-- A notification is shown when a captive portal network is detected.  This is the notification's message. -->
+    <string name="network_available_sign_in_detailed"><xliff:g id="network_ssid">%1$s</xliff:g></string>
+
+    <!-- A notification is shown when the user connects to a Wi-Fi network and the system detects that that network has no Internet access. This is the notification's title. -->
+    <string name="wifi_no_internet"><xliff:g id="network_ssid" example="GoogleGuest">%1$s</xliff:g> has no internet access</string>
+
+    <!-- A notification is shown when the user connects to a Wi-Fi network and the system detects that that network has no Internet access. This is the notification's message. -->
+    <string name="wifi_no_internet_detailed">Tap for options</string>
+
+    <!-- A notification is shown when the user connects to a mobile network without internet access. This is the notification's title. -->
+    <string name="mobile_no_internet">Mobile network has no internet access</string>
+
+    <!-- A notification is shown when the user connects to a non-mobile and non-wifi network without internet access. This is the notification's title. -->
+    <string name="other_networks_no_internet">Network has no internet access</string>
+
+    <!-- A notification is shown when connected network without internet due to private dns validation failed. This is the notification's message. [CHAR LIMIT=NONE] -->
+    <string name="private_dns_broken_detailed">Private DNS server cannot be accessed</string>
+
+    <!-- A notification is shown when the user connects to a network that doesn't have access to some services (e.g. Push notifications may not work). This is the notification's title. [CHAR LIMIT=50] -->
+    <string name="network_partial_connectivity"><xliff:g id="network_ssid" example="GoogleGuest">%1$s</xliff:g> has limited connectivity</string>
+
+    <!-- A notification is shown when the user connects to a network that doesn't have access to some services (e.g. Push notifications may not work). This is the notification's message. [CHAR LIMIT=50] -->
+    <string name="network_partial_connectivity_detailed">Tap to connect anyway</string>
+
+    <!-- A notification might be shown if the device switches to another network type (e.g., mobile data) because it detects that the network it was using (e.g., Wi-Fi) has lost Internet connectivity. This is the notification's title. %1$s is the network type that the device switched to, e.g., cellular data. It is one of the strings in the network_switch_type_name array. -->
+    <string name="network_switch_metered">Switched to <xliff:g id="network_type">%1$s</xliff:g></string>
+
+    <!-- A notification might be shown if the device switches to another network type (e.g., mobile data) because it detects that the network it was using (e.g., Wi-Fi) has lost Internet connectivity. This is the notification's message. %1$s is the network that the device switched to, e.g., cellular data. %2$s is the network type the device switched from, e.g., Wi-Fi. Both are strings in the network_switch_type_name array. -->
+    <string name="network_switch_metered_detail">Device uses <xliff:g id="new_network">%1$s</xliff:g> when <xliff:g id="previous_network">%2$s</xliff:g> has no internet access. Charges may apply.</string>
+
+    <!-- A toast might be shown if the device switches to another network type (e.g., mobile data) because it detects that the network it was using (e.g., Wi-Fi) has lost Internet connectivity. This is the text of the toast. %1$s is the network that the device switched from, e.g., Wi-Fi. %2$s is the network type the device switched from, e.g., cellular data. Both are strings in the network_switch_type_name array. -->
+    <string name="network_switch_metered_toast">Switched from <xliff:g id="previous_network">%1$s</xliff:g> to <xliff:g id="new_network">%2$s</xliff:g></string>
+
+    <!-- Network type names used in the network_switch_metered and network_switch_metered_detail strings. These must be kept in the sync with the values NetworkCapabilities.TRANSPORT_xxx values, and in the same order. -->
+    <string-array name="network_switch_type_name">
+        <item>mobile data</item>
+        <item>Wi-Fi</item>
+        <item>Bluetooth</item>
+        <item>Ethernet</item>
+        <item>VPN</item>
+    </string-array>
+
+    <!-- Network type name displayed if one of the types is not found in network_switch_type_name. -->
+    <string name="network_switch_type_name_unknown">an unknown network type</string>
+
+</resources>
diff --git a/packages/Connectivity/service/jarjar-rules.txt b/packages/Connectivity/service/jarjar-rules.txt
index a7b419b..5caa11b 100644
--- a/packages/Connectivity/service/jarjar-rules.txt
+++ b/packages/Connectivity/service/jarjar-rules.txt
@@ -12,3 +12,6 @@
 # the one in com.android.internal.util
 rule android.util.IndentingPrintWriter* android.connectivity.util.IndentingPrintWriter@1
 rule com.android.internal.util.** com.android.connectivity.util.@1
+
+rule com.android.internal.messages.** com.android.connectivity.messages.@1
+rule com.google.protobuf.** com.android.connectivity.protobuf.@1
diff --git a/packages/Connectivity/service/proto/connectivityproto.proto b/packages/Connectivity/service/proto/connectivityproto.proto
new file mode 100644
index 0000000..a992d7c
--- /dev/null
+++ b/packages/Connectivity/service/proto/connectivityproto.proto
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+// Connectivity protos can be created in this directory. Note this file must be included before
+// building system-messages-proto, otherwise it will not build by itself.
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 3fed29a..b7ce2a3 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -367,6 +367,7 @@
     <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
     <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
     <uses-permission android:name="android.permission.BIND_RESUME_ON_REBOOT_SERVICE" />
+    <uses-permission android:name="android.permission.MANAGE_APP_HIBERNATION"/>
 
     <application android:label="@string/app_label"
                 android:theme="@android:style/Theme.DeviceDefault.DayNight"
diff --git a/services/core/Android.bp b/services/core/Android.bp
index f91e692..c40afbfe 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -209,7 +209,6 @@
         "java/com/android/server/TestNetworkService.java",
         "java/com/android/server/connectivity/AutodestructReference.java",
         "java/com/android/server/connectivity/ConnectivityConstants.java",
-        "java/com/android/server/connectivity/ConnectivityResources.java",
         "java/com/android/server/connectivity/DnsManager.java",
         "java/com/android/server/connectivity/KeepaliveTracker.java",
         "java/com/android/server/connectivity/LingerMonitor.java",
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 58a921f..6fcb3f7 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -69,11 +69,14 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
+import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION;
+import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS;
+import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_TEST;
 import static android.net.NetworkCapabilities.TRANSPORT_VPN;
-import static android.net.NetworkPolicyManager.RULE_NONE;
-import static android.net.NetworkPolicyManager.uidRulesToString;
+import static android.net.NetworkPolicyManager.BLOCKED_REASON_NONE;
+import static android.net.NetworkPolicyManager.blockedReasonsToString;
 import static android.net.NetworkRequest.Type.LISTEN_FOR_BEST;
 import static android.net.shared.NetworkMonitorUtils.isPrivateDnsValidationRequired;
 import static android.os.Process.INVALID_UID;
@@ -106,6 +109,8 @@
 import android.net.ConnectivityDiagnosticsManager.DataStallReport;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
+import android.net.ConnectivityManager.RestrictBackgroundStatus;
+import android.net.ConnectivityResources;
 import android.net.ConnectivitySettingsManager;
 import android.net.DataStallReportParcelable;
 import android.net.DnsResolverServiceManager;
@@ -115,9 +120,9 @@
 import android.net.IDnsResolver;
 import android.net.INetd;
 import android.net.INetworkActivityListener;
+import android.net.INetworkAgent;
 import android.net.INetworkMonitor;
 import android.net.INetworkMonitorCallbacks;
-import android.net.INetworkPolicyListener;
 import android.net.IOnCompleteListener;
 import android.net.IQosCallback;
 import android.net.ISocketKeepaliveCallback;
@@ -135,6 +140,7 @@
 import android.net.NetworkInfo.DetailedState;
 import android.net.NetworkMonitorManager;
 import android.net.NetworkPolicyManager;
+import android.net.NetworkPolicyManager.NetworkPolicyCallback;
 import android.net.NetworkProvider;
 import android.net.NetworkRequest;
 import android.net.NetworkScore;
@@ -208,7 +214,6 @@
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 
-import com.android.connectivity.aidl.INetworkAgent;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.IndentingPrintWriter;
@@ -222,7 +227,6 @@
 import com.android.net.module.util.NetworkCapabilitiesUtils;
 import com.android.net.module.util.PermissionUtils;
 import com.android.server.connectivity.AutodestructReference;
-import com.android.server.connectivity.ConnectivityResources;
 import com.android.server.connectivity.DnsManager;
 import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate;
 import com.android.server.connectivity.KeepaliveTracker;
@@ -237,7 +241,6 @@
 import com.android.server.connectivity.ProfileNetworkPreferences;
 import com.android.server.connectivity.ProxyTracker;
 import com.android.server.connectivity.QosCallbackTracker;
-import com.android.server.net.NetworkPolicyManagerInternal;
 
 import libcore.io.IoUtils;
 
@@ -331,12 +334,10 @@
     private volatile boolean mLockdownEnabled;
 
     /**
-     * Stale copy of uid rules provided by NPMS. As long as they are accessed only in internal
-     * handler thread, they don't need a lock.
+     * Stale copy of uid blocked reasons provided by NPMS. As long as they are accessed only in
+     * internal handler thread, they don't need a lock.
      */
-    private SparseIntArray mUidRules = new SparseIntArray();
-    /** Flag indicating if background data is restricted. */
-    private boolean mRestrictBackground;
+    private SparseIntArray mUidBlockedReasons = new SparseIntArray();
 
     private final Context mContext;
     private final ConnectivityResources mResources;
@@ -352,7 +353,6 @@
     protected INetd mNetd;
     private NetworkStatsManager mStatsManager;
     private NetworkPolicyManager mPolicyManager;
-    private NetworkPolicyManagerInternal mPolicyManagerInternal;
     private final NetdCallback mNetdCallback;
 
     /**
@@ -510,16 +510,6 @@
     // Handle private DNS validation status updates.
     private static final int EVENT_PRIVATE_DNS_VALIDATION_UPDATE = 38;
 
-    /**
-     * Used to handle onUidRulesChanged event from NetworkPolicyManagerService.
-     */
-    private static final int EVENT_UID_RULES_CHANGED = 39;
-
-    /**
-     * Used to handle onRestrictBackgroundChanged event from NetworkPolicyManagerService.
-     */
-    private static final int EVENT_DATA_SAVER_CHANGED = 40;
-
      /**
       * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the network has
       * been tested.
@@ -596,6 +586,13 @@
     private static final int EVENT_SET_PROFILE_NETWORK_PREFERENCE = 50;
 
     /**
+     * Event to specify that reasons for why an uid is blocked changed.
+     * arg1 = uid
+     * arg2 = blockedReasons
+     */
+    private static final int EVENT_UID_BLOCKED_REASON_CHANGED = 51;
+
+    /**
      * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
      * should be shown.
      */
@@ -1242,9 +1239,6 @@
 
         mStatsManager = mContext.getSystemService(NetworkStatsManager.class);
         mPolicyManager = mContext.getSystemService(NetworkPolicyManager.class);
-        mPolicyManagerInternal = Objects.requireNonNull(
-                LocalServices.getService(NetworkPolicyManagerInternal.class),
-                "missing NetworkPolicyManagerInternal");
         mDnsResolver = Objects.requireNonNull(dnsresolver, "missing IDnsResolver");
         mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler);
 
@@ -1253,10 +1247,10 @@
         mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
         mLocationPermissionChecker = new LocationPermissionChecker(mContext);
 
-        // To ensure uid rules are synchronized with Network Policy, register for
+        // To ensure uid state is synchronized with Network Policy, register for
         // NetworkPolicyManagerService events must happen prior to NetworkPolicyManagerService
         // reading existing policy from disk.
-        mPolicyManager.registerListener(mPolicyListener);
+        mPolicyManager.registerNetworkPolicyCallback(null, mPolicyCallback);
 
         final PowerManager powerManager = (PowerManager) context.getSystemService(
                 Context.POWER_SERVICE);
@@ -1344,7 +1338,7 @@
         netCap.addCapability(NET_CAPABILITY_INTERNET);
         netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
         netCap.removeCapability(NET_CAPABILITY_NOT_VPN);
-        netCap.setUids(Collections.singleton(uids));
+        netCap.setUids(UidRange.toIntRanges(Collections.singleton(uids)));
         return netCap;
     }
 
@@ -1780,12 +1774,13 @@
                         nai.network,
                         createWithLocationInfoSanitizedIfNecessaryWhenParceled(
                                 nc, false /* includeLocationSensitiveInfo */,
-                                mDeps.getCallingUid(), callingPackageName, callingAttributionTag));
+                                getCallingPid(), mDeps.getCallingUid(), callingPackageName,
+                                callingAttributionTag));
             }
         }
 
         // No need to check mLockdownEnabled. If it's true, getVpnUnderlyingNetworks returns null.
-        final Network[] networks = getVpnUnderlyingNetworks(Binder.getCallingUid());
+        final Network[] networks = getVpnUnderlyingNetworks(mDeps.getCallingUid());
         if (null != networks) {
             for (final Network network : networks) {
                 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network);
@@ -1795,7 +1790,7 @@
                             createWithLocationInfoSanitizedIfNecessaryWhenParceled(
                                     nc,
                                     false /* includeLocationSensitiveInfo */,
-                                    mDeps.getCallingUid(), callingPackageName,
+                                    getCallingPid(), mDeps.getCallingUid(), callingPackageName,
                                     callingAttributionTag));
                 }
             }
@@ -1878,7 +1873,7 @@
         return createWithLocationInfoSanitizedIfNecessaryWhenParceled(
                 getNetworkCapabilitiesInternal(network),
                 false /* includeLocationSensitiveInfo */,
-                mDeps.getCallingUid(), callingPackageName, callingAttributionTag);
+                getCallingPid(), mDeps.getCallingUid(), callingPackageName, callingAttributionTag);
     }
 
     @VisibleForTesting
@@ -1897,40 +1892,137 @@
         return newNc;
     }
 
-    private boolean hasLocationPermission(int callerUid, @NonNull String callerPkgName,
-            @Nullable String callingAttributionTag) {
-        final long token = Binder.clearCallingIdentity();
-        try {
-            return mLocationPermissionChecker.checkLocationPermission(
-                    callerPkgName, callingAttributionTag, callerUid, null /* message */);
-        } finally {
-            Binder.restoreCallingIdentity(token);
+    /**
+     * Wrapper used to cache the permission check results performed for the corresponding
+     * app. This avoid performing multiple permission checks for different fields in
+     * NetworkCapabilities.
+     * Note: This wrapper does not support any sort of invalidation and thus must not be
+     * persistent or long-lived. It may only be used for the time necessary to
+     * compute the redactions required by one particular NetworkCallback or
+     * synchronous call.
+     */
+    private class RedactionPermissionChecker {
+        private final int mCallingPid;
+        private final int mCallingUid;
+        @NonNull private final String mCallingPackageName;
+        @Nullable private final String mCallingAttributionTag;
+
+        private Boolean mHasLocationPermission = null;
+        private Boolean mHasLocalMacAddressPermission = null;
+        private Boolean mHasSettingsPermission = null;
+
+        RedactionPermissionChecker(int callingPid, int callingUid,
+                @NonNull String callingPackageName, @Nullable String callingAttributionTag) {
+            mCallingPid = callingPid;
+            mCallingUid = callingUid;
+            mCallingPackageName = callingPackageName;
+            mCallingAttributionTag = callingAttributionTag;
         }
+
+        private boolean hasLocationPermissionInternal() {
+            final long token = Binder.clearCallingIdentity();
+            try {
+                return mLocationPermissionChecker.checkLocationPermission(
+                        mCallingPackageName, mCallingAttributionTag, mCallingUid,
+                        null /* message */);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        /**
+         * Returns whether the app holds location permission or not (might return cached result
+         * if the permission was already checked before).
+         */
+        public boolean hasLocationPermission() {
+            if (mHasLocationPermission == null) {
+                // If there is no cached result, perform the check now.
+                mHasLocationPermission = hasLocationPermissionInternal();
+            }
+            return mHasLocationPermission;
+        }
+
+        /**
+         * Returns whether the app holds local mac address permission or not (might return cached
+         * result if the permission was already checked before).
+         */
+        public boolean hasLocalMacAddressPermission() {
+            if (mHasLocalMacAddressPermission == null) {
+                // If there is no cached result, perform the check now.
+                mHasLocalMacAddressPermission =
+                        checkLocalMacAddressPermission(mCallingPid, mCallingUid);
+            }
+            return mHasLocalMacAddressPermission;
+        }
+
+        /**
+         * Returns whether the app holds settings permission or not (might return cached
+         * result if the permission was already checked before).
+         */
+        public boolean hasSettingsPermission() {
+            if (mHasSettingsPermission == null) {
+                // If there is no cached result, perform the check now.
+                mHasSettingsPermission = checkSettingsPermission(mCallingPid, mCallingUid);
+            }
+            return mHasSettingsPermission;
+        }
+    }
+
+    private static boolean shouldRedact(@NetworkCapabilities.RedactionType long redactions,
+            @NetworkCapabilities.NetCapability long redaction) {
+        return (redactions & redaction) != 0;
+    }
+
+    /**
+     * Use the provided |applicableRedactions| to check the receiving app's
+     * permissions and clear/set the corresponding bit in the returned bitmask. The bitmask
+     * returned will be used to ensure the necessary redactions are performed by NetworkCapabilities
+     * before being sent to the corresponding app.
+     */
+    private @NetworkCapabilities.RedactionType long retrieveRequiredRedactions(
+            @NetworkCapabilities.RedactionType long applicableRedactions,
+            @NonNull RedactionPermissionChecker redactionPermissionChecker,
+            boolean includeLocationSensitiveInfo) {
+        long redactions = applicableRedactions;
+        if (shouldRedact(redactions, REDACT_FOR_ACCESS_FINE_LOCATION)) {
+            if (includeLocationSensitiveInfo
+                    && redactionPermissionChecker.hasLocationPermission()) {
+                redactions &= ~REDACT_FOR_ACCESS_FINE_LOCATION;
+            }
+        }
+        if (shouldRedact(redactions, REDACT_FOR_LOCAL_MAC_ADDRESS)) {
+            if (redactionPermissionChecker.hasLocalMacAddressPermission()) {
+                redactions &= ~REDACT_FOR_LOCAL_MAC_ADDRESS;
+            }
+        }
+        if (shouldRedact(redactions, REDACT_FOR_NETWORK_SETTINGS)) {
+            if (redactionPermissionChecker.hasSettingsPermission()) {
+                redactions &= ~REDACT_FOR_NETWORK_SETTINGS;
+            }
+        }
+        return redactions;
     }
 
     @VisibleForTesting
     @Nullable
     NetworkCapabilities createWithLocationInfoSanitizedIfNecessaryWhenParceled(
             @Nullable NetworkCapabilities nc, boolean includeLocationSensitiveInfo,
-            int callerUid, @NonNull String callerPkgName, @Nullable String callingAttributionTag) {
+            int callingPid, int callingUid, @NonNull String callingPkgName,
+            @Nullable String callingAttributionTag) {
         if (nc == null) {
             return null;
         }
-        Boolean hasLocationPermission = null;
-        final NetworkCapabilities newNc;
         // Avoid doing location permission check if the transport info has no location sensitive
         // data.
-        if (includeLocationSensitiveInfo
-                && nc.getTransportInfo() != null
-                && nc.getTransportInfo().hasLocationSensitiveFields()) {
-            hasLocationPermission =
-                    hasLocationPermission(callerUid, callerPkgName, callingAttributionTag);
-            newNc = new NetworkCapabilities(nc, hasLocationPermission);
-        } else {
-            newNc = new NetworkCapabilities(nc, false /* parcelLocationSensitiveFields */);
-        }
+        final RedactionPermissionChecker redactionPermissionChecker =
+                new RedactionPermissionChecker(callingPid, callingUid, callingPkgName,
+                        callingAttributionTag);
+        final long redactions = retrieveRequiredRedactions(
+                nc.getApplicableRedactions(), redactionPermissionChecker,
+                includeLocationSensitiveInfo);
+        final NetworkCapabilities newNc = new NetworkCapabilities(nc, redactions);
         // Reset owner uid if not destined for the owner app.
-        if (callerUid != nc.getOwnerUid()) {
+        if (callingUid != nc.getOwnerUid()) {
             newNc.setOwnerUid(INVALID_UID);
             return newNc;
         }
@@ -1939,23 +2031,17 @@
             // Owner UIDs already checked above. No need to re-check.
             return newNc;
         }
-        // If the caller does not want location sensitive data & target SDK >= S, then mask info.
-        // Else include the owner UID iff the caller has location permission to provide backwards
+        // If the calling does not want location sensitive data & target SDK >= S, then mask info.
+        // Else include the owner UID iff the calling has location permission to provide backwards
         // compatibility for older apps.
         if (!includeLocationSensitiveInfo
                 && isTargetSdkAtleast(
-                        Build.VERSION_CODES.S, callerUid, callerPkgName)) {
+                        Build.VERSION_CODES.S, callingUid, callingPkgName)) {
             newNc.setOwnerUid(INVALID_UID);
             return newNc;
         }
-
-        if (hasLocationPermission == null) {
-            // Location permission not checked yet, check now for masking owner UID.
-            hasLocationPermission =
-                    hasLocationPermission(callerUid, callerPkgName, callingAttributionTag);
-        }
         // Reset owner uid if the app has no location permission.
-        if (!hasLocationPermission) {
+        if (!redactionPermissionChecker.hasLocationPermission()) {
             newNc.setOwnerUid(INVALID_UID);
         }
         return newNc;
@@ -2002,6 +2088,18 @@
         }
     }
 
+    @Override
+    public @RestrictBackgroundStatus int getRestrictBackgroundStatusByCaller() {
+        enforceAccessPermission();
+        final int callerUid = Binder.getCallingUid();
+        final long token = Binder.clearCallingIdentity();
+        try {
+            return mPolicyManager.getRestrictBackgroundStatus(callerUid);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
     // TODO: Consider delete this function or turn it into a no-op method.
     @Override
     public NetworkState[] getAllNetworkState() {
@@ -2237,53 +2335,17 @@
         }
     }
 
-    private final INetworkPolicyListener mPolicyListener = new NetworkPolicyManager.Listener() {
+    private final NetworkPolicyCallback mPolicyCallback = new NetworkPolicyCallback() {
         @Override
-        public void onUidRulesChanged(int uid, int uidRules) {
-            mHandler.sendMessage(mHandler.obtainMessage(EVENT_UID_RULES_CHANGED, uid, uidRules));
-        }
-        @Override
-        public void onRestrictBackgroundChanged(boolean restrictBackground) {
-            // caller is NPMS, since we only register with them
-            if (LOGD_BLOCKED_NETWORKINFO) {
-                log("onRestrictBackgroundChanged(restrictBackground=" + restrictBackground + ")");
-            }
-            mHandler.sendMessage(mHandler.obtainMessage(
-                    EVENT_DATA_SAVER_CHANGED, restrictBackground ? 1 : 0, 0));
+        public void onUidBlockedReasonChanged(int uid, int blockedReasons) {
+            mHandler.sendMessage(mHandler.obtainMessage(EVENT_UID_BLOCKED_REASON_CHANGED,
+                    uid, blockedReasons));
         }
     };
 
-    void handleUidRulesChanged(int uid, int newRules) {
-        // skip update when we've already applied rules
-        final int oldRules = mUidRules.get(uid, RULE_NONE);
-        if (oldRules == newRules) return;
-
-        maybeNotifyNetworkBlockedForNewUidRules(uid, newRules);
-
-        if (newRules == RULE_NONE) {
-            mUidRules.delete(uid);
-        } else {
-            mUidRules.put(uid, newRules);
-        }
-    }
-
-    void handleRestrictBackgroundChanged(boolean restrictBackground) {
-        if (mRestrictBackground == restrictBackground) return;
-
-        final List<UidRange> blockedRanges = mVpnBlockedUidRanges;
-        for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
-            final boolean curMetered = nai.networkCapabilities.isMetered();
-            maybeNotifyNetworkBlocked(nai, curMetered, curMetered, mRestrictBackground,
-                    restrictBackground, blockedRanges, blockedRanges);
-        }
-
-        mRestrictBackground = restrictBackground;
-    }
-
-    private boolean isUidBlockedByRules(int uid, int uidRules, boolean isNetworkMetered,
-            boolean isBackgroundRestricted) {
-        return mPolicyManager.checkUidNetworkingBlocked(uid, uidRules, isNetworkMetered,
-                isBackgroundRestricted);
+    void handleUidBlockedReasonChanged(int uid, int blockedReasons) {
+        maybeNotifyNetworkBlockedForNewState(uid, blockedReasons);
+        mUidBlockedReasons.put(uid, blockedReasons);
     }
 
     private boolean checkAnyPermissionOf(String... permissions) {
@@ -2470,6 +2532,11 @@
         mContext.enforceCallingOrSelfPermission(KeepaliveTracker.PERMISSION, "ConnectivityService");
     }
 
+    private boolean checkLocalMacAddressPermission(int pid, int uid) {
+        return PERMISSION_GRANTED == mContext.checkPermission(
+                Manifest.permission.LOCAL_MAC_ADDRESS, pid, uid);
+    }
+
     private void sendConnectedBroadcast(NetworkInfo info) {
         sendGeneralBroadcast(info, CONNECTIVITY_ACTION);
     }
@@ -2757,19 +2824,16 @@
         pw.decreaseIndent();
         pw.println();
 
-        pw.print("Restrict background: ");
-        pw.println(mRestrictBackground);
-        pw.println();
-
         pw.println("Status for known UIDs:");
         pw.increaseIndent();
-        final int size = mUidRules.size();
+        final int size = mUidBlockedReasons.size();
         for (int i = 0; i < size; i++) {
             // Don't crash if the array is modified while dumping in bugreports.
             try {
-                final int uid = mUidRules.keyAt(i);
-                final int uidRules = mUidRules.get(uid, RULE_NONE);
-                pw.println("UID=" + uid + " rules=" + uidRulesToString(uidRules));
+                final int uid = mUidBlockedReasons.keyAt(i);
+                final int blockedReasons = mUidBlockedReasons.valueAt(i);
+                pw.println("UID=" + uid + " blockedReasons="
+                        + blockedReasonsToString(blockedReasons));
             } catch (ArrayIndexOutOfBoundsException e) {
                 pw.println("  ArrayIndexOutOfBoundsException");
             } catch (ConcurrentModificationException e) {
@@ -2904,7 +2968,7 @@
             if (0 == defaultRequest.mRequests.size()) {
                 pw.println("none, this should never occur.");
             } else {
-                pw.println(defaultRequest.mRequests.get(0).networkCapabilities.getUids());
+                pw.println(defaultRequest.mRequests.get(0).networkCapabilities.getUidRanges());
             }
             pw.decreaseIndent();
             pw.decreaseIndent();
@@ -3005,6 +3069,9 @@
                 case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
                     if (nai.everConnected) {
                         loge("ERROR: cannot call explicitlySelected on already-connected network");
+                        // Note that if the NAI had been connected, this would affect the
+                        // score, and therefore would require re-mixing the score and performing
+                        // a rematch.
                     }
                     nai.networkAgentConfig.explicitlySelected = toBool(msg.arg1);
                     nai.networkAgentConfig.acceptUnvalidated = toBool(msg.arg1) && toBool(msg.arg2);
@@ -3691,7 +3758,7 @@
                 log("Replacing " + existingRequest.mRequests.get(0) + " with "
                         + nri.mRequests.get(0) + " because their intents matched.");
             }
-            handleReleaseNetworkRequest(existingRequest.mRequests.get(0), getCallingUid(),
+            handleReleaseNetworkRequest(existingRequest.mRequests.get(0), mDeps.getCallingUid(),
                     /* callOnUnavailable */ false);
         }
         handleRegisterNetworkRequest(nri);
@@ -4089,6 +4156,7 @@
             // network, we should respect the user's option and don't need to popup the
             // PARTIAL_CONNECTIVITY notification to user again.
             nai.networkAgentConfig.acceptPartialConnectivity = accept;
+            nai.updateScoreForNetworkAgentConfigUpdate();
             rematchAllNetworksAndRequests();
             sendUpdatedScoreToFactories(nai);
         }
@@ -4351,7 +4419,7 @@
 
         Intent intent = new Intent(action);
         if (type != NotificationType.PRIVATE_DNS_BROKEN) {
-            intent.setData(Uri.fromParts("netId", Integer.toString(nai.network.getNetId()), null));
+            intent.putExtra(ConnectivityManager.EXTRA_NETWORK, nai.network);
             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             // Some OEMs have their own Settings package. Thus, need to get the current using
             // Settings package name instead of just use default name "com.android.settings".
@@ -4447,7 +4515,13 @@
         final NetworkPolicyManager netPolicyManager =
                  mContext.getSystemService(NetworkPolicyManager.class);
 
-        final int networkPreference = netPolicyManager.getMultipathPreference(network);
+        final long token = Binder.clearCallingIdentity();
+        final int networkPreference;
+        try {
+            networkPreference = netPolicyManager.getMultipathPreference(network);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
         if (networkPreference != 0) {
             return networkPreference;
         }
@@ -4566,11 +4640,8 @@
                     handlePrivateDnsValidationUpdate(
                             (PrivateDnsValidationUpdate) msg.obj);
                     break;
-                case EVENT_UID_RULES_CHANGED:
-                    handleUidRulesChanged(msg.arg1, msg.arg2);
-                    break;
-                case EVENT_DATA_SAVER_CHANGED:
-                    handleRestrictBackgroundChanged(toBool(msg.arg1));
+                case EVENT_UID_BLOCKED_REASON_CHANGED:
+                    handleUidBlockedReasonChanged(msg.arg1, msg.arg2);
                     break;
                 case EVENT_SET_REQUIRE_VPN_FOR_UIDS:
                     handleSetRequireVpnForUids(toBool(msg.arg1), (UidRange[]) msg.obj);
@@ -5043,8 +5114,8 @@
 
         for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
             final boolean curMetered = nai.networkCapabilities.isMetered();
-            maybeNotifyNetworkBlocked(nai, curMetered, curMetered, mRestrictBackground,
-                    mRestrictBackground, mVpnBlockedUidRanges, newVpnBlockedUidRanges);
+            maybeNotifyNetworkBlocked(nai, curMetered, curMetered,
+                    mVpnBlockedUidRanges, newVpnBlockedUidRanges);
         }
 
         mVpnBlockedUidRanges = newVpnBlockedUidRanges;
@@ -5322,9 +5393,8 @@
         private Set<UidRange> getUids() {
             // networkCapabilities.getUids() returns a defensive copy.
             // multilayer requests will all have the same uids so return the first one.
-            final Set<UidRange> uids = null == mRequests.get(0).networkCapabilities.getUids()
-                    ? new ArraySet<>() : mRequests.get(0).networkCapabilities.getUids();
-            return uids;
+            final Set<UidRange> uids = mRequests.get(0).networkCapabilities.getUidRanges();
+            return (null == uids) ? new ArraySet<>() : uids;
         }
 
         NetworkRequestInfo(@NonNull final NetworkRequest r, @Nullable final PendingIntent pi,
@@ -5777,14 +5847,14 @@
     private void releasePendingNetworkRequestWithDelay(PendingIntent operation) {
         mHandler.sendMessageDelayed(
                 mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
-                getCallingUid(), 0, operation), mReleasePendingIntentDelayMs);
+                mDeps.getCallingUid(), 0, operation), mReleasePendingIntentDelayMs);
     }
 
     @Override
     public void releasePendingNetworkRequest(PendingIntent operation) {
         Objects.requireNonNull(operation, "PendingIntent cannot be null.");
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
-                getCallingUid(), 0, operation));
+                mDeps.getCallingUid(), 0, operation));
     }
 
     // In order to implement the compatibility measure for pre-M apps that call
@@ -5881,7 +5951,7 @@
     public void releaseNetworkRequest(NetworkRequest networkRequest) {
         ensureNetworkRequestHasType(networkRequest);
         mHandler.sendMessage(mHandler.obtainMessage(
-                EVENT_RELEASE_NETWORK_REQUEST, getCallingUid(), 0, networkRequest));
+                EVENT_RELEASE_NETWORK_REQUEST, mDeps.getCallingUid(), 0, networkRequest));
     }
 
     private void handleRegisterNetworkProvider(NetworkProviderInfo npi) {
@@ -6046,10 +6116,15 @@
     private NetworkCapabilities copyDefaultNetworkCapabilitiesForUid(
             @NonNull final NetworkCapabilities netCapToCopy, @NonNull final int requestorUid,
             @NonNull final String requestorPackageName) {
+        // These capabilities are for a TRACK_DEFAULT callback, so:
+        // 1. Remove NET_CAPABILITY_VPN, because it's (currently!) the only difference between
+        //    mDefaultRequest and a per-UID default request.
+        //    TODO: stop depending on the fact that these two unrelated things happen to be the same
+        // 2. Always set the UIDs to mAsUid. restrictRequestUidsForCallerAndSetRequestorInfo will
+        //    not do this in the case of a privileged application.
         final NetworkCapabilities netCap = new NetworkCapabilities(netCapToCopy);
         netCap.removeCapability(NET_CAPABILITY_NOT_VPN);
         netCap.setSingleUid(requestorUid);
-        netCap.setUids(new ArraySet<>());
         restrictRequestUidsForCallerAndSetRequestorInfo(
                 netCap, requestorUid, requestorPackageName);
         return netCap;
@@ -6130,7 +6205,7 @@
         for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
             // Currently, all network requests will have the same uids therefore checking the first
             // one is sufficient. If/when uids are tracked at the nri level, this can change.
-            final Set<UidRange> uids = nri.mRequests.get(0).networkCapabilities.getUids();
+            final Set<UidRange> uids = nri.mRequests.get(0).networkCapabilities.getUidRanges();
             if (null == uids) {
                 continue;
             }
@@ -6571,7 +6646,7 @@
             return;
         }
 
-        final Set<UidRange> ranges = nai.networkCapabilities.getUids();
+        final Set<UidRange> ranges = nai.networkCapabilities.getUidRanges();
         final int vpnAppUid = nai.networkCapabilities.getOwnerUid();
         // TODO: this create a window of opportunity for apps to receive traffic between the time
         // when the old rules are removed and the time when new rules are added. To fix this,
@@ -6827,8 +6902,8 @@
         final boolean meteredChanged = oldMetered != newMetered;
 
         if (meteredChanged) {
-            maybeNotifyNetworkBlocked(nai, oldMetered, newMetered, mRestrictBackground,
-                    mRestrictBackground, mVpnBlockedUidRanges, mVpnBlockedUidRanges);
+            maybeNotifyNetworkBlocked(nai, oldMetered, newMetered,
+                    mVpnBlockedUidRanges, mVpnBlockedUidRanges);
         }
 
         final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING)
@@ -6936,8 +7011,8 @@
 
     private void updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc,
             NetworkCapabilities newNc) {
-        Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUids();
-        Set<UidRange> newRanges = null == newNc ? null : newNc.getUids();
+        Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUidRanges();
+        Set<UidRange> newRanges = null == newNc ? null : newNc.getUidRanges();
         if (null == prevRanges) prevRanges = new ArraySet<>();
         if (null == newRanges) newRanges = new ArraySet<>();
         final Set<UidRange> prevRangesCopy = new ArraySet<>(prevRanges);
@@ -7173,7 +7248,7 @@
                 putParcelable(
                         bundle,
                         createWithLocationInfoSanitizedIfNecessaryWhenParceled(
-                                nc, includeLocationSensitiveInfo, nri.mUid,
+                                nc, includeLocationSensitiveInfo, nri.mPid, nri.mUid,
                                 nrForCallback.getRequestorPackageName(),
                                 nri.mCallingAttributionTag));
                 putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions(
@@ -7194,7 +7269,7 @@
                 putParcelable(
                         bundle,
                         createWithLocationInfoSanitizedIfNecessaryWhenParceled(
-                                netCap, includeLocationSensitiveInfo, nri.mUid,
+                                netCap, includeLocationSensitiveInfo, nri.mPid, nri.mUid,
                                 nrForCallback.getRequestorPackageName(),
                                 nri.mCallingAttributionTag));
                 break;
@@ -7951,8 +8026,8 @@
         final boolean metered = nai.networkCapabilities.isMetered();
         boolean blocked;
         blocked = isUidBlockedByVpn(nri.mUid, mVpnBlockedUidRanges);
-        blocked |= isUidBlockedByRules(nri.mUid, mUidRules.get(nri.mUid),
-                metered, mRestrictBackground);
+        blocked |= NetworkPolicyManager.isUidBlocked(
+                mUidBlockedReasons.get(nri.mUid, BLOCKED_REASON_NONE), metered);
         callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, blocked ? 1 : 0);
     }
 
@@ -7970,16 +8045,14 @@
      *
      * @param nai The target NetworkAgentInfo.
      * @param oldMetered True if the previous network capabilities is metered.
-     * @param newRestrictBackground True if data saver is enabled.
      */
     private void maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered,
-            boolean newMetered, boolean oldRestrictBackground, boolean newRestrictBackground,
-            List<UidRange> oldBlockedUidRanges, List<UidRange> newBlockedUidRanges) {
+            boolean newMetered, List<UidRange> oldBlockedUidRanges,
+            List<UidRange> newBlockedUidRanges) {
 
         for (int i = 0; i < nai.numNetworkRequests(); i++) {
             NetworkRequest nr = nai.requestAt(i);
             NetworkRequestInfo nri = mNetworkRequests.get(nr);
-            final int uidRules = mUidRules.get(nri.mUid);
             final boolean oldBlocked, newBlocked, oldVpnBlocked, newVpnBlocked;
 
             oldVpnBlocked = isUidBlockedByVpn(nri.mUid, oldBlockedUidRanges);
@@ -7987,10 +8060,11 @@
                     ? isUidBlockedByVpn(nri.mUid, newBlockedUidRanges)
                     : oldVpnBlocked;
 
-            oldBlocked = oldVpnBlocked || isUidBlockedByRules(nri.mUid, uidRules, oldMetered,
-                    oldRestrictBackground);
-            newBlocked = newVpnBlocked || isUidBlockedByRules(nri.mUid, uidRules, newMetered,
-                    newRestrictBackground);
+            final int blockedReasons = mUidBlockedReasons.get(nri.mUid, BLOCKED_REASON_NONE);
+            oldBlocked = oldVpnBlocked || NetworkPolicyManager.isUidBlocked(
+                    blockedReasons, oldMetered);
+            newBlocked = newVpnBlocked || NetworkPolicyManager.isUidBlocked(
+                    blockedReasons, newMetered);
 
             if (oldBlocked != newBlocked) {
                 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED,
@@ -8000,19 +8074,20 @@
     }
 
     /**
-     * Notify apps with a given UID of the new blocked state according to new uid rules.
+     * Notify apps with a given UID of the new blocked state according to new uid state.
      * @param uid The uid for which the rules changed.
-     * @param newRules The new rules to apply.
+     * @param blockedReasons The reasons for why an uid is blocked.
      */
-    private void maybeNotifyNetworkBlockedForNewUidRules(int uid, int newRules) {
+    private void maybeNotifyNetworkBlockedForNewState(int uid, int blockedReasons) {
         for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
             final boolean metered = nai.networkCapabilities.isMetered();
             final boolean vpnBlocked = isUidBlockedByVpn(uid, mVpnBlockedUidRanges);
             final boolean oldBlocked, newBlocked;
-            oldBlocked = vpnBlocked || isUidBlockedByRules(
-                    uid, mUidRules.get(uid), metered, mRestrictBackground);
-            newBlocked = vpnBlocked || isUidBlockedByRules(
-                    uid, newRules, metered, mRestrictBackground);
+
+            oldBlocked = vpnBlocked || NetworkPolicyManager.isUidBlocked(
+                    mUidBlockedReasons.get(uid, BLOCKED_REASON_NONE), metered);
+            newBlocked = vpnBlocked || NetworkPolicyManager.isUidBlocked(
+                    blockedReasons, metered);
             if (oldBlocked == newBlocked) {
                 continue;
             }
@@ -8359,7 +8434,7 @@
 
         final NetworkAgentInfo vpn = getVpnForUid(uid);
         if (vpn == null || getVpnType(vpn) != VpnManager.TYPE_VPN_SERVICE
-                || vpn.networkCapabilities.getOwnerUid() != Binder.getCallingUid()) {
+                || vpn.networkCapabilities.getOwnerUid() != mDeps.getCallingUid()) {
             return INVALID_UID;
         }
 
@@ -9268,7 +9343,7 @@
             final ArrayList<NetworkRequest> nrs = new ArrayList<>();
             nrs.add(createNetworkRequest(NetworkRequest.Type.REQUEST, pref.capabilities));
             nrs.add(createDefaultRequest());
-            setNetworkRequestUids(nrs, pref.capabilities.getUids());
+            setNetworkRequestUids(nrs, UidRange.fromIntRanges(pref.capabilities.getUids()));
             final NetworkRequestInfo nri = new NetworkRequestInfo(nrs);
             result.add(nri);
         }
@@ -9484,9 +9559,8 @@
 
     private static void setNetworkRequestUids(@NonNull final List<NetworkRequest> requests,
             @NonNull final Set<UidRange> uids) {
-        final Set<UidRange> ranges = new ArraySet<>(uids);
         for (final NetworkRequest req : requests) {
-            req.networkCapabilities.setUids(ranges);
+            req.networkCapabilities.setUids(UidRange.toIntRanges(uids));
         }
     }
 
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 10d6570..3ea0ce1 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -643,7 +643,7 @@
                 String route, String gateway, String ifName) throws RemoteException {
             final RouteInfo processRoute = new RouteInfo(new IpPrefix(route),
                     ("".equals(gateway)) ? null : InetAddresses.parseNumericAddress(gateway),
-                    ifName);
+                    ifName, RouteInfo.RTN_UNICAST);
             mDaemonHandler.post(() -> notifyRouteChange(updated, processRoute));
         }
 
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index e8ef7e2..78ffcbd 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -319,7 +319,8 @@
 
     private int[] mDataEnabledReason;
 
-    private Map<Integer, Long> mAllowedNetworkTypesList;
+    private int[] mAllowedNetworkTypeReason;
+    private long[] mAllowedNetworkTypeValue;
 
     private List<List<LinkCapacityEstimate>> mLinkCapacityEstimateLists;
 
@@ -388,7 +389,8 @@
     private boolean isPrivilegedPhoneStatePermissionRequired(Set<Integer> events) {
         return events.contains(TelephonyCallback.EVENT_SRVCC_STATE_CHANGED)
                 || events.contains(TelephonyCallback.EVENT_VOICE_ACTIVATION_STATE_CHANGED)
-                || events.contains(TelephonyCallback.EVENT_RADIO_POWER_STATE_CHANGED);
+                || events.contains(TelephonyCallback.EVENT_RADIO_POWER_STATE_CHANGED)
+                || events.contains(TelephonyCallback.EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED);
     }
 
     private static final int MSG_USER_SWITCHED = 1;
@@ -532,6 +534,8 @@
         mTelephonyDisplayInfos = copyOf(mTelephonyDisplayInfos, mNumPhones);
         mIsDataEnabled= copyOf(mIsDataEnabled, mNumPhones);
         mDataEnabledReason = copyOf(mDataEnabledReason, mNumPhones);
+        mAllowedNetworkTypeReason = copyOf(mAllowedNetworkTypeReason, mNumPhones);
+        mAllowedNetworkTypeValue = copyOf(mAllowedNetworkTypeValue, mNumPhones);
 
         // ds -> ss switch.
         if (mNumPhones < oldNumPhones) {
@@ -577,6 +581,8 @@
             mPhysicalChannelConfigs.add(i, new PhysicalChannelConfig.Builder().build());
             mIsDataEnabled[i] = false;
             mDataEnabledReason[i] = TelephonyManager.DATA_ENABLED_REASON_USER;
+            mAllowedNetworkTypeReason[i] = -1;
+            mAllowedNetworkTypeValue[i] = -1;
             mLinkCapacityEstimateLists.add(i, new ArrayList<>());
         }
     }
@@ -637,10 +643,12 @@
         mBarringInfo = new ArrayList<>();
         mTelephonyDisplayInfos = new TelephonyDisplayInfo[numPhones];
         mPhysicalChannelConfigs = new ArrayList<>();
+        mAllowedNetworkTypeReason = new int[numPhones];
+        mAllowedNetworkTypeValue = new long[numPhones];
         mIsDataEnabled = new boolean[numPhones];
         mDataEnabledReason = new int[numPhones];
-        mAllowedNetworkTypesList = new HashMap<>();
         mLinkCapacityEstimateLists = new ArrayList<>();
+
         for (int i = 0; i < numPhones; i++) {
             mCallState[i] =  TelephonyManager.CALL_STATE_IDLE;
             mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE;
@@ -673,6 +681,8 @@
             mPhysicalChannelConfigs.add(i, new PhysicalChannelConfig.Builder().build());
             mIsDataEnabled[i] = false;
             mDataEnabledReason[i] = TelephonyManager.DATA_ENABLED_REASON_USER;
+            mAllowedNetworkTypeReason[i] = -1;
+            mAllowedNetworkTypeValue[i] = -1;
             mLinkCapacityEstimateLists.add(i, new ArrayList<>());
         }
 
@@ -1175,14 +1185,6 @@
                     }
                 }
                 if (events.contains(
-                        TelephonyCallback.EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED)) {
-                    try {
-                        r.callback.onAllowedNetworkTypesChanged(mAllowedNetworkTypesList);
-                    } catch (RemoteException ex) {
-                        remove(r.binder);
-                    }
-                }
-                if (events.contains(
                         TelephonyCallback.EVENT_LINK_CAPACITY_ESTIMATE_CHANGED)) {
                     try {
                         if (mLinkCapacityEstimateLists.get(phoneId) != null) {
@@ -2443,18 +2445,19 @@
      *
      * @param phoneId the phone id.
      * @param subId the subId.
-     * @param allowedNetworkTypesList Map associating all allowed network type reasons with reason's
-     *                                allowed network type values.
+     * @param reason the allowed network type reason.
+     * @param allowedNetworkType the allowed network type value.
      */
-    public void notifyAllowedNetworkTypesChanged(int phoneId, int subId,
-            Map allowedNetworkTypesList) {
+    public void notifyAllowedNetworkTypesChanged(int phoneId, int subId, int reason,
+            long allowedNetworkType) {
         if (!checkNotifyPermission("notifyAllowedNetworkTypesChanged()")) {
             return;
         }
 
         synchronized (mRecords) {
             if (validatePhoneId(phoneId)) {
-                mAllowedNetworkTypesList = allowedNetworkTypesList;
+                mAllowedNetworkTypeReason[phoneId] = reason;
+                mAllowedNetworkTypeValue[phoneId] = allowedNetworkType;
 
                 for (Record r : mRecords) {
                     if (r.matchTelephonyCallbackEvent(
@@ -2462,10 +2465,12 @@
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             if (VDBG) {
-                                log("notifyAllowedNetworkTypesChanged: AllowedNetworkTypesList= "
-                                        + mAllowedNetworkTypesList.toString());
+                                log("notifyAllowedNetworkTypesChanged: reason= " + reason
+                                        + ", allowed network type:"
+                                        + TelephonyManager.convertNetworkTypeBitmaskToString(
+                                        allowedNetworkType));
                             }
-                            r.callback.onAllowedNetworkTypesChanged(mAllowedNetworkTypesList);
+                            r.callback.onAllowedNetworkTypesChanged(reason, allowedNetworkType);
                         } catch (RemoteException ex) {
                             mRemoveList.add(r.binder);
                         }
@@ -2556,6 +2561,8 @@
                 pw.println("mTelephonyDisplayInfo=" + mTelephonyDisplayInfos[i]);
                 pw.println("mIsDataEnabled=" + mIsDataEnabled);
                 pw.println("mDataEnabledReason=" + mDataEnabledReason);
+                pw.println("mAllowedNetworkTypeReason=" + mAllowedNetworkTypeReason[i]);
+                pw.println("mAllowedNetworkTypeValue=" + mAllowedNetworkTypeValue[i]);
                 pw.println("mLinkCapacityEstimateList=" + mLinkCapacityEstimateLists.get(i));
                 pw.decreaseIndent();
             }
diff --git a/services/core/java/com/android/server/VpnManagerService.java b/services/core/java/com/android/server/VpnManagerService.java
index 56aabc20..d756c1f 100644
--- a/services/core/java/com/android/server/VpnManagerService.java
+++ b/services/core/java/com/android/server/VpnManagerService.java
@@ -352,7 +352,10 @@
     @Override
     public void startLegacyVpn(VpnProfile profile) {
         int user = UserHandle.getUserId(mDeps.getCallingUid());
-        final LinkProperties egress = mCm.getActiveLinkProperties();
+        // Note that if the caller is not system (uid >= Process.FIRST_APPLICATION_UID),
+        // the code might not work well since getActiveNetwork might return null if the uid is
+        // blocked by NetworkPolicyManagerService.
+        final LinkProperties egress = mCm.getLinkProperties(mCm.getActiveNetwork());
         if (egress == null) {
             throw new IllegalStateException("Missing active network connection");
         }
diff --git a/services/core/java/com/android/server/am/OWNERS b/services/core/java/com/android/server/am/OWNERS
index 1c38c86..90d9409 100644
--- a/services/core/java/com/android/server/am/OWNERS
+++ b/services/core/java/com/android/server/am/OWNERS
@@ -30,6 +30,10 @@
 michaelwr@google.com
 narayan@google.com
 
+# Voice Interaction
+per-file *Assist* = file:/core/java/android/service/voice/OWNERS
+per-file *Voice* = file:/core/java/android/service/voice/OWNERS
+
 per-file SettingsToPropertiesMapper.java = omakoto@google.com, svetoslavganov@google.com, yamasani@google.com
 
 per-file CarUserSwitchingDialog.java = keunyoung@google.com, felipeal@google.com, gurunagarajan@google.com
diff --git a/services/core/java/com/android/server/apphibernation/AppHibernationService.java b/services/core/java/com/android/server/apphibernation/AppHibernationService.java
index 968cf5f..b3373d0 100644
--- a/services/core/java/com/android/server/apphibernation/AppHibernationService.java
+++ b/services/core/java/com/android/server/apphibernation/AppHibernationService.java
@@ -173,7 +173,9 @@
         if (!checkHibernationEnabled("isHibernatingForUser")) {
             return false;
         }
-
+        getContext().enforceCallingOrSelfPermission(
+                android.Manifest.permission.MANAGE_APP_HIBERNATION,
+                "Caller does not have MANAGE_APP_HIBERNATION permission.");
         userId = handleIncomingUser(userId, "isHibernating");
         if (!mUserManager.isUserUnlockingOrUnlocked(userId)) {
             Slog.e(TAG, "Attempt to get hibernation state of stopped or nonexistent user "
@@ -202,6 +204,9 @@
         if (!checkHibernationEnabled("isHibernatingGlobally")) {
             return false;
         }
+        getContext().enforceCallingOrSelfPermission(
+                android.Manifest.permission.MANAGE_APP_HIBERNATION,
+                "Caller does not have MANAGE_APP_HIBERNATION permission.");
         synchronized (mLock) {
             GlobalLevelState state = mGlobalHibernationStates.get(packageName);
             if (state == null) {
@@ -223,6 +228,9 @@
         if (!checkHibernationEnabled("setHibernatingForUser")) {
             return;
         }
+        getContext().enforceCallingOrSelfPermission(
+                android.Manifest.permission.MANAGE_APP_HIBERNATION,
+                "Caller does not have MANAGE_APP_HIBERNATION permission.");
         userId = handleIncomingUser(userId, "setHibernating");
         if (!mUserManager.isUserUnlockingOrUnlocked(userId)) {
             Slog.w(TAG, "Attempt to set hibernation state for a stopped or nonexistent user "
@@ -263,6 +271,9 @@
         if (!checkHibernationEnabled("setHibernatingGlobally")) {
             return;
         }
+        getContext().enforceCallingOrSelfPermission(
+                android.Manifest.permission.MANAGE_APP_HIBERNATION,
+                "Caller does not have MANAGE_APP_HIBERNATION permission.");
         synchronized (mLock) {
             GlobalLevelState state = mGlobalHibernationStates.get(packageName);
             if (state == null) {
@@ -282,6 +293,35 @@
     }
 
     /**
+     * Get the hibernating packages for the given user. This is equivalent to the list of
+     * packages for the user that return true for {@link #isHibernatingForUser}.
+     */
+    @NonNull List<String> getHibernatingPackagesForUser(int userId) {
+        ArrayList<String> hibernatingPackages = new ArrayList<>();
+        if (!checkHibernationEnabled("getHibernatingPackagesForUser")) {
+            return hibernatingPackages;
+        }
+        getContext().enforceCallingOrSelfPermission(
+                android.Manifest.permission.MANAGE_APP_HIBERNATION,
+                "Caller does not have MANAGE_APP_HIBERNATION permission.");
+        userId = handleIncomingUser(userId, "getHibernatingPackagesForUser");
+        if (!mUserManager.isUserUnlockingOrUnlocked(userId)) {
+            Slog.w(TAG, "Attempt to get hibernating packages for a stopped or nonexistent user "
+                    + userId);
+            return hibernatingPackages;
+        }
+        synchronized (mLock) {
+            Map<String, UserLevelState> userStates = mUserStates.get(userId);
+            for (UserLevelState state : userStates.values()) {
+                if (state.hibernated) {
+                    hibernatingPackages.add(state.packageName);
+                }
+            }
+            return hibernatingPackages;
+        }
+    }
+
+    /**
      * Put an app into hibernation for a given user, allowing user-level optimizations to occur.
      *
      * @param pkgState package hibernation state
@@ -608,6 +648,11 @@
         }
 
         @Override
+        public List<String> getHibernatingPackagesForUser(int userId) {
+            return mService.getHibernatingPackagesForUser(userId);
+        }
+
+        @Override
         public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
                 @Nullable FileDescriptor err, @NonNull String[] args,
                 @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver) {
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index b355730..6776f49 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -91,16 +91,19 @@
         return bits;
     }
 
-    private void openPipe() {
+    private boolean openPipe() {
         try {
-            mPipe = new RandomAccessFile(PIPE_DEVICE, "rw");
-            mPipe.write(createOpenHandshake());
-        } catch (IOException e) {
+            final RandomAccessFile pipe = new RandomAccessFile(PIPE_DEVICE, "rw");
             try {
-                if (mPipe != null) mPipe.close();
-            } catch (IOException ee) {}
-            mPipe = null;
+                pipe.write(createOpenHandshake());
+                mPipe = pipe;
+                return true;
+            } catch (IOException ignore) {
+                pipe.close();
+            }
+        } catch (IOException ignore) {
         }
+        return false;
     }
 
     public HostClipboardMonitor(HostClipboardCallback cb) {
@@ -114,8 +117,7 @@
                 // There's no guarantee that QEMU pipes will be ready at the moment
                 // this method is invoked. We simply try to get the pipe open and
                 // retry on failure indefinitely.
-                while (mPipe == null) {
-                    openPipe();
+                while ((mPipe == null) && !openPipe()) {
                     Thread.sleep(100);
                 }
                 int size = mPipe.readInt();
diff --git a/services/core/java/com/android/server/connectivity/ConnectivityConstants.java b/services/core/java/com/android/server/connectivity/ConnectivityConstants.java
index 0fb6fec..325a2cd 100644
--- a/services/core/java/com/android/server/connectivity/ConnectivityConstants.java
+++ b/services/core/java/com/android/server/connectivity/ConnectivityConstants.java
@@ -18,18 +18,10 @@
 
 /**
  * A class encapsulating various constants used by Connectivity.
+ * TODO : remove this class.
  * @hide
  */
 public class ConnectivityConstants {
-
-    // Penalty applied to scores of Networks that have not been validated.
-    public static final int UNVALIDATED_SCORE_PENALTY = 40;
-
-    // Score for explicitly connected network.
-    //
-    // This ensures that a) the explicitly selected network is never trumped by anything else, and
-    // b) the explicitly selected network is never torn down.
-    public static final int EXPLICITLY_SELECTED_NETWORK_SCORE = 100;
     // VPNs typically have priority over other networks. Give them a score that will
     // let them win every single time.
     public static final int VPN_DEFAULT_SCORE = 101;
diff --git a/services/core/java/com/android/server/connectivity/FullScore.java b/services/core/java/com/android/server/connectivity/FullScore.java
index ac5988a..028cfee 100644
--- a/services/core/java/com/android/server/connectivity/FullScore.java
+++ b/services/core/java/com/android/server/connectivity/FullScore.java
@@ -16,9 +16,21 @@
 
 package com.android.server.connectivity;
 
+import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
+import static android.net.NetworkCapabilities.TRANSPORT_VPN;
+
+import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.net.NetworkAgentConfig;
+import android.net.NetworkCapabilities;
 import android.net.NetworkScore;
 
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.StringJoiner;
+
 /**
  * This class represents how desirable a network is.
  *
@@ -31,11 +43,54 @@
     // a migration.
     private final int mLegacyInt;
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"POLICY_"}, value = {
+            POLICY_IS_VALIDATED,
+            POLICY_IS_VPN,
+            POLICY_EVER_USER_SELECTED,
+            POLICY_ACCEPT_UNVALIDATED
+    })
+    public @interface Policy {
+    }
+
     // Agent-managed policies are in NetworkScore. They start from 1.
-    // CS-managed policies
+    // CS-managed policies, counting from 63 downward
     // This network is validated. CS-managed because the source of truth is in NetworkCapabilities.
+    /** @hide */
     public static final int POLICY_IS_VALIDATED = 63;
 
+    // This is a VPN and behaves as one for scoring purposes.
+    /** @hide */
+    public static final int POLICY_IS_VPN = 62;
+
+    // This network has been selected by the user manually from settings or a 3rd party app
+    // at least once. {@see NetworkAgentConfig#explicitlySelected}.
+    /** @hide */
+    public static final int POLICY_EVER_USER_SELECTED = 61;
+
+    // The user has indicated in UI that this network should be used even if it doesn't
+    // validate. {@see NetworkAgentConfig#acceptUnvalidated}.
+    /** @hide */
+    public static final int POLICY_ACCEPT_UNVALIDATED = 60;
+
+    // To help iterate when printing
+    @VisibleForTesting
+    static final int MIN_CS_MANAGED_POLICY = POLICY_ACCEPT_UNVALIDATED;
+    @VisibleForTesting
+    static final int MAX_CS_MANAGED_POLICY = POLICY_IS_VALIDATED;
+
+    @VisibleForTesting
+    static @NonNull String policyNameOf(final int policy) {
+        switch (policy) {
+            case POLICY_IS_VALIDATED: return "IS_VALIDATED";
+            case POLICY_IS_VPN: return "IS_VPN";
+            case POLICY_EVER_USER_SELECTED: return "EVER_USER_SELECTED";
+            case POLICY_ACCEPT_UNVALIDATED: return "ACCEPT_UNVALIDATED";
+        }
+        throw new IllegalArgumentException("Unknown policy : " + policy);
+    }
+
     // Bitmask of all the policies applied to this score.
     private final long mPolicies;
 
@@ -45,12 +100,46 @@
     }
 
     /**
-     * Make a FullScore from a NetworkScore
+     * Given a score supplied by the NetworkAgent and CS-managed objects, produce a full score.
+     *
+     * @param score the score supplied by the agent
+     * @param caps the NetworkCapabilities of the network
+     * @param config the NetworkAgentConfig of the network
+     * @return an FullScore that is appropriate to use for ranking.
      */
-    public static FullScore withPolicy(@NonNull final NetworkScore originalScore,
-            final boolean isValidated) {
-        return new FullScore(originalScore.getLegacyInt(),
-                isValidated ? 1L << POLICY_IS_VALIDATED : 0L);
+    public static FullScore fromNetworkScore(@NonNull final NetworkScore score,
+            @NonNull final NetworkCapabilities caps, @NonNull final NetworkAgentConfig config) {
+        return withPolicies(score.getLegacyInt(), caps.hasCapability(NET_CAPABILITY_VALIDATED),
+                caps.hasTransport(TRANSPORT_VPN),
+                config.explicitlySelected,
+                config.acceptUnvalidated);
+    }
+
+    /**
+     * Return a new score given updated caps and config.
+     *
+     * @param caps the NetworkCapabilities of the network
+     * @param config the NetworkAgentConfig of the network
+     * @return a score with the policies from the arguments reset
+     */
+    public FullScore mixInScore(@NonNull final NetworkCapabilities caps,
+            @NonNull final NetworkAgentConfig config) {
+        return withPolicies(mLegacyInt, caps.hasCapability(NET_CAPABILITY_VALIDATED),
+                caps.hasTransport(TRANSPORT_VPN),
+                config.explicitlySelected,
+                config.acceptUnvalidated);
+    }
+
+    private static FullScore withPolicies(@NonNull final int legacyInt,
+            final boolean isValidated,
+            final boolean isVpn,
+            final boolean everUserSelected,
+            final boolean acceptUnvalidated) {
+        return new FullScore(legacyInt,
+                (isValidated         ? 1L << POLICY_IS_VALIDATED : 0)
+                | (isVpn             ? 1L << POLICY_IS_VPN : 0)
+                | (everUserSelected  ? 1L << POLICY_EVER_USER_SELECTED : 0)
+                | (acceptUnvalidated ? 1L << POLICY_ACCEPT_UNVALIDATED : 0));
     }
 
     /**
@@ -58,11 +147,65 @@
      * This will be removed before S is published.
      */
     public int getLegacyInt() {
-        return mLegacyInt;
+        return getLegacyInt(false /* pretendValidated */);
     }
 
+    public int getLegacyIntAsValidated() {
+        return getLegacyInt(true /* pretendValidated */);
+    }
+
+    // TODO : remove these two constants
+    // Penalty applied to scores of Networks that have not been validated.
+    private static final int UNVALIDATED_SCORE_PENALTY = 40;
+
+    // Score for a network that can be used unvalidated
+    private static final int ACCEPT_UNVALIDATED_NETWORK_SCORE = 100;
+
+    private int getLegacyInt(boolean pretendValidated) {
+        // If the user has chosen this network at least once, give it the maximum score when
+        // checking to pretend it's validated, or if it doesn't need to validate because the
+        // user said to use it even if it doesn't validate.
+        // This ensures that networks that have been selected in UI are not torn down before the
+        // user gets a chance to prefer it when a higher-scoring network (e.g., Ethernet) is
+        // available.
+        if (hasPolicy(POLICY_EVER_USER_SELECTED)
+                && (hasPolicy(POLICY_ACCEPT_UNVALIDATED) || pretendValidated)) {
+            return ACCEPT_UNVALIDATED_NETWORK_SCORE;
+        }
+
+        int score = mLegacyInt;
+        // Except for VPNs, networks are subject to a penalty for not being validated.
+        // Apply the penalty unless the network is a VPN, or it's validated or pretending to be.
+        if (!hasPolicy(POLICY_IS_VALIDATED) && !pretendValidated && !hasPolicy(POLICY_IS_VPN)) {
+            score -= UNVALIDATED_SCORE_PENALTY;
+        }
+        if (score < 0) score = 0;
+        return score;
+    }
+
+    /**
+     * @return whether this score has a particular policy.
+     */
+    @VisibleForTesting
+    public boolean hasPolicy(final int policy) {
+        return 0 != (mPolicies & (1L << policy));
+    }
+
+    // Example output :
+    // Score(50 ; Policies : EVER_USER_SELECTED&IS_VALIDATED)
     @Override
     public String toString() {
-        return "Score(" + mLegacyInt + ")";
+        final StringJoiner sj = new StringJoiner(
+                "&", // delimiter
+                "Score(" + mLegacyInt + " ; Policies : ", // prefix
+                ")"); // suffix
+        for (int i = NetworkScore.MIN_AGENT_MANAGED_POLICY;
+                i <= NetworkScore.MAX_AGENT_MANAGED_POLICY; ++i) {
+            if (hasPolicy(i)) sj.add(policyNameOf(i));
+        }
+        for (int i = MIN_CS_MANAGED_POLICY; i <= MAX_CS_MANAGED_POLICY; ++i) {
+            if (hasPolicy(i)) sj.add(policyNameOf(i));
+        }
+        return sj.toString();
     }
 }
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 372601f..103ab95 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -17,7 +17,6 @@
 package com.android.server.connectivity;
 
 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
 import static android.net.NetworkCapabilities.transportNamesOf;
 
 import android.annotation.NonNull;
@@ -26,6 +25,8 @@
 import android.net.CaptivePortalData;
 import android.net.IDnsResolver;
 import android.net.INetd;
+import android.net.INetworkAgent;
+import android.net.INetworkAgentRegistry;
 import android.net.INetworkMonitor;
 import android.net.LinkProperties;
 import android.net.NattKeepalivePacketData;
@@ -52,8 +53,6 @@
 import android.util.Pair;
 import android.util.SparseArray;
 
-import com.android.connectivity.aidl.INetworkAgent;
-import com.android.connectivity.aidl.INetworkAgentRegistry;
 import com.android.internal.util.WakeupMessage;
 import com.android.server.ConnectivityService;
 
@@ -358,12 +357,12 @@
         networkInfo = info;
         linkProperties = lp;
         networkCapabilities = nc;
-        mScore = mixInScore(score, nc);
+        networkAgentConfig = config;
+        setScore(score); // uses members networkCapabilities and networkAgentConfig
         clatd = new Nat464Xlat(this, netd, dnsResolver, deps);
         mConnService = connService;
         mContext = context;
         mHandler = handler;
-        networkAgentConfig = config;
         this.factorySerialNumber = factorySerialNumber;
         this.creatorUid = creatorUid;
         mQosCallbackTracker = qosCallbackTracker;
@@ -669,6 +668,7 @@
             @NonNull final NetworkCapabilities nc) {
         final NetworkCapabilities oldNc = networkCapabilities;
         networkCapabilities = nc;
+        mScore = mScore.mixInScore(networkCapabilities, networkAgentConfig);
         final NetworkMonitorManager nm = mNetworkMonitor;
         if (nm != null) {
             nm.notifyNetworkCapabilitiesChanged(nc);
@@ -846,30 +846,6 @@
         return isVPN();
     }
 
-    private int getCurrentScore(boolean pretendValidated) {
-        // TODO: We may want to refactor this into a NetworkScore class that takes a base score from
-        // the NetworkAgent and signals from the NetworkAgent and uses those signals to modify the
-        // score.  The NetworkScore class would provide a nice place to centralize score constants
-        // so they are not scattered about the transports.
-
-        // If this network is explicitly selected and the user has decided to use it even if it's
-        // unvalidated, give it the maximum score. Also give it the maximum score if it's explicitly
-        // selected and we're trying to see what its score could be. This ensures that we don't tear
-        // down an explicitly selected network before the user gets a chance to prefer it when
-        // a higher-scoring network (e.g., Ethernet) is available.
-        if (networkAgentConfig.explicitlySelected
-                && (networkAgentConfig.acceptUnvalidated || pretendValidated)) {
-            return ConnectivityConstants.EXPLICITLY_SELECTED_NETWORK_SCORE;
-        }
-
-        int score = mScore.getLegacyInt();
-        if (!lastValidated && !pretendValidated && !ignoreWifiUnvalidationPenalty() && !isVPN()) {
-            score -= ConnectivityConstants.UNVALIDATED_SCORE_PENALTY;
-        }
-        if (score < 0) score = 0;
-        return score;
-    }
-
     // Return true on devices configured to ignore score penalty for wifi networks
     // that become unvalidated (b/31075769).
     private boolean ignoreWifiUnvalidationPenalty() {
@@ -882,22 +858,29 @@
     // Get the current score for this Network.  This may be modified from what the
     // NetworkAgent sent, as it has modifiers applied to it.
     public int getCurrentScore() {
-        return getCurrentScore(false);
+        return mScore.getLegacyInt();
     }
 
     // Get the current score for this Network as if it was validated.  This may be modified from
     // what the NetworkAgent sent, as it has modifiers applied to it.
     public int getCurrentScoreAsValidated() {
-        return getCurrentScore(true);
+        return mScore.getLegacyIntAsValidated();
     }
 
+    /**
+     * Mix-in the ConnectivityService-managed bits in the score.
+     */
     public void setScore(final NetworkScore score) {
-        mScore = mixInScore(score, networkCapabilities);
+        mScore = FullScore.fromNetworkScore(score, networkCapabilities, networkAgentConfig);
     }
 
-    private static FullScore mixInScore(@NonNull final NetworkScore score,
-            @NonNull final NetworkCapabilities caps) {
-        return FullScore.withPolicy(score, caps.hasCapability(NET_CAPABILITY_VALIDATED));
+    /**
+     * Update the ConnectivityService-managed bits in the score.
+     *
+     * Call this after updating the network agent config.
+     */
+    public void updateScoreForNetworkAgentConfigUpdate() {
+        mScore = mScore.mixInScore(networkCapabilities, networkAgentConfig);
     }
 
     /**
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index 181a10d..0c0d459 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -28,6 +28,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
+import android.graphics.drawable.Icon;
+import android.net.ConnectivityResources;
 import android.net.NetworkSpecifier;
 import android.net.TelephonyNetworkSpecifier;
 import android.net.wifi.WifiInfo;
@@ -40,7 +42,7 @@
 import android.util.SparseIntArray;
 import android.widget.Toast;
 
-import com.android.internal.R;
+import com.android.connectivity.resources.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 
@@ -82,6 +84,7 @@
 
     // The context is for the current user (system server)
     private final Context mContext;
+    private final Resources mResources;
     private final TelephonyManager mTelephonyManager;
     // The notification manager is created from a context for User.ALL, so notifications
     // will be sent to all users.
@@ -96,6 +99,7 @@
                 (NotificationManager) c.createContextAsUser(UserHandle.ALL, 0 /* flags */)
                         .getSystemService(Context.NOTIFICATION_SERVICE);
         mNotificationTypeMap = new SparseIntArray();
+        mResources = new ConnectivityResources(mContext).get();
     }
 
     @VisibleForTesting
@@ -113,20 +117,19 @@
         return -1;
     }
 
-    private static String getTransportName(final int transportType) {
-        Resources r = Resources.getSystem();
-        String[] networkTypes = r.getStringArray(R.array.network_switch_type_name);
+    private String getTransportName(final int transportType) {
+        String[] networkTypes = mResources.getStringArray(R.array.network_switch_type_name);
         try {
             return networkTypes[transportType];
         } catch (IndexOutOfBoundsException e) {
-            return r.getString(R.string.network_switch_type_name_unknown);
+            return mResources.getString(R.string.network_switch_type_name_unknown);
         }
     }
 
     private static int getIcon(int transportType) {
         return (transportType == TRANSPORT_WIFI)
-                ? R.drawable.stat_notify_wifi_in_range :  // TODO: Distinguish ! from ?.
-                R.drawable.stat_notify_rssi_in_range;
+                ? R.drawable.stat_notify_wifi_in_range  // TODO: Distinguish ! from ?.
+                : R.drawable.stat_notify_rssi_in_range;
     }
 
     /**
@@ -194,10 +197,10 @@
                     tag, nameOf(eventId), getTransportName(transportType), name, highPriority));
         }
 
-        Resources r = mContext.getResources();
+        final Resources r = mResources;
         final CharSequence title;
         final CharSequence details;
-        int icon = getIcon(transportType);
+        Icon icon = Icon.createWithResource(r, getIcon(transportType));
         if (notifyType == NotificationType.NO_INTERNET && transportType == TRANSPORT_WIFI) {
             title = r.getString(R.string.wifi_no_internet, name);
             details = r.getString(R.string.wifi_no_internet_detailed);
@@ -272,8 +275,7 @@
                 .setSmallIcon(icon)
                 .setAutoCancel(true)
                 .setTicker(title)
-                .setColor(mContext.getColor(
-                        com.android.internal.R.color.system_notification_accent_color))
+                .setColor(mContext.getColor(android.R.color.system_notification_accent_color))
                 .setContentTitle(title)
                 .setContentIntent(intent)
                 .setLocalOnly(true)
@@ -353,7 +355,7 @@
     public void showToast(NetworkAgentInfo fromNai, NetworkAgentInfo toNai) {
         String fromTransport = getTransportName(approximateTransportType(fromNai));
         String toTransport = getTransportName(approximateTransportType(toNai));
-        String text = mContext.getResources().getString(
+        String text = mResources.getString(
                 R.string.network_switch_metered_toast, fromTransport, toTransport);
         Toast.makeText(mContext, text, Toast.LENGTH_LONG).show();
     }
diff --git a/services/core/java/com/android/server/connectivity/ProxyTracker.java b/services/core/java/com/android/server/connectivity/ProxyTracker.java
index f883307..f572b46 100644
--- a/services/core/java/com/android/server/connectivity/ProxyTracker.java
+++ b/services/core/java/com/android/server/connectivity/ProxyTracker.java
@@ -34,7 +34,6 @@
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Handler;
-import android.os.HandlerExecutor;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.TextUtils;
@@ -105,7 +104,7 @@
 
         PacProxyInstalledListener listener = new PacProxyInstalledListener(pacChangedEvent);
         mPacProxyManager.addPacProxyInstalledListener(
-                new HandlerExecutor(mConnectivityServiceHandler), listener);
+                mConnectivityServiceHandler::post, listener);
     }
 
     // Convert empty ProxyInfo's to null as null-checks are used to determine if proxies are present
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 124c374..30e0c7e 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -19,6 +19,7 @@
 import static android.Manifest.permission.BIND_VPN_SERVICE;
 import static android.net.ConnectivityManager.NETID_UNSET;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
+import static android.os.UserHandle.PER_USER_RANGE;
 import static android.net.RouteInfo.RTN_THROW;
 import static android.net.RouteInfo.RTN_UNREACHABLE;
 import static android.net.VpnManager.NOTIFICATION_CHANNEL_VPN;
@@ -68,8 +69,8 @@
 import android.net.NetworkInfo.DetailedState;
 import android.net.NetworkProvider;
 import android.net.NetworkRequest;
+import android.net.NetworkScore;
 import android.net.RouteInfo;
-import android.net.UidRange;
 import android.net.UidRangeParcel;
 import android.net.UnderlyingNetworkInfo;
 import android.net.VpnManager;
@@ -1174,11 +1175,13 @@
 
         if (!allowIPv4) {
             lp.addRoute(new RouteInfo(new IpPrefix(
-                    NetworkStackConstants.IPV4_ADDR_ANY, 0), RTN_UNREACHABLE));
+                    NetworkStackConstants.IPV4_ADDR_ANY, 0), null /*gateway*/,
+                    null /*iface*/, RTN_UNREACHABLE));
         }
         if (!allowIPv6) {
             lp.addRoute(new RouteInfo(new IpPrefix(
-                    NetworkStackConstants.IPV6_ADDR_ANY, 0), RTN_UNREACHABLE));
+                    NetworkStackConstants.IPV6_ADDR_ANY, 0), null /*gateway*/,
+                    null /*iface*/, RTN_UNREACHABLE));
         }
 
         // Concatenate search domains into a string.
@@ -1239,7 +1242,7 @@
         mLegacyState = LegacyVpnInfo.STATE_CONNECTING;
         updateState(DetailedState.CONNECTING, "agentConnect");
 
-        NetworkAgentConfig networkAgentConfig = new NetworkAgentConfig();
+        NetworkAgentConfig networkAgentConfig = new NetworkAgentConfig.Builder().build();
         networkAgentConfig.allowBypass = mConfig.allowBypass && !mLockdown;
 
         mNetworkCapabilities.setOwnerUid(mOwnerUID);
@@ -1258,9 +1261,11 @@
         }
 
         mNetworkAgent = new NetworkAgent(mContext, mLooper, NETWORKTYPE /* logtag */,
-                mNetworkCapabilities, lp, VPN_DEFAULT_SCORE, networkAgentConfig, mNetworkProvider) {
+                mNetworkCapabilities, lp,
+                new NetworkScore.Builder().setLegacyInt(VPN_DEFAULT_SCORE).build(),
+                networkAgentConfig, mNetworkProvider) {
             @Override
-            public void unwanted() {
+            public void onNetworkUnwanted() {
                 // We are user controlled, not driven by NetworkRequest.
             }
         };
@@ -1346,7 +1351,7 @@
         String oldInterface = mInterface;
         Connection oldConnection = mConnection;
         NetworkAgent oldNetworkAgent = mNetworkAgent;
-        Set<UidRange> oldUsers = mNetworkCapabilities.getUids();
+        Set<Range<Integer>> oldUsers = mNetworkCapabilities.getUids();
 
         // Configure the interface. Abort if any of these steps fails.
         ParcelFileDescriptor tun = ParcelFileDescriptor.adoptFd(jniCreate(config.mtu));
@@ -1452,7 +1457,7 @@
     }
 
     /**
-     * Creates a {@link Set} of non-intersecting {@link UidRange} objects including all UIDs
+     * Creates a {@link Set} of non-intersecting {@code Range<Integer>} objects including all UIDs
      * associated with one user, and any restricted profiles attached to that user.
      *
      * <p>If one of {@param allowedApplications} or {@param disallowedApplications} is provided,
@@ -1465,10 +1470,10 @@
      * @param disallowedApplications (optional) List of applications to deny.
      */
     @VisibleForTesting
-    Set<UidRange> createUserAndRestrictedProfilesRanges(@UserIdInt int userId,
+    Set<Range<Integer>> createUserAndRestrictedProfilesRanges(@UserIdInt int userId,
             @Nullable List<String> allowedApplications,
             @Nullable List<String> disallowedApplications) {
-        final Set<UidRange> ranges = new ArraySet<>();
+        final Set<Range<Integer>> ranges = new ArraySet<>();
 
         // Assign the top-level user to the set of ranges
         addUserToRanges(ranges, userId, allowedApplications, disallowedApplications);
@@ -1492,20 +1497,20 @@
     }
 
     /**
-     * Updates a {@link Set} of non-intersecting {@link UidRange} objects to include all UIDs
+     * Updates a {@link Set} of non-intersecting {@code Range<Integer>} objects to include all UIDs
      * associated with one user.
      *
      * <p>If one of {@param allowedApplications} or {@param disallowedApplications} is provided,
      * the UID ranges will match the app allowlist or denylist specified there. Otherwise, all UIDs
      * in the user will be included.
      *
-     * @param ranges {@link Set} of {@link UidRange}s to which to add.
+     * @param ranges {@link Set} of {@code Range<Integer>}s to which to add.
      * @param userId The userId to add to {@param ranges}.
      * @param allowedApplications (optional) allowlist of applications to include.
      * @param disallowedApplications (optional) denylist of applications to exclude.
      */
     @VisibleForTesting
-    void addUserToRanges(@NonNull Set<UidRange> ranges, @UserIdInt int userId,
+    void addUserToRanges(@NonNull Set<Range<Integer>> ranges, @UserIdInt int userId,
             @Nullable List<String> allowedApplications,
             @Nullable List<String> disallowedApplications) {
         if (allowedApplications != null) {
@@ -1515,40 +1520,41 @@
                 if (start == -1) {
                     start = uid;
                 } else if (uid != stop + 1) {
-                    ranges.add(new UidRange(start, stop));
+                    ranges.add(new Range<Integer>(start, stop));
                     start = uid;
                 }
                 stop = uid;
             }
-            if (start != -1) ranges.add(new UidRange(start, stop));
+            if (start != -1) ranges.add(new Range<Integer>(start, stop));
         } else if (disallowedApplications != null) {
             // Add all ranges for user skipping UIDs for disallowedApplications.
-            final UidRange userRange = UidRange.createForUser(UserHandle.of(userId));
-            int start = userRange.start;
+            final Range<Integer> userRange = createUidRangeForUser(userId);
+            int start = userRange.getLower();
             for (int uid : getAppsUids(disallowedApplications, userId)) {
                 if (uid == start) {
                     start++;
                 } else {
-                    ranges.add(new UidRange(start, uid - 1));
+                    ranges.add(new Range<Integer>(start, uid - 1));
                     start = uid + 1;
                 }
             }
-            if (start <= userRange.stop) ranges.add(new UidRange(start, userRange.stop));
+            if (start <= userRange.getUpper()) {
+                ranges.add(new Range<Integer>(start, userRange.getUpper()));
+            }
         } else {
             // Add all UIDs for the user.
-            ranges.add(UidRange.createForUser(UserHandle.of(userId)));
+            ranges.add(createUidRangeForUser(userId));
         }
     }
 
     // Returns the subset of the full list of active UID ranges the VPN applies to (mVpnUsers) that
     // apply to userId.
-    private static List<UidRange> uidRangesForUser(int userId, Set<UidRange> existingRanges) {
-        // UidRange#createForUser returns the entire range of UIDs available to a macro-user.
-        // This is something like 0-99999 ; {@see UserHandle#PER_USER_RANGE}
-        final UidRange userRange = UidRange.createForUser(UserHandle.of(userId));
-        final List<UidRange> ranges = new ArrayList<>();
-        for (UidRange range : existingRanges) {
-            if (userRange.containsRange(range)) {
+    private static List<Range<Integer>> uidRangesForUser(int userId,
+            Set<Range<Integer>> existingRanges) {
+        final Range<Integer> userRange = createUidRangeForUser(userId);
+        final List<Range<Integer>> ranges = new ArrayList<>();
+        for (Range<Integer> range : existingRanges) {
+            if (userRange.contains(range)) {
                 ranges.add(range);
             }
         }
@@ -1565,7 +1571,7 @@
         UserInfo user = mUserManager.getUserInfo(userId);
         if (user.isRestricted() && user.restrictedProfileParentId == mUserId) {
             synchronized(Vpn.this) {
-                final Set<UidRange> existingRanges = mNetworkCapabilities.getUids();
+                final Set<Range<Integer>> existingRanges = mNetworkCapabilities.getUids();
                 if (existingRanges != null) {
                     try {
                         addUserToRanges(existingRanges, userId, mConfig.allowedApplications,
@@ -1593,10 +1599,10 @@
         UserInfo user = mUserManager.getUserInfo(userId);
         if (user.isRestricted() && user.restrictedProfileParentId == mUserId) {
             synchronized(Vpn.this) {
-                final Set<UidRange> existingRanges = mNetworkCapabilities.getUids();
+                final Set<Range<Integer>> existingRanges = mNetworkCapabilities.getUids();
                 if (existingRanges != null) {
                     try {
-                        final List<UidRange> removedRanges =
+                        final List<Range<Integer>> removedRanges =
                                 uidRangesForUser(userId, existingRanges);
                         existingRanges.removeAll(removedRanges);
                         mNetworkCapabilities.setUids(existingRanges);
@@ -1657,7 +1663,7 @@
         final Set<UidRangeParcel> rangesToRemove = new ArraySet<>(mBlockedUidsAsToldToConnectivity);
         final Set<UidRangeParcel> rangesToAdd;
         if (enforce) {
-            final Set<UidRange> restrictedProfilesRanges =
+            final Set<Range<Integer>> restrictedProfilesRanges =
                     createUserAndRestrictedProfilesRanges(mUserId,
                     /* allowedApplications */ null,
                     /* disallowedApplications */ exemptedPackages);
@@ -1666,11 +1672,12 @@
             // The UID range of the first user (0-99999) would block the IPSec traffic, which comes
             // directly from the kernel and is marked as uid=0. So we adjust the range to allow
             // it through (b/69873852).
-            for (UidRange range : restrictedProfilesRanges) {
-                if (range.start == 0 && range.stop != 0) {
-                    rangesThatShouldBeBlocked.add(new UidRangeParcel(1, range.stop));
-                } else if (range.start != 0) {
-                    rangesThatShouldBeBlocked.add(new UidRangeParcel(range.start, range.stop));
+            for (Range<Integer> range : restrictedProfilesRanges) {
+                if (range.getLower() == 0 && range.getUpper() != 0) {
+                    rangesThatShouldBeBlocked.add(new UidRangeParcel(1, range.getUpper()));
+                } else if (range.getLower() != 0) {
+                    rangesThatShouldBeBlocked.add(
+                            new UidRangeParcel(range.getLower(), range.getUpper()));
                 }
             }
 
@@ -1692,12 +1699,12 @@
     }
 
     /**
-     * Tell ConnectivityService to add or remove a list of {@link UidRange}s to the list of UIDs
-     * that are only allowed to make connections through sockets that have had {@code protect()}
-     * called on them.
+     * Tell ConnectivityService to add or remove a list of {@link UidRangeParcel}s to the list of
+     * UIDs that are only allowed to make connections through sockets that have had
+     * {@code protect()} called on them.
      *
      * @param enforce {@code true} to add to the denylist, {@code false} to remove.
-     * @param ranges {@link Collection} of {@link UidRange}s to add (if {@param enforce} is
+     * @param ranges {@link Collection} of {@link UidRangeParcel}s to add (if {@param enforce} is
      *               {@code true}) or to remove.
      * @return {@code true} if all of the UIDs were added/removed. {@code false} otherwise,
      *         including added ranges that already existed or removed ones that didn't.
@@ -2696,7 +2703,8 @@
 
                     mConfig.routes.clear();
                     for (final RouteInfo route : oldRoutes) {
-                        mConfig.routes.add(new RouteInfo(route.getDestination(), RTN_UNREACHABLE));
+                        mConfig.routes.add(new RouteInfo(route.getDestination(), null /*gateway*/,
+                                null /*iface*/, RTN_UNREACHABLE));
                     }
                     if (mNetworkAgent != null) {
                         mNetworkAgent.sendLinkProperties(makeLinkProperties());
@@ -3035,10 +3043,12 @@
                 // Add a throw route for the VPN server endpoint, if one was specified.
                 if (endpointAddress instanceof Inet4Address) {
                     mConfig.routes.add(new RouteInfo(
-                            new IpPrefix(endpointAddress, 32), RTN_THROW));
+                            new IpPrefix(endpointAddress, 32), null /*gateway*/,
+                            null /*iface*/, RTN_THROW));
                 } else if (endpointAddress instanceof Inet6Address) {
                     mConfig.routes.add(new RouteInfo(
-                            new IpPrefix(endpointAddress, 128), RTN_THROW));
+                            new IpPrefix(endpointAddress, 128), null /*gateway*/,
+                            null /*iface*/, RTN_THROW));
                 } else {
                     Log.e(TAG, "Unknown IP address family for VPN endpoint: "
                             + endpointAddress);
@@ -3338,4 +3348,12 @@
                     firstChildSessionCallback);
         }
     }
+
+    /**
+     * Returns the entire range of UIDs available to a macro-user. This is something like 0-99999.
+     */
+    @VisibleForTesting
+    static Range<Integer> createUidRangeForUser(int userId) {
+        return new Range<Integer>(userId * PER_USER_RANGE, (userId + 1) * PER_USER_RANGE - 1);
+    }
 }
diff --git a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
index fa03e59..47eb3eb 100644
--- a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
+++ b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
@@ -405,7 +405,8 @@
         for (final IkeTrafficSelector selector : trafficSelectors) {
             for (final IpPrefix prefix :
                     new IpRange(selector.startingAddress, selector.endingAddress).asIpPrefixes()) {
-                routes.add(new RouteInfo(prefix, null));
+                routes.add(new RouteInfo(prefix, null /*gateway*/, null /*iface*/,
+                        RouteInfo.RTN_UNICAST));
             }
         }
 
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 294d7e2..0215188 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -92,7 +92,6 @@
 import android.security.AndroidKeyStoreMaintenance;
 import android.security.Authorization;
 import android.security.KeyStore;
-import android.security.keystore.AndroidKeyStoreProvider;
 import android.security.keystore.KeyProperties;
 import android.security.keystore.KeyProtection;
 import android.security.keystore.UserNotAuthenticatedException;
@@ -157,7 +156,6 @@
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Objects;
-import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -264,13 +262,7 @@
 
         @Override
         public void onStart() {
-            Optional<Boolean> keystore2_enabled =
-                    android.sysprop.Keystore2Properties.keystore2_enabled();
-            if (keystore2_enabled.isPresent() && keystore2_enabled.get()) {
-                android.security.keystore2.AndroidKeyStoreProvider.install();
-            } else {
-                AndroidKeyStoreProvider.install();
-            }
+            android.security.keystore2.AndroidKeyStoreProvider.install();
             mLockSettingsService = new LockSettingsService(getContext());
             publishBinderService("lock_settings", mLockSettingsService);
         }
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index aee0947..46c80e7 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -56,6 +56,25 @@
 import static android.net.NetworkPolicy.LIMIT_DISABLED;
 import static android.net.NetworkPolicy.SNOOZE_NEVER;
 import static android.net.NetworkPolicy.WARNING_DISABLED;
+import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_FOREGROUND;
+import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_MASK;
+import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_SYSTEM;
+import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_USER_EXEMPTED;
+import static android.net.NetworkPolicyManager.ALLOWED_REASON_FOREGROUND;
+import static android.net.NetworkPolicyManager.ALLOWED_REASON_NONE;
+import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_ALLOWLIST;
+import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST;
+import static android.net.NetworkPolicyManager.ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS;
+import static android.net.NetworkPolicyManager.ALLOWED_REASON_SYSTEM;
+import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_ADMIN_DISABLED;
+import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_DATA_SAVER;
+import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_MASK;
+import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_USER_RESTRICTED;
+import static android.net.NetworkPolicyManager.BLOCKED_REASON_APP_STANDBY;
+import static android.net.NetworkPolicyManager.BLOCKED_REASON_BATTERY_SAVER;
+import static android.net.NetworkPolicyManager.BLOCKED_REASON_DOZE;
+import static android.net.NetworkPolicyManager.BLOCKED_REASON_NONE;
+import static android.net.NetworkPolicyManager.BLOCKED_REASON_RESTRICTED_MODE;
 import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
 import static android.net.NetworkPolicyManager.MASK_ALL_NETWORKS;
@@ -244,6 +263,7 @@
 import com.android.internal.util.StatLogger;
 import com.android.internal.util.XmlUtils;
 import com.android.net.module.util.NetworkIdentityUtils;
+import com.android.net.module.util.PermissionUtils;
 import com.android.server.EventLogTags;
 import com.android.server.LocalServices;
 import com.android.server.ServiceThread;
@@ -414,6 +434,14 @@
     private static final int MSG_SET_NETWORK_TEMPLATE_ENABLED = 18;
     private static final int MSG_SUBSCRIPTION_PLANS_CHANGED = 19;
     private static final int MSG_STATS_PROVIDER_LIMIT_REACHED = 20;
+    // TODO: Add similar docs for other messages.
+    /**
+     * Message to indicate that reasons for why an uid is blocked changed.
+     * arg1 = uid
+     * arg2 = oldBlockedReasons
+     * obj = newBlockedReasons
+     */
+    private static final int MSG_BLOCKED_REASON_CHANGED = 21;
 
     private static final int UID_MSG_STATE_CHANGED = 100;
     private static final int UID_MSG_GONE = 101;
@@ -560,7 +588,10 @@
 
     /** Foreground at UID granularity. */
     @GuardedBy("mUidRulesFirstLock")
-    final SparseArray<UidState> mUidState = new SparseArray<UidState>();
+    private final SparseArray<UidState> mUidState = new SparseArray<>();
+
+    @GuardedBy("mUidRulesFirstLock")
+    private final SparseArray<UidBlockedState> mUidBlockedState = new SparseArray<>();
 
     /** Map from network ID to last observed meteredness state */
     @GuardedBy("mNetworkPoliciesSecondLock")
@@ -2879,15 +2910,18 @@
     }
 
     @Override
-    public void registerListener(INetworkPolicyListener listener) {
+    public void registerListener(@NonNull INetworkPolicyListener listener) {
+        Objects.requireNonNull(listener);
         // TODO: Remove CONNECTIVITY_INTERNAL and the *AnyPermissionOf methods above after all apps
         //  have declared OBSERVE_NETWORK_POLICY.
         enforceAnyPermissionOf(CONNECTIVITY_INTERNAL, OBSERVE_NETWORK_POLICY);
         mListeners.register(listener);
+        // TODO: Send callbacks to the newly registered listener
     }
 
     @Override
-    public void unregisterListener(INetworkPolicyListener listener) {
+    public void unregisterListener(@NonNull INetworkPolicyListener listener) {
+        Objects.requireNonNull(listener);
         // TODO: Remove CONNECTIVITY_INTERNAL and the *AnyPermissionOf methods above after all apps
         //  have declared OBSERVE_NETWORK_POLICY.
         enforceAnyPermissionOf(CONNECTIVITY_INTERNAL, OBSERVE_NETWORK_POLICY);
@@ -3081,8 +3115,16 @@
     @Override
     public int getRestrictBackgroundByCaller() {
         mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
-        final int uid = Binder.getCallingUid();
+        return getRestrictBackgroundStatusInternal(Binder.getCallingUid());
+    }
 
+    @Override
+    public int getRestrictBackgroundStatus(int uid) {
+        PermissionUtils.enforceNetworkStackPermission(mContext);
+        return getRestrictBackgroundStatusInternal(uid);
+    }
+
+    private int getRestrictBackgroundStatusInternal(int uid) {
         synchronized (mUidRulesFirstLock) {
             // Must clear identity because getUidPolicy() is restricted to system.
             final long token = Binder.clearCallingIdentity();
@@ -3551,6 +3593,7 @@
      * Get multipath preference value for the given network.
      */
     public int getMultipathPreference(Network network) {
+        PermissionUtils.enforceNetworkStackPermission(mContext);
         final Integer preference = mMultipathPolicyTracker.getMultipathPreference(network);
         if (preference != null) {
             return preference;
@@ -3923,6 +3966,7 @@
                 mUidRules.put(uid, newUidRule);
                 mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRule).sendToTarget();
             }
+            updateBlockedReasonsForRestrictedModeUL(uid);
         });
         if (mRestrictedNetworkingMode) {
             // firewall rules only need to be set when this mode is being enabled.
@@ -3943,6 +3987,7 @@
             mUidRules.put(uid, newUidRule);
             mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRule).sendToTarget();
         }
+        updateBlockedReasonsForRestrictedModeUL(uid);
 
         // if restricted networking mode is on, and the app has an access exemption, the uid rule
         // will not change, but the firewall rule will have to be updated.
@@ -3954,6 +3999,31 @@
         }
     }
 
+    private void updateBlockedReasonsForRestrictedModeUL(int uid) {
+        UidBlockedState uidBlockedState = mUidBlockedState.get(uid);
+        if (uidBlockedState == null) {
+            uidBlockedState = new UidBlockedState();
+            mUidBlockedState.put(uid, uidBlockedState);
+        }
+        final int oldEffectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons;
+        if (mRestrictedNetworkingMode) {
+            uidBlockedState.blockedReasons |= BLOCKED_REASON_RESTRICTED_MODE;
+        } else {
+            uidBlockedState.blockedReasons &= ~BLOCKED_REASON_RESTRICTED_MODE;
+        }
+        if (hasRestrictedModeAccess(uid)) {
+            uidBlockedState.allowedReasons |= ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS;
+        } else {
+            uidBlockedState.allowedReasons &= ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS;
+        }
+        uidBlockedState.updateEffectiveBlockedReasons();
+        if (oldEffectiveBlockedReasons != uidBlockedState.effectiveBlockedReasons) {
+            mHandler.obtainMessage(MSG_BLOCKED_REASON_CHANGED, uid,
+                    uidBlockedState.effectiveBlockedReasons, oldEffectiveBlockedReasons)
+                    .sendToTarget();
+        }
+    }
+
     private int getNewRestrictedModeUidRule(int uid, int oldUidRule) {
         int newRule = oldUidRule;
         newRule &= ~MASK_RESTRICTED_MODE_NETWORKS;
@@ -4074,11 +4144,21 @@
         boolean isWhitelisted = mPowerSaveTempWhitelistAppIds.get(appId)
                 || mPowerSaveWhitelistAppIds.get(appId);
         if (!deviceIdleMode) {
-            isWhitelisted = isWhitelisted || mPowerSaveWhitelistExceptIdleAppIds.get(appId);
+            isWhitelisted = isWhitelisted || isWhitelistedFromPowerSaveExceptIdleUL(uid);
         }
         return isWhitelisted;
     }
 
+    /**
+     * Returns whether a uid is allowlisted from power saving restrictions, except Device idle
+     * (eg: Battery Saver and app idle).
+     */
+    @GuardedBy("mUidRulesFirstLock")
+    private boolean isWhitelistedFromPowerSaveExceptIdleUL(int uid) {
+        final int appId = UserHandle.getAppId(uid);
+        return mPowerSaveWhitelistExceptIdleAppIds.get(appId);
+    }
+
     // NOTE: since both fw_dozable and fw_powersave uses the same map
     // (mPowerSaveTempWhitelistAppIds) for allowlisting, we can reuse their logic in this method.
     @GuardedBy("mUidRulesFirstLock")
@@ -4523,6 +4603,11 @@
         final int oldUidRules = mUidRules.get(uid, RULE_NONE);
         final boolean isForeground = isUidForegroundOnRestrictBackgroundUL(uid);
         final boolean isRestrictedByAdmin = isRestrictedByAdminUL(uid);
+        UidBlockedState uidBlockedState = mUidBlockedState.get(uid);
+        if (uidBlockedState == null) {
+            uidBlockedState = new UidBlockedState();
+            mUidBlockedState.put(uid, uidBlockedState);
+        }
 
         final boolean isDenied = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0;
         final boolean isAllowed = (uidPolicy & POLICY_ALLOW_METERED_BACKGROUND) != 0;
@@ -4547,6 +4632,16 @@
             }
         }
 
+        int newBlockedReasons = BLOCKED_REASON_NONE;
+        int newAllowedReasons = ALLOWED_REASON_NONE;
+        newBlockedReasons |= (isRestrictedByAdmin ? BLOCKED_METERED_REASON_ADMIN_DISABLED : 0);
+        newBlockedReasons |= (mRestrictBackground ? BLOCKED_METERED_REASON_DATA_SAVER : 0);
+        newBlockedReasons |= (isDenied ? BLOCKED_METERED_REASON_USER_RESTRICTED : 0);
+
+        newAllowedReasons |= (isSystem(uid) ? ALLOWED_METERED_REASON_SYSTEM : 0);
+        newAllowedReasons |= (isForeground ? ALLOWED_METERED_REASON_FOREGROUND : 0);
+        newAllowedReasons |= (isAllowed ? ALLOWED_METERED_REASON_USER_EXEMPTED : 0);
+
         if (LOGV) {
             Log.v(TAG, "updateRuleForRestrictBackgroundUL(" + uid + ")"
                     + ": isForeground=" +isForeground
@@ -4619,6 +4714,18 @@
             // Dispatch changed rule to existing listeners.
             mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget();
         }
+
+        final int oldEffectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons;
+        uidBlockedState.blockedReasons = (uidBlockedState.blockedReasons
+                & ~BLOCKED_METERED_REASON_MASK) | newBlockedReasons;
+        uidBlockedState.allowedReasons = (uidBlockedState.allowedReasons
+                & ~ALLOWED_METERED_REASON_MASK) | newAllowedReasons;
+        uidBlockedState.updateEffectiveBlockedReasons();
+        if (oldEffectiveBlockedReasons != uidBlockedState.effectiveBlockedReasons) {
+            mHandler.obtainMessage(MSG_BLOCKED_REASON_CHANGED, uid,
+                    uidBlockedState.effectiveBlockedReasons, oldEffectiveBlockedReasons)
+                    .sendToTarget();
+        }
     }
 
     /**
@@ -4692,6 +4799,12 @@
         // Copy existing uid rules and clear ALL_NETWORK rules.
         int newUidRules = oldUidRules & (~MASK_ALL_NETWORKS);
 
+        UidBlockedState uidBlockedState = mUidBlockedState.get(uid);
+        if (uidBlockedState == null) {
+            uidBlockedState = new UidBlockedState();
+            mUidBlockedState.put(uid, uidBlockedState);
+        }
+
         // First step: define the new rule based on user restrictions and foreground state.
 
         // NOTE: if statements below could be inlined, but it's easier to understand the logic
@@ -4704,6 +4817,20 @@
             newUidRules |= isWhitelisted ? RULE_ALLOW_ALL : RULE_REJECT_ALL;
         }
 
+        int newBlockedReasons = BLOCKED_REASON_NONE;
+        int newAllowedReasons = ALLOWED_REASON_NONE;
+        newBlockedReasons |= (mRestrictPower ? BLOCKED_REASON_BATTERY_SAVER : 0);
+        newBlockedReasons |= (mDeviceIdleMode ? BLOCKED_REASON_DOZE : 0);
+        newBlockedReasons |= (isUidIdle ? BLOCKED_REASON_APP_STANDBY : 0);
+        newBlockedReasons |= (uidBlockedState.blockedReasons & BLOCKED_REASON_RESTRICTED_MODE);
+
+        newAllowedReasons |= (isSystem(uid) ? ALLOWED_REASON_SYSTEM : 0);
+        newAllowedReasons |= (isForeground ? ALLOWED_REASON_FOREGROUND : 0);
+        newAllowedReasons |= (isWhitelistedFromPowerSaveUL(uid, true)
+                ? ALLOWED_REASON_POWER_SAVE_ALLOWLIST : 0);
+        newAllowedReasons |= (isWhitelistedFromPowerSaveExceptIdleUL(uid)
+                ? ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST : 0);
+
         if (LOGV) {
             Log.v(TAG, "updateRulesForPowerRestrictionsUL(" + uid + ")"
                     + ", isIdle: " + isUidIdle
@@ -4735,6 +4862,18 @@
             mHandler.obtainMessage(MSG_RULES_CHANGED, uid, newUidRules).sendToTarget();
         }
 
+        final int oldEffectiveBlockedReasons = uidBlockedState.effectiveBlockedReasons;
+        uidBlockedState.blockedReasons = (uidBlockedState.blockedReasons
+                & BLOCKED_METERED_REASON_MASK) | newBlockedReasons;
+        uidBlockedState.allowedReasons = (uidBlockedState.allowedReasons
+                & ALLOWED_METERED_REASON_MASK) | newAllowedReasons;
+        uidBlockedState.updateEffectiveBlockedReasons();
+        if (oldEffectiveBlockedReasons != uidBlockedState.effectiveBlockedReasons) {
+            mHandler.obtainMessage(MSG_BLOCKED_REASON_CHANGED, uid,
+                    uidBlockedState.effectiveBlockedReasons, oldEffectiveBlockedReasons)
+                    .sendToTarget();
+        }
+
         return newUidRules;
     }
 
@@ -4764,61 +4903,57 @@
     }
 
     private void dispatchUidRulesChanged(INetworkPolicyListener listener, int uid, int uidRules) {
-        if (listener != null) {
-            try {
-                listener.onUidRulesChanged(uid, uidRules);
-            } catch (RemoteException ignored) {
-            }
+        try {
+            listener.onUidRulesChanged(uid, uidRules);
+        } catch (RemoteException ignored) {
         }
     }
 
     private void dispatchMeteredIfacesChanged(INetworkPolicyListener listener,
             String[] meteredIfaces) {
-        if (listener != null) {
-            try {
-                listener.onMeteredIfacesChanged(meteredIfaces);
-            } catch (RemoteException ignored) {
-            }
+        try {
+            listener.onMeteredIfacesChanged(meteredIfaces);
+        } catch (RemoteException ignored) {
         }
     }
 
     private void dispatchRestrictBackgroundChanged(INetworkPolicyListener listener,
             boolean restrictBackground) {
-        if (listener != null) {
-            try {
-                listener.onRestrictBackgroundChanged(restrictBackground);
-            } catch (RemoteException ignored) {
-            }
+        try {
+            listener.onRestrictBackgroundChanged(restrictBackground);
+        } catch (RemoteException ignored) {
         }
     }
 
     private void dispatchUidPoliciesChanged(INetworkPolicyListener listener, int uid,
             int uidPolicies) {
-        if (listener != null) {
-            try {
-                listener.onUidPoliciesChanged(uid, uidPolicies);
-            } catch (RemoteException ignored) {
-            }
+        try {
+            listener.onUidPoliciesChanged(uid, uidPolicies);
+        } catch (RemoteException ignored) {
         }
     }
 
     private void dispatchSubscriptionOverride(INetworkPolicyListener listener, int subId,
             int overrideMask, int overrideValue, int[] networkTypes) {
-        if (listener != null) {
-            try {
-                listener.onSubscriptionOverride(subId, overrideMask, overrideValue, networkTypes);
-            } catch (RemoteException ignored) {
-            }
+        try {
+            listener.onSubscriptionOverride(subId, overrideMask, overrideValue, networkTypes);
+        } catch (RemoteException ignored) {
         }
     }
 
     private void dispatchSubscriptionPlansChanged(INetworkPolicyListener listener, int subId,
             SubscriptionPlan[] plans) {
-        if (listener != null) {
-            try {
-                listener.onSubscriptionPlansChanged(subId, plans);
-            } catch (RemoteException ignored) {
-            }
+        try {
+            listener.onSubscriptionPlansChanged(subId, plans);
+        } catch (RemoteException ignored) {
+        }
+    }
+
+    private void dispatchBlockedReasonChanged(INetworkPolicyListener listener, int uid,
+            int oldBlockedReasons, int newBlockedReasons) {
+        try {
+            listener.onBlockedReasonChanged(uid, oldBlockedReasons, newBlockedReasons);
+        } catch (RemoteException ignored) {
         }
     }
 
@@ -4975,6 +5110,19 @@
                     mListeners.finishBroadcast();
                     return true;
                 }
+                case MSG_BLOCKED_REASON_CHANGED: {
+                    final int uid = msg.arg1;
+                    final int newBlockedReasons = msg.arg2;
+                    final int oldBlockedReasons = (int) msg.obj;
+                    final int length = mListeners.beginBroadcast();
+                    for (int i = 0; i < length; i++) {
+                        final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
+                        dispatchBlockedReasonChanged(listener, uid,
+                                oldBlockedReasons, newBlockedReasons);
+                    }
+                    mListeners.finishBroadcast();
+                    return true;
+                }
                 default: {
                     return false;
                 }
@@ -5706,6 +5854,56 @@
         return (bundle != null) ? bundle.getBoolean(key, defaultValue) : defaultValue;
     }
 
+    private class UidBlockedState {
+        public int blockedReasons;
+        public int allowedReasons;
+        public int effectiveBlockedReasons;
+
+        UidBlockedState() {
+            blockedReasons = BLOCKED_REASON_NONE;
+            allowedReasons = ALLOWED_REASON_NONE;
+            effectiveBlockedReasons = BLOCKED_REASON_NONE;
+        }
+
+        void updateEffectiveBlockedReasons() {
+            effectiveBlockedReasons = blockedReasons;
+            // If the uid is not subject to any blocked reasons, then return early
+            if (blockedReasons == BLOCKED_REASON_NONE) {
+                return;
+            }
+            if ((allowedReasons & ALLOWED_REASON_SYSTEM) != 0) {
+                effectiveBlockedReasons = (blockedReasons & ALLOWED_METERED_REASON_MASK);
+            }
+            if ((allowedReasons & ALLOWED_METERED_REASON_SYSTEM) != 0) {
+                effectiveBlockedReasons = (blockedReasons & ~ALLOWED_METERED_REASON_MASK);
+            }
+            if ((allowedReasons & ALLOWED_REASON_FOREGROUND) != 0) {
+                effectiveBlockedReasons &= ~BLOCKED_REASON_BATTERY_SAVER;
+                effectiveBlockedReasons &= ~BLOCKED_REASON_DOZE;
+                effectiveBlockedReasons &= ~BLOCKED_REASON_APP_STANDBY;
+            }
+            if ((allowedReasons & ALLOWED_METERED_REASON_FOREGROUND) != 0) {
+                effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_DATA_SAVER;
+                effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_USER_RESTRICTED;
+            }
+            if ((allowedReasons & ALLOWED_REASON_POWER_SAVE_ALLOWLIST) != 0) {
+                effectiveBlockedReasons &= ~BLOCKED_REASON_BATTERY_SAVER;
+                effectiveBlockedReasons &= ~BLOCKED_REASON_DOZE;
+                effectiveBlockedReasons &= ~BLOCKED_REASON_APP_STANDBY;
+            }
+            if ((allowedReasons & ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST) != 0) {
+                effectiveBlockedReasons &= ~BLOCKED_REASON_BATTERY_SAVER;
+                effectiveBlockedReasons &= ~BLOCKED_REASON_APP_STANDBY;
+            }
+            if ((allowedReasons & ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS) != 0) {
+                effectiveBlockedReasons &= ~BLOCKED_REASON_RESTRICTED_MODE;
+            }
+            if ((allowedReasons & ALLOWED_METERED_REASON_USER_EXEMPTED) != 0) {
+                effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_DATA_SAVER;
+            }
+        }
+    }
+
     private class NotificationId {
         private final String mTag;
         private final int mId;
diff --git a/services/core/java/com/android/server/os/NativeTombstoneManager.java b/services/core/java/com/android/server/os/NativeTombstoneManager.java
index 9c4c510..cc6a824 100644
--- a/services/core/java/com/android/server/os/NativeTombstoneManager.java
+++ b/services/core/java/com/android/server/os/NativeTombstoneManager.java
@@ -411,8 +411,13 @@
                             processName = stream.readString(Tombstone.PROCESS_NAME);
                             break;
 
-                        case (int) Tombstone.CAUSE:
-                            long token = stream.start(Tombstone.CAUSE);
+                        case (int) Tombstone.CAUSES:
+                            if (!crashReason.equals("")) {
+                                // Causes appear in decreasing order of likelihood. For now we only
+                                // want the most likely crash reason here, so ignore all others.
+                                break;
+                            }
+                            long token = stream.start(Tombstone.CAUSES);
                         cause:
                             while (stream.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
                                 switch (stream.getFieldNumber()) {
diff --git a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java
index 0c8e36b..c8dc1b1 100644
--- a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java
+++ b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java
@@ -146,47 +146,11 @@
                 uid,
                 compilationReason,
                 compilerFilter,
-                ArtStatsLog.ART_DATUM_REPORTED__KIND__ART_DATUM_DEX2OAT_DEX_CODE_BYTES,
-                getDexBytes(path),
-                dexMetadataType);
-        logger.write(
-                sessionId,
-                uid,
-                compilationReason,
-                compilerFilter,
                 ArtStatsLog.ART_DATUM_REPORTED__KIND__ART_DATUM_DEX2OAT_TOTAL_TIME,
                 compileTime,
                 dexMetadataType);
     }
 
-    private static long getDexBytes(String apkPath) {
-        StrictJarFile jarFile = null;
-        long dexBytes = 0;
-        try {
-            jarFile = new StrictJarFile(apkPath,
-                    /*verify=*/ false,
-                    /*signatureSchemeRollbackProtectionsEnforced=*/ false);
-            Iterator<ZipEntry> it = jarFile.iterator();
-            while (it.hasNext()) {
-                ZipEntry entry = it.next();
-                if (entry.getName().matches("classes(\\d)*[.]dex")) {
-                    dexBytes += entry.getSize();
-                }
-            }
-            return dexBytes;
-        } catch (IOException ignore) {
-            Slog.e(TAG, "Error when parsing APK " + apkPath);
-            return -1L;
-        } finally {
-            try {
-                if (jarFile != null) {
-                    jarFile.close();
-                }
-            } catch (IOException ignore) {
-            }
-        }
-    }
-
     private static int getDexMetadataType(String dexMetadataPath) {
         if (dexMetadataPath == null) {
             return ArtStatsLog.ART_DATUM_REPORTED__DEX_METADATA_TYPE__ART_DEX_METADATA_TYPE_NONE;
diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
index 69a153f..9589505 100644
--- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
+++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
@@ -42,7 +42,6 @@
 import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkAgent;
-import android.net.NetworkAgent.ValidationStatus;
 import android.net.NetworkAgentConfig;
 import android.net.NetworkCapabilities;
 import android.net.RouteInfo;
@@ -1442,17 +1441,16 @@
                             caps,
                             lp,
                             Vcn.getNetworkScore(),
-                            new NetworkAgentConfig(),
+                            new NetworkAgentConfig.Builder().build(),
                             mVcnContext.getVcnNetworkProvider()) {
                         @Override
-                        public void unwanted() {
+                        public void onNetworkUnwanted() {
                             Slog.d(TAG, "NetworkAgent was unwanted");
                             teardownAsynchronously();
                         }
 
                         @Override
-                        public void onValidationStatus(
-                                @ValidationStatus int status, @Nullable Uri redirectUri) {
+                        public void onValidationStatus(int status, @Nullable Uri redirectUri) {
                             if (status == NetworkAgent.VALIDATION_STATUS_VALID) {
                                 clearFailedAttemptCounterAndSafeModeAlarm();
                             }
@@ -1798,8 +1796,10 @@
             lp.addDnsServer(addr);
         }
 
-        lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
-        lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
+        lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null /*gateway*/,
+                null /*iface*/, RouteInfo.RTN_UNICAST));
+        lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null /*gateway*/,
+                null /*iface*/, RouteInfo.RTN_UNICAST));
 
         lp.setMtu(gatewayConnectionConfig.getMaxMtu());
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/dex/OWNERS b/services/tests/mockingservicestests/src/com/android/server/pm/dex/OWNERS
index 5a4431e..5492dc8 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/dex/OWNERS
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/dex/OWNERS
@@ -1,2 +1 @@
-calin@google.com
-ngeoffray@google.com
+include platform/art:/OWNERS
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java b/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java
index 1c96838..1b8ab21 100644
--- a/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java
@@ -18,6 +18,7 @@
 
 import static android.content.pm.PackageManager.MATCH_ANY_USER;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.AdditionalAnswers.returnsArgAt;
 import static org.mockito.ArgumentMatchers.any;
@@ -67,6 +68,7 @@
     private static final String PACKAGE_SCHEME = "package";
     private static final String PACKAGE_NAME_1 = "package1";
     private static final String PACKAGE_NAME_2 = "package2";
+    private static final String PACKAGE_NAME_3 = "package3";
     private static final int USER_ID_1 = 1;
     private static final int USER_ID_2 = 2;
 
@@ -107,6 +109,8 @@
 
         List<PackageInfo> packages = new ArrayList<>();
         packages.add(makePackageInfo(PACKAGE_NAME_1));
+        packages.add(makePackageInfo(PACKAGE_NAME_2));
+        packages.add(makePackageInfo(PACKAGE_NAME_3));
         doReturn(new ParceledListSlice<>(packages)).when(mIPackageManager).getInstalledPackages(
                 intThat(arg -> (arg & MATCH_ANY_USER) != 0), anyInt());
         mAppHibernationService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
@@ -179,6 +183,26 @@
         assertTrue(mAppHibernationService.isHibernatingGlobally(PACKAGE_NAME_1));
     }
 
+    @Test
+    public void testGetHibernatingPackagesForUser_returnsCorrectPackages() throws RemoteException {
+        // GIVEN an unlocked user with all packages installed
+        UserInfo userInfo =
+                addUser(USER_ID_2, new String[]{PACKAGE_NAME_1, PACKAGE_NAME_2, PACKAGE_NAME_3});
+        mAppHibernationService.onUserUnlocking(new SystemService.TargetUser(userInfo));
+        doReturn(true).when(mUserManager).isUserUnlockingOrUnlocked(USER_ID_2);
+
+        // WHEN packages are hibernated for the user
+        mAppHibernationService.setHibernatingForUser(PACKAGE_NAME_1, USER_ID_2, true);
+        mAppHibernationService.setHibernatingForUser(PACKAGE_NAME_2, USER_ID_2, true);
+
+        // THEN the hibernating packages returned matches
+        List<String> hibernatingPackages =
+                mAppHibernationService.getHibernatingPackagesForUser(USER_ID_2);
+        assertEquals(2, hibernatingPackages.size());
+        assertTrue(hibernatingPackages.contains(PACKAGE_NAME_1));
+        assertTrue(hibernatingPackages.contains(PACKAGE_NAME_2));
+    }
+
     /**
      * Add a mock user with one package.
      */
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/ArtStatsLogUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/dex/ArtStatsLogUtilsTest.java
index e605d75..13d75a7 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/ArtStatsLogUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/ArtStatsLogUtilsTest.java
@@ -245,14 +245,6 @@
                 UID,
                 COMPILATION_REASON,
                 COMPILER_FILTER,
-                ArtStatsLog.ART_DATUM_REPORTED__KIND__ART_DATUM_DEX2OAT_DEX_CODE_BYTES,
-                DEX_CONTENT.length,
-                dexMetadataType);
-        inorder.verify(mockLogger).write(
-                SESSION_ID,
-                UID,
-                COMPILATION_REASON,
-                COMPILER_FILTER,
                 ArtStatsLog.ART_DATUM_REPORTED__KIND__ART_DATUM_DEX2OAT_TOTAL_TIME,
                 COMPILE_TIME,
                 dexMetadataType);
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index ec7d4bd..647a2a2 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -60,9 +60,9 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.service.ServiceProtoEnums;
 import android.service.usb.UsbPortInfoProto;
 import android.service.usb.UsbPortManagerProto;
-import android.service.usb.UsbServiceProto;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Slog;
@@ -992,15 +992,15 @@
     private static int convertContaminantDetectionStatusToProto(int contaminantDetectionStatus) {
         switch (contaminantDetectionStatus) {
             case UsbPortStatus.CONTAMINANT_DETECTION_NOT_SUPPORTED:
-                return UsbServiceProto.CONTAMINANT_STATUS_NOT_SUPPORTED;
+                return ServiceProtoEnums.CONTAMINANT_STATUS_NOT_SUPPORTED;
             case UsbPortStatus.CONTAMINANT_DETECTION_DISABLED:
-                return UsbServiceProto.CONTAMINANT_STATUS_DISABLED;
+                return ServiceProtoEnums.CONTAMINANT_STATUS_DISABLED;
             case UsbPortStatus.CONTAMINANT_DETECTION_NOT_DETECTED:
-                return UsbServiceProto.CONTAMINANT_STATUS_NOT_DETECTED;
+                return ServiceProtoEnums.CONTAMINANT_STATUS_NOT_DETECTED;
             case UsbPortStatus.CONTAMINANT_DETECTION_DETECTED:
-                return UsbServiceProto.CONTAMINANT_STATUS_DETECTED;
+                return ServiceProtoEnums.CONTAMINANT_STATUS_DETECTED;
             default:
-                return UsbServiceProto.CONTAMINANT_STATUS_UNKNOWN;
+                return ServiceProtoEnums.CONTAMINANT_STATUS_UNKNOWN;
         }
     }
 
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 217570e..ae1984e 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -42,8 +42,6 @@
 import com.android.internal.telephony.ICarrierConfigLoader;
 import com.android.telephony.Rlog;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -110,31 +108,17 @@
      */
     public static final int USSD_OVER_IMS_ONLY       = 3;
 
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = { "CARRIER_NR_AVAILABILITY_" }, value = {
-            CARRIER_NR_AVAILABILITY_NONE,
-            CARRIER_NR_AVAILABILITY_NSA,
-            CARRIER_NR_AVAILABILITY_SA,
-    })
-    public @interface DeviceNrCapability {}
-
-    /**
-     * Indicates CARRIER_NR_AVAILABILITY_NONE determine that the carrier does not enable 5G NR.
-     */
-    public static final int CARRIER_NR_AVAILABILITY_NONE = 0;
-
     /**
      * Indicates CARRIER_NR_AVAILABILITY_NSA determine that the carrier enable the non-standalone
      * (NSA) mode of 5G NR.
      */
-    public static final int CARRIER_NR_AVAILABILITY_NSA = 1 << 0;
+    public static final int CARRIER_NR_AVAILABILITY_NSA = 1;
 
     /**
      * Indicates CARRIER_NR_AVAILABILITY_SA determine that the carrier enable the standalone (SA)
      * mode of 5G NR.
      */
-    public static final int CARRIER_NR_AVAILABILITY_SA = 1 << 1;
+    public static final int CARRIER_NR_AVAILABILITY_SA = 2;
 
     private final Context mContext;
 
@@ -1807,23 +1791,20 @@
             "show_precise_failed_cause_bool";
 
     /**
-     * Bit-field integer to determine whether the carrier enable the non-standalone (NSA) mode of
-     * 5G NR, standalone (SA) mode of 5G NR
+     * A list of carrier nr availability is used to determine whether the carrier enable the
+     * non-standalone (NSA) mode of 5G NR, standalone (SA) mode of 5G NR
      *
-     * <UL>
-     *  <LI>CARRIER_NR_AVAILABILITY_NONE: non-NR = 0 </LI>
-     *  <LI>CARRIER_NR_AVAILABILITY_NSA: NSA = 1 << 0</LI>
-     *  <LI>CARRIER_NR_AVAILABILITY_SA: SA = 1 << 1</LI>
-     * </UL>
-     * <p> The value of this key must be bitwise OR of
-     * {@link #CARRIER_NR_AVAILABILITY_NONE}, {@link #CARRIER_NR_AVAILABILITY_NSA},
-     * {@link #CARRIER_NR_AVAILABILITY_SA}.
+     * <p> The value of list is
+     * {@link #CARRIER_NR_AVAILABILITY_NSA}, or {@link #CARRIER_NR_AVAILABILITY_SA}.
      *
-     * <p> For example, if both NSA and SA are used, the value of key is 3 (1 << 0 | 1 << 1).
-     * If the carrier doesn't support 5G NR, the value of key is 0 (non-NR).
-     * If the key is invalid or not configured, a default value 3 (NSA|SA = 3) will apply.
+     * <p> For example, if both NSA and SA are used, the list value is {
+     * {@link #CARRIER_NR_AVAILABILITY_NSA},{@link #CARRIER_NR_AVAILABILITY_SA}}.
+     * If the carrier doesn't support 5G NR, the value is the empty array.
+     * If the key is invalid or not configured, the default value {
+     * {@link #CARRIER_NR_AVAILABILITY_NSA},{@link #CARRIER_NR_AVAILABILITY_SA}} will apply.
      */
-    public static final String KEY_CARRIER_NR_AVAILABILITY_INT = "carrier_nr_availability_int";
+    public static final String KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY =
+            "carrier_nr_availabilities_int_array";
 
     /**
      * Boolean to decide whether LTE is enabled.
@@ -4268,6 +4249,14 @@
     public static final String KEY_STORE_SIM_PIN_FOR_UNATTENDED_REBOOT_BOOL =
             "store_sim_pin_for_unattended_reboot_bool";
 
+     /**
+     * Determine whether "Enable 2G" toggle can be shown.
+     *
+     * Used to trade privacy/security against potentially reduced carrier coverage for some
+     * carriers.
+     */
+    public static final String KEY_HIDE_ENABLE_2G = "hide_enable_2g_bool";
+
     /** The default value for every variable. */
     private final static PersistableBundle sDefaults;
 
@@ -4645,8 +4634,8 @@
         sDefaults.putString(KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING, "");
         sDefaults.putBoolean(KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL, true);
         sDefaults.putInt(KEY_LTE_PLUS_THRESHOLD_BANDWIDTH_KHZ_INT, 20000);
-        sDefaults.putInt(KEY_CARRIER_NR_AVAILABILITY_INT,
-                CARRIER_NR_AVAILABILITY_NSA | CARRIER_NR_AVAILABILITY_SA);
+        sDefaults.putIntArray(KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY,
+                new int[]{CARRIER_NR_AVAILABILITY_NSA, CARRIER_NR_AVAILABILITY_SA});
         sDefaults.putBoolean(KEY_LTE_ENABLED_BOOL, true);
         sDefaults.putBoolean(KEY_SUPPORT_TDSCDMA_BOOL, false);
         sDefaults.putStringArray(KEY_SUPPORT_TDSCDMA_ROAMING_NETWORKS_STRING_ARRAY, null);
@@ -4825,6 +4814,7 @@
         sDefaults.putStringArray(KEY_ALLOWED_INITIAL_ATTACH_APN_TYPES_STRING_ARRAY,
                 new String[]{"ia", "default", "ims", "mms", "dun", "emergency"});
         sDefaults.putBoolean(KEY_STORE_SIM_PIN_FOR_UNATTENDED_REBOOT_BOOL, true);
+        sDefaults.putBoolean(KEY_HIDE_ENABLE_2G, false);
     }
 
     /**
diff --git a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
index 597fe8f..957f683 100644
--- a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
+++ b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
@@ -68,22 +68,22 @@
     public final boolean isEnDcAvailable;
 
     /**
-     * Provides network support info for LTE VoPS and LTE Emergency bearer support
+     * Provides network support info for VoPS and Emergency bearer support
      */
     @Nullable
-    private final LteVopsSupportInfo mLteVopsSupportInfo;
+    private final VopsSupportInfo mVopsSupportInfo;
 
     /**
      * @hide
      */
     DataSpecificRegistrationInfo(
             int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable,
-            boolean isEnDcAvailable, @Nullable LteVopsSupportInfo lteVops) {
+            boolean isEnDcAvailable, @Nullable VopsSupportInfo vops) {
         this.maxDataCalls = maxDataCalls;
         this.isDcNrRestricted = isDcNrRestricted;
         this.isNrAvailable = isNrAvailable;
         this.isEnDcAvailable = isEnDcAvailable;
-        this.mLteVopsSupportInfo = lteVops;
+        this.mVopsSupportInfo = vops;
     }
 
     /**
@@ -97,7 +97,7 @@
         isDcNrRestricted = dsri.isDcNrRestricted;
         isNrAvailable = dsri.isNrAvailable;
         isEnDcAvailable = dsri.isEnDcAvailable;
-        mLteVopsSupportInfo = dsri.mLteVopsSupportInfo;
+        mVopsSupportInfo = dsri.mVopsSupportInfo;
     }
 
     private DataSpecificRegistrationInfo(/* @NonNull */ Parcel source) {
@@ -105,7 +105,7 @@
         isDcNrRestricted = source.readBoolean();
         isNrAvailable = source.readBoolean();
         isEnDcAvailable = source.readBoolean();
-        mLteVopsSupportInfo = LteVopsSupportInfo.CREATOR.createFromParcel(source);
+        mVopsSupportInfo = source.readParcelable(VopsSupportInfo.class.getClassLoader());
     }
 
     @Override
@@ -114,7 +114,7 @@
         dest.writeBoolean(isDcNrRestricted);
         dest.writeBoolean(isNrAvailable);
         dest.writeBoolean(isEnDcAvailable);
-        mLteVopsSupportInfo.writeToParcel(dest, flags);
+        dest.writeParcelable(mVopsSupportInfo, flags);
     }
 
     @Override
@@ -131,15 +131,15 @@
                 .append(" isDcNrRestricted = " + isDcNrRestricted)
                 .append(" isNrAvailable = " + isNrAvailable)
                 .append(" isEnDcAvailable = " + isEnDcAvailable)
-                .append(" " + mLteVopsSupportInfo)
+                .append(" " + mVopsSupportInfo)
                 .append(" }")
                 .toString();
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable, isEnDcAvailable,
-                mLteVopsSupportInfo);
+        return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable,
+                isEnDcAvailable, mVopsSupportInfo);
     }
 
     @Override
@@ -153,7 +153,7 @@
                 && this.isDcNrRestricted == other.isDcNrRestricted
                 && this.isNrAvailable == other.isNrAvailable
                 && this.isEnDcAvailable == other.isEnDcAvailable
-                && Objects.equals(mLteVopsSupportInfo, other.mLteVopsSupportInfo);
+                && Objects.equals(mVopsSupportInfo, other.mVopsSupportInfo);
     }
 
     public static final @NonNull Parcelable.Creator<DataSpecificRegistrationInfo> CREATOR =
@@ -171,10 +171,26 @@
 
     /**
      * @return The LTE VOPS (Voice over Packet Switched) support information
+     *
+     * @deprecated use {@link #getVopsSupportInfo()}
      */
+    @Deprecated
     @NonNull
     public LteVopsSupportInfo getLteVopsSupportInfo() {
-        return mLteVopsSupportInfo;
+        return mVopsSupportInfo instanceof LteVopsSupportInfo
+                ? (LteVopsSupportInfo) mVopsSupportInfo
+                : new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE,
+                LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE);
     }
 
+    /**
+     * @return The VOPS (Voice over Packet Switched) support information.
+     *
+     * The instance of {@link LTEVopsSupportInfo}, or {@link NrVopsSupportInfo},
+     * null if there is there is no VOPS support information available.
+     */
+    @Nullable
+    public VopsSupportInfo getVopsSupportInfo() {
+        return mVopsSupportInfo;
+    }
 }
diff --git a/telephony/java/android/telephony/DataThrottlingRequest.java b/telephony/java/android/telephony/DataThrottlingRequest.java
index f50bb58..2827e8d 100644
--- a/telephony/java/android/telephony/DataThrottlingRequest.java
+++ b/telephony/java/android/telephony/DataThrottlingRequest.java
@@ -17,6 +17,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.RequiresFeature;
 import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -52,6 +53,9 @@
      * @hide
      */
     @SystemApi
+    @RequiresFeature(
+            enforcement = "android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported",
+            value = TelephonyManager.CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING)
     public static final int DATA_THROTTLING_ACTION_THROTTLE_SECONDARY_CARRIER = 1;
 
     /**
@@ -63,6 +67,9 @@
      * @hide
      */
     @SystemApi
+    @RequiresFeature(
+            enforcement = "android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported",
+            value = TelephonyManager.CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING)
     public static final int DATA_THROTTLING_ACTION_THROTTLE_PRIMARY_CARRIER = 2;
 
     /**
@@ -76,6 +83,9 @@
      * @hide
      */
     @SystemApi
+    @RequiresFeature(
+            enforcement = "android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported",
+            value = TelephonyManager.CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING)
     public static final int DATA_THROTTLING_ACTION_HOLD = 3;
 
     /**
diff --git a/telephony/java/android/telephony/LteVopsSupportInfo.java b/telephony/java/android/telephony/LteVopsSupportInfo.java
index 83e41bf..87761e2 100644
--- a/telephony/java/android/telephony/LteVopsSupportInfo.java
+++ b/telephony/java/android/telephony/LteVopsSupportInfo.java
@@ -21,7 +21,7 @@
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.os.Parcel;
-import android.os.Parcelable;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -32,7 +32,7 @@
  * @hide
  */
 @SystemApi
-public final class LteVopsSupportInfo implements Parcelable {
+public final class LteVopsSupportInfo extends VopsSupportInfo {
 
     /**@hide*/
     @Retention(RetentionPolicy.SOURCE)
@@ -42,7 +42,10 @@
     public @interface LteVopsStatus {}
     /**
      * Indicates information not available from modem.
+     *
+     * @deprecated as no instance will be created in this case
      */
+    @Deprecated
     public static final int LTE_STATUS_NOT_AVAILABLE = 1;
 
     /**
@@ -82,13 +85,38 @@
         return mEmcBearerSupport;
     }
 
+    /**
+     * Returns whether VoPS is supported by the network
+     */
+    @Override
+    public boolean isVopsSupported() {
+        return mVopsSupport == LTE_STATUS_SUPPORTED;
+    }
+
+    /**
+     * Returns whether emergency service is supported by the network
+     */
+    @Override
+    public boolean isEmergencyServiceSupported() {
+        return mEmcBearerSupport == LTE_STATUS_SUPPORTED;
+    }
+
+    /**
+     * Returns whether emergency service fallback is supported by the network
+     */
+    @Override
+    public boolean isEmergencyServiceFallbackSupported() {
+        return false;
+    }
+
     @Override
     public int describeContents() {
         return 0;
     }
 
     @Override
-    public void writeToParcel(Parcel out, int flags) {
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        super.writeToParcel(out, flags, AccessNetworkType.EUTRAN);
         out.writeInt(mVopsSupport);
         out.writeInt(mEmcBearerSupport);
     }
@@ -124,6 +152,8 @@
             new Creator<LteVopsSupportInfo>() {
         @Override
         public LteVopsSupportInfo createFromParcel(Parcel in) {
+            // Skip the type info.
+            in.readInt();
             return new LteVopsSupportInfo(in);
         }
 
@@ -133,6 +163,11 @@
         }
     };
 
+    /** @hide */
+    protected static LteVopsSupportInfo createFromParcelBody(Parcel in) {
+        return new LteVopsSupportInfo(in);
+    }
+
     private LteVopsSupportInfo(Parcel in) {
         mVopsSupport = in.readInt();
         mEmcBearerSupport = in.readInt();
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index a78f813..5fb60d7 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -293,11 +293,12 @@
                                    @Nullable CellIdentity cellIdentity, @Nullable String rplmn,
                                    int maxDataCalls, boolean isDcNrRestricted,
                                    boolean isNrAvailable, boolean isEndcAvailable,
-                                   LteVopsSupportInfo lteVopsSupportInfo) {
+                                   @Nullable VopsSupportInfo vopsSupportInfo) {
         this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause,
                 emergencyOnly, availableServices, cellIdentity, rplmn);
         mDataSpecificInfo = new DataSpecificRegistrationInfo(
-                maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, lteVopsSupportInfo);
+                maxDataCalls, isDcNrRestricted, isNrAvailable,
+                isEndcAvailable, vopsSupportInfo);
         updateNrState();
     }
 
diff --git a/telephony/java/android/telephony/NrVopsSupportInfo.aidl b/telephony/java/android/telephony/NrVopsSupportInfo.aidl
new file mode 100644
index 0000000..460a589
--- /dev/null
+++ b/telephony/java/android/telephony/NrVopsSupportInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+parcelable NrVopsSupportInfo;
diff --git a/telephony/java/android/telephony/NrVopsSupportInfo.java b/telephony/java/android/telephony/NrVopsSupportInfo.java
new file mode 100644
index 0000000..155ee38
--- /dev/null
+++ b/telephony/java/android/telephony/NrVopsSupportInfo.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Class stores information related to NR network VoPS support
+ * @hide
+ */
+@SystemApi
+public final class NrVopsSupportInfo extends VopsSupportInfo {
+
+    /**
+     * Indicates network does not support vops
+     */
+    public static final int NR_STATUS_VOPS_NOT_SUPPORTED = 0;
+
+    /**
+     * Indicates network supports vops over 3gpp access.
+     */
+    public static final int NR_STATUS_VOPS_3GPP_SUPPORTED = 1;
+
+    /**
+     * Indicates network supports vops over non 3gpp access
+     */
+    public static final int NR_STATUS_VOPS_NON_3GPP_SUPPORTED = 2;
+
+    /**@hide*/
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+        prefix = {"NR_STATUS_VOPS_"},
+        value = {
+            NR_STATUS_VOPS_NOT_SUPPORTED,
+            NR_STATUS_VOPS_3GPP_SUPPORTED,
+            NR_STATUS_VOPS_NON_3GPP_SUPPORTED
+        })
+    public @interface NrVopsStatus {}
+
+    /**
+     * Indicates network does not support emergency service
+     */
+    public static final int NR_STATUS_EMC_NOT_SUPPORTED = 0;
+
+    /**
+     * Indicates network supports emergency service in NR connected to 5GCN only
+     */
+    public static final int NR_STATUS_EMC_5GCN_ONLY = 1;
+
+    /**
+     * Indicates network supports emergency service in E-UTRA connected to 5GCN only
+     */
+    public static final int NR_STATUS_EMC_EUTRA_5GCN_ONLY = 2;
+
+    /**
+     * Indicates network supports emergency service in NR connected to 5GCN and
+     * E-UTRA connected to 5GCN
+     */
+    public static final int NR_STATUS_EMC_NR_EUTRA_5GCN = 3;
+
+    /**@hide*/
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+        prefix = {"NR_STATUS_EMC_"},
+        value = {
+            NR_STATUS_EMC_NOT_SUPPORTED,
+            NR_STATUS_EMC_5GCN_ONLY,
+            NR_STATUS_EMC_EUTRA_5GCN_ONLY,
+            NR_STATUS_EMC_NR_EUTRA_5GCN
+        })
+    public @interface NrEmcStatus {}
+
+    /**
+     * Indicates network does not support emergency service
+     */
+    public static final int NR_STATUS_EMF_NOT_SUPPORTED = 0;
+
+    /**
+     * Indicates network supports emergency service fallback in NR connected to 5GCN only
+     */
+    public static final int NR_STATUS_EMF_5GCN_ONLY = 1;
+
+    /**
+     * Indicates network supports emergency service fallback in E-UTRA connected to 5GCN only
+     */
+    public static final int NR_STATUS_EMF_EUTRA_5GCN_ONLY = 2;
+
+    /**
+     * Indicates network supports emergency service fallback in NR connected to 5GCN
+     * and E-UTRA connected to 5GCN
+     */
+    public static final int NR_STATUS_EMF_NR_EUTRA_5GCN = 3;
+
+    /**@hide*/
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+        prefix = {"NR_STATUS_EMF_"},
+        value = {
+            NR_STATUS_EMF_NOT_SUPPORTED,
+            NR_STATUS_EMF_5GCN_ONLY,
+            NR_STATUS_EMF_EUTRA_5GCN_ONLY,
+            NR_STATUS_EMF_NR_EUTRA_5GCN
+        })
+    public @interface NrEmfStatus {}
+
+    @NrVopsStatus
+    private final int mVopsSupport;
+    @NrEmcStatus
+    private final int mEmcSupport;
+    @NrEmfStatus
+    private final int mEmfSupport;
+
+    public NrVopsSupportInfo(@NrVopsStatus int vops, @NrEmcStatus int emc, @NrEmcStatus int emf) {
+        mVopsSupport = vops;
+        mEmcSupport = emc;
+        mEmfSupport = emf;
+    }
+
+    /**
+     * Provides the NR VoPS support capability as described in:
+     * 3GPP 24.501 EPS network feature support -> IMS VoPS
+     */
+    public @NrVopsStatus int getVopsSupport() {
+        return mVopsSupport;
+    }
+
+    /**
+     * Provides the NR Emergency bearer support capability as described in:
+     * 3GPP 24.501 EPS network feature support -> EMC, and
+     * 38.331 SIB1 : ims-EmergencySupport
+     */
+    public @NrEmcStatus int getEmcSupport() {
+        return mEmcSupport;
+    }
+
+    /**
+     * Provides the NR emergency service fallback support capability as
+     * described in 3GPP 24.501 EPS network feature support -> EMF
+     */
+    public @NrEmfStatus int getEmfSupport() {
+        return mEmfSupport;
+    }
+
+    /**
+     * Returns whether VoPS is supported by the network
+     */
+    @Override
+    public boolean isVopsSupported() {
+        return mVopsSupport != NR_STATUS_VOPS_NOT_SUPPORTED;
+    }
+
+    /**
+     * Returns whether emergency service is supported by the network
+     */
+    @Override
+    public boolean isEmergencyServiceSupported() {
+        return mEmcSupport != NR_STATUS_EMC_NOT_SUPPORTED;
+    }
+
+    /**
+     * Returns whether emergency service fallback is supported by the network
+     */
+    public boolean isEmergencyServiceFallbackSupported() {
+        return mEmfSupport != NR_STATUS_EMF_NOT_SUPPORTED;
+    }
+
+    /**
+     * Implement the Parcelable interface
+     */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        super.writeToParcel(out, flags, AccessNetworkType.NGRAN);
+        out.writeInt(mVopsSupport);
+        out.writeInt(mEmcSupport);
+        out.writeInt(mEmfSupport);
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (o == null || !(o instanceof NrVopsSupportInfo)) {
+            return false;
+        }
+        if (this == o) return true;
+        NrVopsSupportInfo other = (NrVopsSupportInfo) o;
+        return mVopsSupport == other.mVopsSupport
+            && mEmcSupport == other.mEmcSupport
+            && mEmfSupport == other.mEmfSupport;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mVopsSupport, mEmcSupport, mEmfSupport);
+    }
+
+    /**
+     * @return string representation.
+     */
+    @NonNull
+    @Override
+    public String toString() {
+        return ("NrVopsSupportInfo : "
+                + " mVopsSupport = " + mVopsSupport
+                + " mEmcSupport = " + mEmcSupport
+                + " mEmfSupport = " + mEmfSupport);
+    }
+
+    public static final @android.annotation.NonNull Creator<NrVopsSupportInfo> CREATOR =
+            new Creator<NrVopsSupportInfo>() {
+        @Override
+        public NrVopsSupportInfo createFromParcel(Parcel in) {
+            // Skip the type info.
+            in.readInt();
+            return new NrVopsSupportInfo(in);
+        }
+
+        @Override
+        public NrVopsSupportInfo[] newArray(int size) {
+            return new NrVopsSupportInfo[size];
+        }
+    };
+
+    /** @hide */
+    protected static NrVopsSupportInfo createFromParcelBody(Parcel in) {
+        return new NrVopsSupportInfo(in);
+    }
+
+    private NrVopsSupportInfo(Parcel in) {
+        mVopsSupport = in.readInt();
+        mEmcSupport = in.readInt();
+        mEmfSupport = in.readInt();
+    }
+}
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index b958bff..ce5a8cc 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -2127,7 +2127,7 @@
                 ret = iccISms.getSmsCapacityOnIccForSubscriber(getSubscriptionId());
             }
         } catch (RemoteException ex) {
-            throw new RuntimeException(ex);
+            Log.e(TAG, "getSmsCapacityOnIcc() RemoteException", ex);
         }
         return ret;
     }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 99b5687..bae032c 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -129,6 +129,8 @@
 import java.util.UUID;
 import java.util.concurrent.Executor;
 import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
 /**
  * Provides access to information about the telephony services on
@@ -3116,6 +3118,10 @@
                 return NETWORK_TYPE_BITMASK_LTE_CA;
             case NETWORK_TYPE_NR:
                 return NETWORK_TYPE_BITMASK_NR;
+            case NETWORK_TYPE_IWLAN:
+                return NETWORK_TYPE_BITMASK_IWLAN;
+            case NETWORK_TYPE_IDEN:
+                return (1 << (NETWORK_TYPE_IDEN - 1));
             default:
                 return NETWORK_TYPE_BITMASK_UNKNOWN;
         }
@@ -8224,7 +8230,8 @@
     @IntDef({
             ALLOWED_NETWORK_TYPES_REASON_USER,
             ALLOWED_NETWORK_TYPES_REASON_POWER,
-            ALLOWED_NETWORK_TYPES_REASON_CARRIER
+            ALLOWED_NETWORK_TYPES_REASON_CARRIER,
+            ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface AllowedNetworkTypesReason {
@@ -8261,21 +8268,36 @@
     public static final int ALLOWED_NETWORK_TYPES_REASON_CARRIER = 2;
 
     /**
-     * Set the allowed network types of the device and
-     * provide the reason triggering the allowed network change.
+     * To indicate allowed network type change is requested by the user via the 2G toggle.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G = 3;
+
+    /**
+     * Set the allowed network types of the device and provide the reason triggering the allowed
+     * network change.
      * This can be called for following reasons
      * <ol>
      * <li>Allowed network types control by USER {@link #ALLOWED_NETWORK_TYPES_REASON_USER}
      * <li>Allowed network types control by power manager
      * {@link #ALLOWED_NETWORK_TYPES_REASON_POWER}
      * <li>Allowed network types control by carrier {@link #ALLOWED_NETWORK_TYPES_REASON_CARRIER}
+     * <li>Allowed network types control by the user-controlled "Allow 2G" toggle
+     * {@link #ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G}
      * </ol>
      * This API will result in allowing an intersection of allowed network types for all reasons,
      * including the configuration done through other reasons.
+     *
+     * The functionality of this API with the parameter
+     * {@link #ALLOWED_NETWORK_TYPES_REASON_CARRIER} is the same as the API
+     * {@link TelephonyManager#setAllowedNetworkTypes}. Use this API instead of
+     * {@link TelephonyManager#setAllowedNetworkTypes}.
      * <p>
      * If {@link android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported}
      * ({@link TelephonyManager#CAPABILITY_ALLOWED_NETWORK_TYPES_USED}) returns true, then
-     * setAllowedNetworkTypesBitmap is used on the radio interface.  Otherwise,
+     * setAllowedNetworkTypesBitmap is used on the radio interface. Otherwise,
      * setPreferredNetworkTypesBitmap is used instead.
      *
      * @param reason the reason the allowed network type change is taking place
@@ -8315,21 +8337,17 @@
      * {@link #getAllowedNetworkTypesForReason} returns allowed network type for a
      * specific reason.
      *
-     * <p>Requires Permission:
-     * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE READ_PRIVILEGED_PHONE_STATE}
-     * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
-     *
      * @param reason the reason the allowed network type change is taking place
      * @return the allowed network type bitmask
      * @throws IllegalStateException    if the Telephony process is not currently available.
      * @throws IllegalArgumentException if invalid AllowedNetworkTypesReason is passed.
      * @hide
      */
-    @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     @RequiresFeature(
             enforcement = "android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported",
             value = TelephonyManager.CAPABILITY_ALLOWED_NETWORK_TYPES_USED)
+    @SystemApi
     public @NetworkTypeBitMask long getAllowedNetworkTypesForReason(
             @AllowedNetworkTypesReason int reason) {
         if (!isValidAllowedNetworkTypesReason(reason)) {
@@ -8358,6 +8376,7 @@
             case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER:
             case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_POWER:
             case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_CARRIER:
+            case TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G:
                 return true;
         }
         return false;
@@ -8373,6 +8392,25 @@
     }
 
     /**
+     * Returns a string representation of the allowed network types{@link NetworkTypeBitMask}.
+     *
+     * @param networkTypeBitmask The bitmask of allowed network types.
+     * @return the name of the allowed network types
+     * @hide
+     */
+    public static String convertNetworkTypeBitmaskToString(
+            @NetworkTypeBitMask long networkTypeBitmask) {
+        String networkTypeName = IntStream.rangeClosed(NETWORK_TYPE_GPRS, NETWORK_TYPE_NR)
+                .filter(x -> {
+                    return (networkTypeBitmask & getBitMaskForNetworkType(x))
+                            == getBitMaskForNetworkType(x);
+                })
+                .mapToObj(x -> getNetworkTypeName(x))
+                .collect(Collectors.joining("|"));
+        return TextUtils.isEmpty(networkTypeName) ? "UNKNOWN" : networkTypeName;
+    }
+
+    /**
      * Set the preferred network type to global mode which includes LTE, CDMA, EvDo and GSM/WCDMA.
      *
      * <p>Requires that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
@@ -11859,12 +11897,6 @@
      * "Data capable" means that this device supports packet-switched
      * data connections over the telephony network.
      * <p>
-     * Note: the meaning of this flag is subtly different from the
-     * PackageManager.FEATURE_TELEPHONY system feature, which is available
-     * on any device with a telephony radio, even if the device is
-     * voice-only.
-     *
-     * @hide
      */
     public boolean isDataCapable() {
         if (mContext == null) return true;
@@ -12079,6 +12111,7 @@
                     NETWORK_TYPE_BITMASK_LTE,
                     NETWORK_TYPE_BITMASK_LTE_CA,
                     NETWORK_TYPE_BITMASK_NR,
+                    NETWORK_TYPE_BITMASK_IWLAN
             })
     public @interface NetworkTypeBitMask {}
 
@@ -14401,12 +14434,23 @@
     public static final String CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE =
             "CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE";
 
+    /**
+     * Indicates whether a data throttling request sent with {@link #sendThermalMitigationRequest}
+     * is supported. See comments on {@link #sendThermalMitigationRequest} for more information.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING =
+            "CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING";
+
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @StringDef(prefix = "CAPABILITY_", value = {
             CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE,
             CAPABILITY_ALLOWED_NETWORK_TYPES_USED,
-            CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE
+            CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE,
+            CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING,
     })
     public @interface RadioInterfaceCapability {}
 
@@ -14516,11 +14560,24 @@
      * and can be used at any time during data throttling to hold onto the current level of data
      * throttling.
      *
+     * <p> If {@link android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported}({@link
+     * #CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING}) returns false, then sending a {@link
+     * DataThrottlingRequest#DATA_THROTTLING_ACTION_HOLD}, {@link
+     * DataThrottlingRequest#DATA_THROTTLING_ACTION_THROTTLE_SECONDARY_CARRIER}, or {@link
+     * DataThrottlingRequest#DATA_THROTTLING_ACTION_THROTTLE_PRIMARY_CARRIER} will result in {@link
+     * IllegalArgumentException} being thrown. However, on devices that do not
+     * support data throttling, {@link
+     * DataThrottlingRequest#DATA_THROTTLING_ACTION_NO_DATA_THROTTLING} can still be requested in
+     * order to undo the mitigations above it (i.e {@link
+     * ThermalMitigationRequest#THERMAL_MITIGATION_ACTION_VOICE_ONLY} and/or {@link
+     * ThermalMitigationRequest#THERMAL_MITIGATION_ACTION_RADIO_OFF}).
+     *
      * @param thermalMitigationRequest Thermal mitigation request. See {@link
      * ThermalMitigationRequest} for details.
      *
      * @throws IllegalStateException if the Telephony process is not currently available.
-     * @throws IllegalArgumentException if the thermalMitigationRequest had invalid parameters.
+     * @throws IllegalArgumentException if the thermalMitigationRequest had invalid parameters or
+     * if the device's modem does not support data throttling.
      *
      * @hide
      */
@@ -14574,6 +14631,11 @@
      */
     public void registerTelephonyCallback(@NonNull @CallbackExecutor Executor executor,
             @NonNull TelephonyCallback callback) {
+
+        if (mContext == null) {
+            throw new IllegalStateException("telephony service is null.");
+        }
+
         if (executor == null || callback == null) {
             throw new IllegalArgumentException("TelephonyCallback and executor must be non-null");
         }
diff --git a/telephony/java/android/telephony/VopsSupportInfo.aidl b/telephony/java/android/telephony/VopsSupportInfo.aidl
new file mode 100644
index 0000000..31c608f
--- /dev/null
+++ b/telephony/java/android/telephony/VopsSupportInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+parcelable VopsSupportInfo;
diff --git a/telephony/java/android/telephony/VopsSupportInfo.java b/telephony/java/android/telephony/VopsSupportInfo.java
new file mode 100644
index 0000000..f89bfa9
--- /dev/null
+++ b/telephony/java/android/telephony/VopsSupportInfo.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.annotation.NonNull;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
+
+/**
+ * Abstract base class for the information related to network VoPS support.
+ * This is the base class for XxVopsSupportInfo which represent VoPS support
+ * information for specific network access techonology.
+ * @hide
+ */
+@SuppressLint("ParcelNotFinal")
+@SystemApi
+public abstract class VopsSupportInfo implements Parcelable {
+
+    /**
+     * @hide
+     */
+    public VopsSupportInfo() {}
+
+    /**
+     * Returns whether VoPS is supported by the network
+     */
+    public abstract boolean isVopsSupported();
+
+    /**
+     * Returns whether emergency service is supported by the network
+     */
+    public abstract boolean isEmergencyServiceSupported();
+
+    /**
+     * Returns whether emergency service fallback is supported by the network
+     */
+    public abstract boolean isEmergencyServiceFallbackSupported();
+
+    /**
+     * Implement the Parcelable interface
+     */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /** Implement the Parcelable interface */
+    @Override
+    public abstract void writeToParcel(@NonNull Parcel dest, int flags);
+
+    /**
+     * Used by child classes for parceling.
+     *
+     * @hide
+     */
+    protected void writeToParcel(@NonNull Parcel dest, int flags, int type) {
+        dest.writeInt(type);
+    }
+
+    /** Implement the Parcelable interface */
+    public static final @android.annotation.NonNull Creator<VopsSupportInfo> CREATOR =
+            new Creator<VopsSupportInfo>() {
+        @Override
+        public VopsSupportInfo createFromParcel(Parcel in) {
+                int type = in.readInt();
+                switch (type) {
+                    case AccessNetworkType.EUTRAN:
+                        return LteVopsSupportInfo.createFromParcelBody(in);
+                    case AccessNetworkType.NGRAN:
+                        return NrVopsSupportInfo.createFromParcelBody(in);
+                    default: throw new RuntimeException("Bad VopsSupportInfo Parcel");
+                }
+        }
+
+        @Override
+        public VopsSupportInfo[] newArray(int size) {
+            return new VopsSupportInfo[size];
+        }
+    };
+
+    @Override
+    public abstract int hashCode();
+
+    @Override
+    public abstract boolean equals(Object o);
+}
diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
index 0dfec75..d40b88c 100644
--- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
@@ -35,6 +35,9 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
+import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION;
+import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS;
+import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
 import static android.net.NetworkCapabilities.RESTRICTED_CAPABILITIES;
 import static android.net.NetworkCapabilities.SIGNAL_STRENGTH_UNSPECIFIED;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
@@ -51,7 +54,6 @@
 import static com.android.testutils.MiscAsserts.assertThrows;
 import static com.android.testutils.ParcelUtils.assertParcelSane;
 import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
-import static com.android.testutils.ParcelUtils.parcelingRoundTrip;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
@@ -62,13 +64,13 @@
 import static org.junit.Assert.fail;
 import static org.junit.Assume.assumeTrue;
 
-import android.net.wifi.WifiInfo;
 import android.net.wifi.aware.DiscoverySession;
 import android.net.wifi.aware.PeerHandle;
 import android.net.wifi.aware.WifiAwareNetworkSpecifier;
 import android.os.Build;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.ArraySet;
+import android.util.Range;
 
 import androidx.test.runner.AndroidJUnit4;
 
@@ -240,72 +242,93 @@
     @Test
     public void testSetUids() {
         final NetworkCapabilities netCap = new NetworkCapabilities();
-        final Set<UidRange> uids = new ArraySet<>();
-        uids.add(new UidRange(50, 100));
-        uids.add(new UidRange(3000, 4000));
-        netCap.setUids(uids);
-        assertTrue(netCap.appliesToUid(50));
-        assertTrue(netCap.appliesToUid(80));
-        assertTrue(netCap.appliesToUid(100));
+        // Null uids match all UIDs
+        netCap.setUids(null);
+        assertTrue(netCap.appliesToUid(10));
+        assertTrue(netCap.appliesToUid(200));
         assertTrue(netCap.appliesToUid(3000));
-        assertTrue(netCap.appliesToUid(3001));
-        assertFalse(netCap.appliesToUid(10));
-        assertFalse(netCap.appliesToUid(25));
-        assertFalse(netCap.appliesToUid(49));
-        assertFalse(netCap.appliesToUid(101));
-        assertFalse(netCap.appliesToUid(2000));
-        assertFalse(netCap.appliesToUid(100000));
-
+        assertTrue(netCap.appliesToUid(10010));
         assertTrue(netCap.appliesToUidRange(new UidRange(50, 100)));
         assertTrue(netCap.appliesToUidRange(new UidRange(70, 72)));
         assertTrue(netCap.appliesToUidRange(new UidRange(3500, 3912)));
-        assertFalse(netCap.appliesToUidRange(new UidRange(1, 100)));
-        assertFalse(netCap.appliesToUidRange(new UidRange(49, 100)));
-        assertFalse(netCap.appliesToUidRange(new UidRange(1, 10)));
-        assertFalse(netCap.appliesToUidRange(new UidRange(60, 101)));
-        assertFalse(netCap.appliesToUidRange(new UidRange(60, 3400)));
-
-        NetworkCapabilities netCap2 = new NetworkCapabilities();
-        // A new netcap object has null UIDs, so anything will satisfy it.
-        assertTrue(netCap2.satisfiedByUids(netCap));
-        // Still not equal though.
-        assertFalse(netCap2.equalsUids(netCap));
-        netCap2.setUids(uids);
-        assertTrue(netCap2.satisfiedByUids(netCap));
-        assertTrue(netCap.equalsUids(netCap2));
-        assertTrue(netCap2.equalsUids(netCap));
-
-        uids.add(new UidRange(600, 700));
-        netCap2.setUids(uids);
-        assertFalse(netCap2.satisfiedByUids(netCap));
-        assertFalse(netCap.appliesToUid(650));
-        assertTrue(netCap2.appliesToUid(650));
-        netCap.combineCapabilities(netCap2);
-        assertTrue(netCap2.satisfiedByUids(netCap));
-        assertTrue(netCap.appliesToUid(650));
-        assertFalse(netCap.appliesToUid(500));
-
-        assertTrue(new NetworkCapabilities().satisfiedByUids(netCap));
-        netCap.combineCapabilities(new NetworkCapabilities());
-        assertTrue(netCap.appliesToUid(500));
         assertTrue(netCap.appliesToUidRange(new UidRange(1, 100000)));
-        assertFalse(netCap2.appliesToUid(500));
-        assertFalse(netCap2.appliesToUidRange(new UidRange(1, 100000)));
-        assertTrue(new NetworkCapabilities().satisfiedByUids(netCap));
+
+        if (isAtLeastS()) {
+            final Set<Range<Integer>> uids = new ArraySet<>();
+            uids.add(uidRange(50, 100));
+            uids.add(uidRange(3000, 4000));
+            netCap.setUids(uids);
+            assertTrue(netCap.appliesToUid(50));
+            assertTrue(netCap.appliesToUid(80));
+            assertTrue(netCap.appliesToUid(100));
+            assertTrue(netCap.appliesToUid(3000));
+            assertTrue(netCap.appliesToUid(3001));
+            assertFalse(netCap.appliesToUid(10));
+            assertFalse(netCap.appliesToUid(25));
+            assertFalse(netCap.appliesToUid(49));
+            assertFalse(netCap.appliesToUid(101));
+            assertFalse(netCap.appliesToUid(2000));
+            assertFalse(netCap.appliesToUid(100000));
+
+            assertTrue(netCap.appliesToUidRange(new UidRange(50, 100)));
+            assertTrue(netCap.appliesToUidRange(new UidRange(70, 72)));
+            assertTrue(netCap.appliesToUidRange(new UidRange(3500, 3912)));
+            assertFalse(netCap.appliesToUidRange(new UidRange(1, 100)));
+            assertFalse(netCap.appliesToUidRange(new UidRange(49, 100)));
+            assertFalse(netCap.appliesToUidRange(new UidRange(1, 10)));
+            assertFalse(netCap.appliesToUidRange(new UidRange(60, 101)));
+            assertFalse(netCap.appliesToUidRange(new UidRange(60, 3400)));
+
+            NetworkCapabilities netCap2 = new NetworkCapabilities();
+            // A new netcap object has null UIDs, so anything will satisfy it.
+            assertTrue(netCap2.satisfiedByUids(netCap));
+            // Still not equal though.
+            assertFalse(netCap2.equalsUids(netCap));
+            netCap2.setUids(uids);
+            assertTrue(netCap2.satisfiedByUids(netCap));
+            assertTrue(netCap.equalsUids(netCap2));
+            assertTrue(netCap2.equalsUids(netCap));
+
+            uids.add(uidRange(600, 700));
+            netCap2.setUids(uids);
+            assertFalse(netCap2.satisfiedByUids(netCap));
+            assertFalse(netCap.appliesToUid(650));
+            assertTrue(netCap2.appliesToUid(650));
+            netCap.combineCapabilities(netCap2);
+            assertTrue(netCap2.satisfiedByUids(netCap));
+            assertTrue(netCap.appliesToUid(650));
+            assertFalse(netCap.appliesToUid(500));
+
+            assertTrue(new NetworkCapabilities().satisfiedByUids(netCap));
+            netCap.combineCapabilities(new NetworkCapabilities());
+            assertTrue(netCap.appliesToUid(500));
+            assertTrue(netCap.appliesToUidRange(new UidRange(1, 100000)));
+            assertFalse(netCap2.appliesToUid(500));
+            assertFalse(netCap2.appliesToUidRange(new UidRange(1, 100000)));
+            assertTrue(new NetworkCapabilities().satisfiedByUids(netCap));
+
+            // Null uids satisfies everything.
+            netCap.setUids(null);
+            assertTrue(netCap2.satisfiedByUids(netCap));
+            assertTrue(netCap.satisfiedByUids(netCap2));
+            netCap2.setUids(null);
+            assertTrue(netCap2.satisfiedByUids(netCap));
+            assertTrue(netCap.satisfiedByUids(netCap2));
+        }
     }
 
     @Test
     public void testParcelNetworkCapabilities() {
-        final Set<UidRange> uids = new ArraySet<>();
-        uids.add(new UidRange(50, 100));
-        uids.add(new UidRange(3000, 4000));
+        final Set<Range<Integer>> uids = new ArraySet<>();
+        uids.add(uidRange(50, 100));
+        uids.add(uidRange(3000, 4000));
         final NetworkCapabilities netCap = new NetworkCapabilities()
             .addCapability(NET_CAPABILITY_INTERNET)
-            .setUids(uids)
             .addCapability(NET_CAPABILITY_EIMS)
             .addCapability(NET_CAPABILITY_NOT_METERED);
         if (isAtLeastS()) {
             netCap.setSubIds(Set.of(TEST_SUBID1, TEST_SUBID2));
+            netCap.setUids(uids);
         } else if (isAtLeastR()) {
             netCap.setOwnerUid(123);
             netCap.setAdministratorUids(new int[] {5, 11});
@@ -330,55 +353,6 @@
         testParcelSane(netCap);
     }
 
-    private NetworkCapabilities createNetworkCapabilitiesWithWifiInfo() {
-        // uses a real WifiInfo to test parceling of sensitive data.
-        final WifiInfo wifiInfo = new WifiInfo.Builder()
-                .setSsid("sssid1234".getBytes())
-                .setBssid("00:11:22:33:44:55")
-                .build();
-        return new NetworkCapabilities()
-                .addCapability(NET_CAPABILITY_INTERNET)
-                .addCapability(NET_CAPABILITY_EIMS)
-                .addCapability(NET_CAPABILITY_NOT_METERED)
-                .setSSID(TEST_SSID)
-                .setTransportInfo(wifiInfo)
-                .setRequestorPackageName("com.android.test")
-                .setRequestorUid(9304);
-    }
-
-    @Test
-    public void testParcelNetworkCapabilitiesWithLocationSensitiveFields() {
-        assumeTrue(isAtLeastS());
-
-        final NetworkCapabilities netCap = createNetworkCapabilitiesWithWifiInfo();
-        final NetworkCapabilities netCapWithLocationSensitiveFields =
-                new NetworkCapabilities(netCap, true);
-
-        assertParcelingIsLossless(netCapWithLocationSensitiveFields);
-        testParcelSane(netCapWithLocationSensitiveFields);
-
-        assertEquals(netCapWithLocationSensitiveFields,
-                parcelingRoundTrip(netCapWithLocationSensitiveFields));
-    }
-
-    @Test
-    public void testParcelNetworkCapabilitiesWithoutLocationSensitiveFields() {
-        assumeTrue(isAtLeastS());
-
-        final NetworkCapabilities netCap = createNetworkCapabilitiesWithWifiInfo();
-        final NetworkCapabilities netCapWithoutLocationSensitiveFields =
-                new NetworkCapabilities(netCap, false);
-
-        final NetworkCapabilities sanitizedNetCap =
-                new NetworkCapabilities(netCapWithoutLocationSensitiveFields);
-        final WifiInfo sanitizedWifiInfo = new WifiInfo.Builder()
-                .setSsid(new byte[0])
-                .setBssid(WifiInfo.DEFAULT_MAC_ADDRESS)
-                .build();
-        sanitizedNetCap.setTransportInfo(sanitizedWifiInfo);
-        assertEquals(sanitizedNetCap, parcelingRoundTrip(netCapWithoutLocationSensitiveFields));
-    }
-
     private void testParcelSane(NetworkCapabilities cap) {
         if (isAtLeastS()) {
             assertParcelSane(cap, 17);
@@ -389,6 +363,45 @@
         }
     }
 
+    private static NetworkCapabilities createNetworkCapabilitiesWithTransportInfo() {
+        return new NetworkCapabilities()
+                .addCapability(NET_CAPABILITY_INTERNET)
+                .addCapability(NET_CAPABILITY_EIMS)
+                .addCapability(NET_CAPABILITY_NOT_METERED)
+                .setSSID(TEST_SSID)
+                .setTransportInfo(new TestTransportInfo())
+                .setRequestorPackageName("com.android.test")
+                .setRequestorUid(9304);
+    }
+
+    @Test
+    public void testNetworkCapabilitiesCopyWithNoRedactions() {
+        assumeTrue(isAtLeastS());
+
+        final NetworkCapabilities netCap = createNetworkCapabilitiesWithTransportInfo();
+        final NetworkCapabilities netCapWithNoRedactions =
+                new NetworkCapabilities(netCap, NetworkCapabilities.REDACT_NONE);
+        TestTransportInfo testTransportInfo =
+                (TestTransportInfo) netCapWithNoRedactions.getTransportInfo();
+        assertFalse(testTransportInfo.locationRedacted);
+        assertFalse(testTransportInfo.localMacAddressRedacted);
+        assertFalse(testTransportInfo.settingsRedacted);
+    }
+
+    @Test
+    public void testNetworkCapabilitiesCopyWithoutLocationSensitiveFields() {
+        assumeTrue(isAtLeastS());
+
+        final NetworkCapabilities netCap = createNetworkCapabilitiesWithTransportInfo();
+        final NetworkCapabilities netCapWithNoRedactions =
+                new NetworkCapabilities(netCap, REDACT_FOR_ACCESS_FINE_LOCATION);
+        TestTransportInfo testTransportInfo =
+                (TestTransportInfo) netCapWithNoRedactions.getTransportInfo();
+        assertTrue(testTransportInfo.locationRedacted);
+        assertFalse(testTransportInfo.localMacAddressRedacted);
+        assertFalse(testTransportInfo.settingsRedacted);
+    }
+
     @Test
     public void testOemPaid() {
         NetworkCapabilities nc = new NetworkCapabilities();
@@ -540,12 +553,16 @@
         assertFalse(nc1.satisfiedByNetworkCapabilities(nc2));
     }
 
-    private ArraySet<UidRange> uidRange(int from, int to) {
-        final ArraySet<UidRange> range = new ArraySet<>(1);
-        range.add(new UidRange(from, to));
+    private ArraySet<Range<Integer>> uidRanges(int from, int to) {
+        final ArraySet<Range<Integer>> range = new ArraySet<>(1);
+        range.add(uidRange(from, to));
         return range;
     }
 
+    private Range<Integer> uidRange(int from, int to) {
+        return new Range<Integer>(from, to);
+    }
+
     @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
     public void testSetAdministratorUids() {
         NetworkCapabilities nc =
@@ -601,23 +618,23 @@
         } catch (IllegalStateException expected) {}
         nc1.setSSID(TEST_SSID);
 
-        nc1.setUids(uidRange(10, 13));
-        assertNotEquals(nc1, nc2);
-        nc2.combineCapabilities(nc1);  // Everything + 10~13 is still everything.
-        assertNotEquals(nc1, nc2);
-        nc1.combineCapabilities(nc2);  // 10~13 + everything is everything.
-        assertEquals(nc1, nc2);
-        nc1.setUids(uidRange(10, 13));
-        nc2.setUids(uidRange(20, 23));
-        assertNotEquals(nc1, nc2);
-        nc1.combineCapabilities(nc2);
-        assertTrue(nc1.appliesToUid(12));
-        assertFalse(nc2.appliesToUid(12));
-        assertTrue(nc1.appliesToUid(22));
-        assertTrue(nc2.appliesToUid(22));
-
-        // Verify the subscription id list can be combined only when they are equal.
         if (isAtLeastS()) {
+            nc1.setUids(uidRanges(10, 13));
+            assertNotEquals(nc1, nc2);
+            nc2.combineCapabilities(nc1);  // Everything + 10~13 is still everything.
+            assertNotEquals(nc1, nc2);
+            nc1.combineCapabilities(nc2);  // 10~13 + everything is everything.
+            assertEquals(nc1, nc2);
+            nc1.setUids(uidRanges(10, 13));
+            nc2.setUids(uidRanges(20, 23));
+            assertNotEquals(nc1, nc2);
+            nc1.combineCapabilities(nc2);
+            assertTrue(nc1.appliesToUid(12));
+            assertFalse(nc2.appliesToUid(12));
+            assertTrue(nc1.appliesToUid(22));
+            assertTrue(nc2.appliesToUid(22));
+
+            // Verify the subscription id list can be combined only when they are equal.
             nc1.setSubIds(Set.of(TEST_SUBID1, TEST_SUBID2));
             nc2.setSubIds(Set.of(TEST_SUBID2));
             assertThrows(IllegalStateException.class, () -> nc2.combineCapabilities(nc1));
@@ -773,8 +790,11 @@
         if (isAtLeastR()) {
             assertTrue(DIFFERENT_TEST_SSID.equals(nc2.getSsid()));
         }
-
-        nc1.setUids(uidRange(10, 13));
+        if (isAtLeastS()) {
+            nc1.setUids(uidRanges(10, 13));
+        } else {
+            nc1.setUids(null);
+        }
         nc2.set(nc1);  // Overwrites, as opposed to combineCapabilities
         assertEquals(nc1, nc2);
 
@@ -1033,18 +1053,42 @@
         } catch (IllegalArgumentException e) { }
     }
 
-    private class TestTransportInfo implements TransportInfo {
+    /**
+     * Test TransportInfo to verify redaction mechanism.
+     */
+    private static class TestTransportInfo implements TransportInfo {
+        public final boolean locationRedacted;
+        public final boolean localMacAddressRedacted;
+        public final boolean settingsRedacted;
+
         TestTransportInfo() {
+            locationRedacted = false;
+            localMacAddressRedacted = false;
+            settingsRedacted = false;
+        }
+
+        TestTransportInfo(boolean locationRedacted,
+                boolean localMacAddressRedacted,
+                boolean settingsRedacted) {
+            this.locationRedacted = locationRedacted;
+            this.localMacAddressRedacted =
+                    localMacAddressRedacted;
+            this.settingsRedacted = settingsRedacted;
         }
 
         @Override
-        public TransportInfo makeCopy(boolean parcelLocationSensitiveFields) {
-            return this;
+        public TransportInfo makeCopy(@NetworkCapabilities.RedactionType long redactions) {
+            return new TestTransportInfo(
+                    (redactions & NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION) != 0,
+                    (redactions & REDACT_FOR_LOCAL_MAC_ADDRESS) != 0,
+                    (redactions & REDACT_FOR_NETWORK_SETTINGS) != 0
+            );
         }
 
         @Override
-        public boolean hasLocationSensitiveFields() {
-            return false;
+        public @NetworkCapabilities.RedactionType long getApplicableRedactions() {
+            return REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS
+                    | REDACT_FOR_NETWORK_SETTINGS;
         }
     }
 
@@ -1055,7 +1099,7 @@
         final int requestUid = 10100;
         final int[] administratorUids = {ownerUid, 10001};
         final TelephonyNetworkSpecifier specifier = new TelephonyNetworkSpecifier(1);
-        final TestTransportInfo transportInfo = new TestTransportInfo();
+        final TransportInfo transportInfo = new TransportInfo() {};
         final String ssid = "TEST_SSID";
         final String packageName = "com.google.test.networkcapabilities";
         final NetworkCapabilities nc = new NetworkCapabilities.Builder()
diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
index 2a2dc56..db49e0b 100644
--- a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
+++ b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
@@ -44,12 +44,10 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.platform.app.InstrumentationRegistry
 import com.android.server.ConnectivityService
-import com.android.server.LocalServices
 import com.android.server.NetworkAgentWrapper
 import com.android.server.TestNetIdManager
 import com.android.server.connectivity.MockableSystemProperties
 import com.android.server.connectivity.ProxyTracker
-import com.android.server.net.NetworkPolicyManagerInternal
 import com.android.testutils.TestableNetworkCallback
 import org.junit.After
 import org.junit.Before
@@ -162,10 +160,6 @@
         networkStackClient.init()
         networkStackClient.start()
 
-        LocalServices.removeServiceForTest(NetworkPolicyManagerInternal::class.java)
-        LocalServices.addService(NetworkPolicyManagerInternal::class.java,
-                mock(NetworkPolicyManagerInternal::class.java))
-
         service = TestConnectivityService(makeDependencies())
         cm = ConnectivityManager(context, service)
         context.addMockSystemService(Context.CONNECTIVITY_SERVICE, cm)
diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
index 01d8186..e2d43cb 100644
--- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
+++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
@@ -44,11 +44,11 @@
 import android.net.NetworkSpecifier;
 import android.net.QosFilter;
 import android.net.SocketKeepalive;
-import android.net.UidRange;
 import android.os.ConditionVariable;
 import android.os.HandlerThread;
 import android.os.Message;
 import android.util.Log;
+import android.util.Range;
 
 import com.android.net.module.util.ArrayTrackRecord;
 import com.android.server.connectivity.ConnectivityConstants;
@@ -222,7 +222,7 @@
         mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
     }
 
-    public void setUids(Set<UidRange> uids) {
+    public void setUids(Set<Range<Integer>> uids) {
         mNetworkCapabilities.setUids(uids);
         mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
     }
diff --git a/tests/net/java/android/net/util/KeepaliveUtilsTest.kt b/tests/net/java/android/net/util/KeepaliveUtilsTest.kt
index 8ea226d..b62bdbc 100644
--- a/tests/net/java/android/net/util/KeepaliveUtilsTest.kt
+++ b/tests/net/java/android/net/util/KeepaliveUtilsTest.kt
@@ -18,6 +18,7 @@
 
 import android.content.Context
 import android.content.res.Resources
+import android.net.ConnectivityResources
 import android.net.NetworkCapabilities
 import android.net.NetworkCapabilities.MAX_TRANSPORT
 import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
@@ -26,13 +27,15 @@
 import android.net.NetworkCapabilities.TRANSPORT_WIFI
 import androidx.test.filters.SmallTest
 import com.android.internal.R
+import org.junit.After
 import org.junit.Assert.assertArrayEquals
 import org.junit.Assert.assertEquals
 import org.junit.Assert.fail
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
-import org.mockito.ArgumentMatchers
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Mockito.any
 import org.mockito.Mockito.doReturn
 import org.mockito.Mockito.mock
 
@@ -47,21 +50,33 @@
 class KeepaliveUtilsTest {
 
     // Prepare mocked context with given resource strings.
-    private fun getMockedContextWithStringArrayRes(id: Int, res: Array<out String?>?): Context {
+    private fun getMockedContextWithStringArrayRes(
+        id: Int,
+        name: String,
+        res: Array<out String?>?
+    ): Context {
         val mockRes = mock(Resources::class.java)
-        doReturn(res).`when`(mockRes).getStringArray(ArgumentMatchers.eq(id))
+        doReturn(res).`when`(mockRes).getStringArray(eq(id))
+        doReturn(id).`when`(mockRes).getIdentifier(eq(name), any(), any())
 
         return mock(Context::class.java).apply {
             doReturn(mockRes).`when`(this).getResources()
+            ConnectivityResources.setResourcesContextForTest(this)
         }
     }
 
+    @After
+    fun tearDown() {
+        ConnectivityResources.setResourcesContextForTest(null)
+    }
+
     @Test
     fun testGetSupportedKeepalives() {
         fun assertRunWithException(res: Array<out String?>?) {
             try {
                 val mockContext = getMockedContextWithStringArrayRes(
-                        R.array.config_networkSupportedKeepaliveCount, res)
+                        R.array.config_networkSupportedKeepaliveCount,
+                        "config_networkSupportedKeepaliveCount", res)
                 KeepaliveUtils.getSupportedKeepalives(mockContext)
                 fail("Expected KeepaliveDeviceConfigurationException")
             } catch (expected: KeepaliveUtils.KeepaliveDeviceConfigurationException) {
@@ -89,7 +104,8 @@
         val expectedValidRes = intArrayOf(3, 0, 0, 0, 4, 0, 0, 0)
 
         val mockContext = getMockedContextWithStringArrayRes(
-                R.array.config_networkSupportedKeepaliveCount, validRes)
+                R.array.config_networkSupportedKeepaliveCount,
+                "config_networkSupportedKeepaliveCount", validRes)
         val actual = KeepaliveUtils.getSupportedKeepalives(mockContext)
         assertArrayEquals(expectedValidRes, actual)
     }
diff --git a/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt b/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt
index 1945ce7..25aa626 100644
--- a/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt
+++ b/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt
@@ -21,6 +21,7 @@
 import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_HANDOVER
 import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_PERFORMANCE
 import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_RELIABILITY
+import android.net.ConnectivityResources
 import android.net.ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI
 import android.net.ConnectivitySettingsManager.NETWORK_METERED_MULTIPATH_PREFERENCE
 import android.net.util.MultinetworkPolicyTracker.ActiveDataSubscriptionIdListener
@@ -31,8 +32,9 @@
 import android.test.mock.MockContentResolver
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
-import com.android.internal.R
+import com.android.connectivity.resources.R
 import com.android.internal.util.test.FakeSettingsProvider
+import org.junit.After
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
@@ -41,6 +43,7 @@
 import org.mockito.ArgumentCaptor
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.ArgumentMatchers.argThat
+import org.mockito.ArgumentMatchers.eq
 import org.mockito.Mockito.any
 import org.mockito.Mockito.doReturn
 import org.mockito.Mockito.mock
@@ -57,6 +60,8 @@
 @SmallTest
 class MultinetworkPolicyTrackerTest {
     private val resources = mock(Resources::class.java).also {
+        doReturn(R.integer.config_networkAvoidBadWifi).`when`(it).getIdentifier(
+                eq("config_networkAvoidBadWifi"), eq("integer"), any())
         doReturn(0).`when`(it).getInteger(R.integer.config_networkAvoidBadWifi)
     }
     private val telephonyManager = mock(TelephonyManager::class.java)
@@ -75,6 +80,7 @@
         doReturn(resources).`when`(it).resources
         doReturn(it).`when`(it).createConfigurationContext(any())
         Settings.Global.putString(resolver, NETWORK_AVOID_BAD_WIFI, "1")
+        ConnectivityResources.setResourcesContextForTest(it)
     }
     private val tracker = MultinetworkPolicyTracker(context, null /* handler */)
 
@@ -85,6 +91,11 @@
         assertEquals(preference, tracker.meteredMultipathPreference)
     }
 
+    @After
+    fun tearDown() {
+        ConnectivityResources.setResourcesContextForTest(null)
+    }
+
     @Test
     fun testUpdateMeteredMultipathPreference() {
         assertMultipathPreference(MULTIPATH_PREFERENCE_HANDOVER)
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 7ac488d..ed9a44b 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -82,15 +82,19 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_XCAP;
+import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION;
+import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS;
+import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
+import static android.net.NetworkCapabilities.REDACT_NONE;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
 import static android.net.NetworkCapabilities.TRANSPORT_VPN;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
-import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED;
-import static android.net.NetworkPolicyManager.RULE_NONE;
-import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
-import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
+import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_DATA_SAVER;
+import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_USER_RESTRICTED;
+import static android.net.NetworkPolicyManager.BLOCKED_REASON_BATTERY_SAVER;
+import static android.net.NetworkPolicyManager.BLOCKED_REASON_NONE;
 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID;
 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
@@ -179,6 +183,7 @@
 import android.net.ConnectivityManager.PacketKeepalive;
 import android.net.ConnectivityManager.PacketKeepaliveCallback;
 import android.net.ConnectivityManager.TooManyRequestsException;
+import android.net.ConnectivityResources;
 import android.net.ConnectivitySettingsManager;
 import android.net.ConnectivityThread;
 import android.net.DataStallReportParcelable;
@@ -188,7 +193,6 @@
 import android.net.INetd;
 import android.net.INetworkMonitor;
 import android.net.INetworkMonitorCallbacks;
-import android.net.INetworkPolicyListener;
 import android.net.IOnCompleteListener;
 import android.net.IQosCallback;
 import android.net.InetAddresses;
@@ -207,6 +211,7 @@
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
 import android.net.NetworkPolicyManager;
+import android.net.NetworkPolicyManager.NetworkPolicyCallback;
 import android.net.NetworkRequest;
 import android.net.NetworkScore;
 import android.net.NetworkSpecifier;
@@ -236,7 +241,6 @@
 import android.net.shared.NetworkMonitorUtils;
 import android.net.shared.PrivateDnsConfig;
 import android.net.util.MultinetworkPolicyTracker;
-import android.net.wifi.WifiInfo;
 import android.os.BadParcelableException;
 import android.os.Binder;
 import android.os.Build;
@@ -267,12 +271,14 @@
 import android.util.ArraySet;
 import android.util.Log;
 import android.util.Pair;
+import android.util.Range;
 import android.util.SparseArray;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.connectivity.resources.R;
 import com.android.internal.net.VpnConfig;
 import com.android.internal.net.VpnProfile;
 import com.android.internal.util.ArrayUtils;
@@ -282,7 +288,6 @@
 import com.android.net.module.util.ArrayTrackRecord;
 import com.android.server.ConnectivityService.ConnectivityDiagnosticsCallbackInfo;
 import com.android.server.connectivity.ConnectivityConstants;
-import com.android.server.connectivity.ConnectivityResources;
 import com.android.server.connectivity.MockableSystemProperties;
 import com.android.server.connectivity.Nat464Xlat;
 import com.android.server.connectivity.NetworkAgentInfo;
@@ -292,7 +297,6 @@
 import com.android.server.connectivity.Vpn;
 import com.android.server.connectivity.VpnProfileStore;
 import com.android.server.net.NetworkPinner;
-import com.android.server.net.NetworkPolicyManagerInternal;
 import com.android.testutils.ExceptionUtils;
 import com.android.testutils.HandlerUtils;
 import com.android.testutils.RecorderCallback.CallbackEntry;
@@ -423,7 +427,7 @@
     private TestNetworkAgentWrapper mEthernetNetworkAgent;
     private MockVpn mMockVpn;
     private Context mContext;
-    private INetworkPolicyListener mPolicyListener;
+    private NetworkPolicyCallback mPolicyCallback;
     private WrappedMultinetworkPolicyTracker mPolicyTracker;
     private HandlerThread mAlarmManagerThread;
     private TestNetIdManager mNetIdManager;
@@ -435,8 +439,7 @@
     private TestNetworkCallback mProfileDefaultNetworkCallback;
 
     // State variables required to emulate NetworkPolicyManagerService behaviour.
-    private int mUidRules = RULE_NONE;
-    private boolean mRestrictBackground = false;
+    private int mBlockedReasons = BLOCKED_REASON_NONE;
 
     @Mock DeviceIdleInternal mDeviceIdleInternal;
     @Mock INetworkManagementService mNetworkManagementService;
@@ -1159,7 +1162,7 @@
         }
 
         public void setUids(Set<UidRange> uids) {
-            mNetworkCapabilities.setUids(uids);
+            mNetworkCapabilities.setUids(UidRange.toIntRanges(uids));
             if (mAgentRegistered) {
                 mMockNetworkAgent.setNetworkCapabilities(mNetworkCapabilities, true);
             }
@@ -1375,28 +1378,13 @@
     }
 
     private void mockUidNetworkingBlocked() {
-        doAnswer(i -> mContext.getSystemService(NetworkPolicyManager.class)
-                .checkUidNetworkingBlocked(i.getArgument(0) /* uid */, mUidRules,
-                        i.getArgument(1) /* metered */, mRestrictBackground)
+        doAnswer(i -> NetworkPolicyManager.isUidBlocked(mBlockedReasons, i.getArgument(1))
         ).when(mNetworkPolicyManager).isUidNetworkingBlocked(anyInt(), anyBoolean());
-
-        doAnswer(inv -> mContext.getSystemService(NetworkPolicyManager.class)
-                .checkUidNetworkingBlocked(inv.getArgument(0) /* uid */,
-                        inv.getArgument(1) /* uidRules */,
-                        inv.getArgument(2) /* isNetworkMetered */,
-                        inv.getArgument(3) /* isBackgroundRestricted */)
-        ).when(mNetworkPolicyManager).checkUidNetworkingBlocked(
-                anyInt(), anyInt(), anyBoolean(), anyBoolean());
     }
 
-    private void setUidRulesChanged(int uidRules) throws RemoteException {
-        mUidRules = uidRules;
-        mPolicyListener.onUidRulesChanged(Process.myUid(), mUidRules);
-    }
-
-    private void setRestrictBackgroundChanged(boolean restrictBackground) throws RemoteException {
-        mRestrictBackground = restrictBackground;
-        mPolicyListener.onRestrictBackgroundChanged(mRestrictBackground);
+    private void setBlockedReasonChanged(int blockedReasons) {
+        mBlockedReasons = blockedReasons;
+        mPolicyCallback.onUidBlockedReasonChanged(Process.myUid(), blockedReasons);
     }
 
     private Nat464Xlat getNat464Xlat(NetworkAgentWrapper mna) {
@@ -1464,6 +1452,8 @@
     }
 
     private static final int PRIMARY_USER = 0;
+    private static final UidRange PRIMARY_UIDRANGE =
+            UidRange.createForUser(UserHandle.of(PRIMARY_USER));
     private static final int APP1_UID = UserHandle.getUid(PRIMARY_USER, 10100);
     private static final int APP2_UID = UserHandle.getUid(PRIMARY_USER, 10101);
     private static final int VPN_UID = UserHandle.getUid(PRIMARY_USER, 10043);
@@ -1517,9 +1507,6 @@
         mServiceContext = new MockContext(InstrumentationRegistry.getContext(),
                 new FakeSettingsProvider());
         mServiceContext.setUseRegisteredHandlers(true);
-        LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class);
-        LocalServices.addService(
-                NetworkPolicyManagerInternal.class, mock(NetworkPolicyManagerInternal.class));
 
         mAlarmManagerThread = new HandlerThread("TestAlarmManager");
         mAlarmManagerThread.start();
@@ -1538,10 +1525,11 @@
         mService.mNascentDelayMs = TEST_NASCENT_DELAY_MS;
         verify(mDeps).makeMultinetworkPolicyTracker(any(), any(), any());
 
-        final ArgumentCaptor<INetworkPolicyListener> policyListenerCaptor =
-                ArgumentCaptor.forClass(INetworkPolicyListener.class);
-        verify(mNetworkPolicyManager).registerListener(policyListenerCaptor.capture());
-        mPolicyListener = policyListenerCaptor.getValue();
+        final ArgumentCaptor<NetworkPolicyCallback> policyCallbackCaptor =
+                ArgumentCaptor.forClass(NetworkPolicyCallback.class);
+        verify(mNetworkPolicyManager).registerNetworkPolicyCallback(any(),
+                policyCallbackCaptor.capture());
+        mPolicyCallback = policyCallbackCaptor.getValue();
 
         // Create local CM before sending system ready so that we can answer
         // getSystemService() correctly.
@@ -1585,11 +1573,27 @@
                 com.android.connectivity.resources.R.string.config_networkCaptivePortalServerUrl);
         doReturn(new String[]{ WIFI_WOL_IFNAME }).when(mResources).getStringArray(
                 com.android.connectivity.resources.R.array.config_wakeonlan_supported_interfaces);
-        final com.android.server.connectivity.ConnectivityResources connRes = mock(
-                ConnectivityResources.class);
+        doReturn(new String[] { "0,1", "1,3" }).when(mResources).getStringArray(
+                com.android.connectivity.resources.R.array.config_networkSupportedKeepaliveCount);
+        doReturn(com.android.connectivity.resources.R.array.config_networkSupportedKeepaliveCount)
+                .when(mResources).getIdentifier(eq("config_networkSupportedKeepaliveCount"),
+                eq("array"), any());
+        doReturn(com.android.connectivity.resources.R.array.network_switch_type_name)
+                .when(mResources).getIdentifier(eq("network_switch_type_name"),
+                eq("array"), any());
+
+        // We don't test the actual notification value strings, so just return an empty array.
+        // It doesn't matter what the values are as long as it's not null.
+        doReturn(new String[0]).when(mResources).getStringArray(R.array.network_switch_type_name);
+
+        final ConnectivityResources connRes = mock(ConnectivityResources.class);
         doReturn(mResources).when(connRes).get();
         doReturn(connRes).when(deps).getResources(any());
 
+        final Context mockResContext = mock(Context.class);
+        doReturn(mResources).when(mockResContext).getResources();
+        ConnectivityResources.setResourcesContextForTest(mockResContext);
+
         return deps;
     }
 
@@ -1645,6 +1649,7 @@
         waitForIdle();
 
         FakeSettingsProvider.clearSettingsProvider();
+        ConnectivityResources.setResourcesContextForTest(null);
 
         mCsHandlerThread.quitSafely();
         mAlarmManagerThread.quitSafely();
@@ -4343,6 +4348,7 @@
         assertTrue(mPolicyTracker.shouldNotifyWifiUnvalidated());
     }
 
+    @Ignore("Refactoring in progress b/178071397")
     @Test
     public void testAvoidBadWifi() throws Exception {
         final ContentResolver cr = mServiceContext.getContentResolver();
@@ -6946,7 +6952,7 @@
         final int uid = Process.myUid();
         NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork());
         assertNotNull("nc=" + nc, nc.getUids());
-        assertEquals(nc.getUids(), uidRangesForUids(uid));
+        assertEquals(nc.getUids(), UidRange.toIntRanges(uidRangesForUids(uid)));
         assertVpnTransportInfo(nc, VpnManager.TYPE_VPN_SERVICE);
 
         // Set an underlying network and expect to see the VPN transports change.
@@ -6971,10 +6977,13 @@
 
         // Expect that the VPN UID ranges contain both |uid| and the UID range for the newly-added
         // restricted user.
+        final UidRange rRange = UidRange.createForUser(UserHandle.of(RESTRICTED_USER));
+        final Range<Integer> restrictUidRange = new Range<Integer>(rRange.start, rRange.stop);
+        final Range<Integer> singleUidRange = new Range<Integer>(uid, uid);
         callback.expectCapabilitiesThat(mMockVpn, (caps)
                 -> caps.getUids().size() == 2
-                && caps.getUids().contains(new UidRange(uid, uid))
-                && caps.getUids().contains(createUidRange(RESTRICTED_USER))
+                && caps.getUids().contains(singleUidRange)
+                && caps.getUids().contains(restrictUidRange)
                 && caps.hasTransport(TRANSPORT_VPN)
                 && caps.hasTransport(TRANSPORT_WIFI));
 
@@ -6983,8 +6992,8 @@
         callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
         callback.expectCapabilitiesThat(mMockVpn, (caps)
                 -> caps.getUids().size() == 2
-                && caps.getUids().contains(new UidRange(uid, uid))
-                && caps.getUids().contains(createUidRange(RESTRICTED_USER))
+                && caps.getUids().contains(singleUidRange)
+                && caps.getUids().contains(restrictUidRange)
                 && caps.hasTransport(TRANSPORT_VPN)
                 && !caps.hasTransport(TRANSPORT_WIFI));
 
@@ -6998,7 +7007,7 @@
         // change made just before that (i.e., loss of TRANSPORT_WIFI) is preserved.
         callback.expectCapabilitiesThat(mMockVpn, (caps)
                 -> caps.getUids().size() == 1
-                && caps.getUids().contains(new UidRange(uid, uid))
+                && caps.getUids().contains(singleUidRange)
                 && caps.hasTransport(TRANSPORT_VPN)
                 && !caps.hasTransport(TRANSPORT_WIFI));
     }
@@ -7265,7 +7274,7 @@
         assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
         assertExtraInfoFromCmPresent(mCellNetworkAgent);
 
-        setUidRulesChanged(RULE_REJECT_ALL);
+        setBlockedReasonChanged(BLOCKED_REASON_BATTERY_SAVER);
         cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
         assertNull(mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
@@ -7273,17 +7282,17 @@
         assertExtraInfoFromCmBlocked(mCellNetworkAgent);
 
         // ConnectivityService should cache it not to invoke the callback again.
-        setUidRulesChanged(RULE_REJECT_METERED);
+        setBlockedReasonChanged(BLOCKED_METERED_REASON_USER_RESTRICTED);
         cellNetworkCallback.assertNoCallback();
 
-        setUidRulesChanged(RULE_NONE);
+        setBlockedReasonChanged(BLOCKED_REASON_NONE);
         cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
         assertExtraInfoFromCmPresent(mCellNetworkAgent);
 
-        setUidRulesChanged(RULE_REJECT_METERED);
+        setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER);
         cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
         assertNull(mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
@@ -7308,33 +7317,33 @@
         assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
         assertExtraInfoFromCmBlocked(mCellNetworkAgent);
 
-        setUidRulesChanged(RULE_ALLOW_METERED);
+        setBlockedReasonChanged(BLOCKED_REASON_NONE);
         cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
         assertExtraInfoFromCmPresent(mCellNetworkAgent);
 
-        setUidRulesChanged(RULE_NONE);
+        setBlockedReasonChanged(BLOCKED_REASON_NONE);
         cellNetworkCallback.assertNoCallback();
 
         // Restrict background data. Networking is not blocked because the network is unmetered.
-        setRestrictBackgroundChanged(true);
+        setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER);
         cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
         assertNull(mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
         assertExtraInfoFromCmBlocked(mCellNetworkAgent);
-        setRestrictBackgroundChanged(true);
+        setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER);
         cellNetworkCallback.assertNoCallback();
 
-        setUidRulesChanged(RULE_ALLOW_METERED);
+        setBlockedReasonChanged(BLOCKED_REASON_NONE);
         cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
         assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
         assertExtraInfoFromCmPresent(mCellNetworkAgent);
 
-        setRestrictBackgroundChanged(false);
+        setBlockedReasonChanged(BLOCKED_REASON_NONE);
         cellNetworkCallback.assertNoCallback();
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
@@ -7351,9 +7360,9 @@
         mockUidNetworkingBlocked();
 
         // No Networkcallbacks invoked before any network is active.
-        setUidRulesChanged(RULE_REJECT_ALL);
-        setUidRulesChanged(RULE_NONE);
-        setUidRulesChanged(RULE_REJECT_METERED);
+        setBlockedReasonChanged(BLOCKED_REASON_BATTERY_SAVER);
+        setBlockedReasonChanged(BLOCKED_REASON_NONE);
+        setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER);
         defaultCallback.assertNoCallback();
 
         mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
@@ -7378,8 +7387,8 @@
         defaultCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
 
         // Verify there's no Networkcallbacks invoked after data saver on/off.
-        setRestrictBackgroundChanged(true);
-        setRestrictBackgroundChanged(false);
+        setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER);
+        setBlockedReasonChanged(BLOCKED_REASON_NONE);
         defaultCallback.assertNoCallback();
 
         mCellNetworkAgent.disconnect();
@@ -7478,6 +7487,9 @@
         final NetworkRequest vpnUidRequest = new NetworkRequest.Builder().build();
         registerNetworkCallbackAsUid(vpnUidRequest, vpnUidCallback, VPN_UID);
 
+        final TestNetworkCallback vpnUidDefaultCallback = new TestNetworkCallback();
+        registerDefaultNetworkCallbackAsUid(vpnUidDefaultCallback, VPN_UID);
+
         final int uid = Process.myUid();
         final int userId = UserHandle.getUserId(uid);
         final ArrayList<String> allowList = new ArrayList<>();
@@ -7496,6 +7508,7 @@
         callback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiNetworkAgent);
         defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiNetworkAgent);
         vpnUidCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+        vpnUidDefaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID));
         assertNull(mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED);
@@ -7508,6 +7521,7 @@
         callback.expectBlockedStatusCallback(false, mWiFiNetworkAgent);
         defaultCallback.expectBlockedStatusCallback(false, mWiFiNetworkAgent);
         vpnUidCallback.assertNoCallback();
+        vpnUidDefaultCallback.assertNoCallback();
         expectNetworkRejectNonSecureVpn(inOrder, false, firstHalf, secondHalf);
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID));
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
@@ -7522,6 +7536,7 @@
         callback.assertNoCallback();
         defaultCallback.assertNoCallback();
         vpnUidCallback.assertNoCallback();
+        vpnUidDefaultCallback.assertNoCallback();
 
         // The following requires that the UID of this test package is greater than VPN_UID. This
         // is always true in practice because a plain AOSP build with no apps installed has almost
@@ -7542,6 +7557,7 @@
         callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
         defaultCallback.assertNoCallback();
         vpnUidCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
+        vpnUidDefaultCallback.assertNoCallback();
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID));
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
@@ -7562,6 +7578,7 @@
         defaultCallback.expectBlockedStatusCallback(true, mWiFiNetworkAgent);
         assertBlockedCallbackInAnyOrder(callback, true, mWiFiNetworkAgent, mCellNetworkAgent);
         vpnUidCallback.assertNoCallback();
+        vpnUidDefaultCallback.assertNoCallback();
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID));
         assertNull(mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED);
@@ -7573,6 +7590,7 @@
         defaultCallback.expectBlockedStatusCallback(false, mWiFiNetworkAgent);
         assertBlockedCallbackInAnyOrder(callback, false, mWiFiNetworkAgent, mCellNetworkAgent);
         vpnUidCallback.assertNoCallback();
+        vpnUidDefaultCallback.assertNoCallback();
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID));
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
@@ -7587,6 +7605,7 @@
         callback.assertNoCallback();
         defaultCallback.assertNoCallback();
         vpnUidCallback.assertNoCallback();
+        vpnUidDefaultCallback.assertNoCallback();
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID));
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
@@ -7598,6 +7617,7 @@
         callback.assertNoCallback();
         defaultCallback.assertNoCallback();
         vpnUidCallback.assertNoCallback();
+        vpnUidDefaultCallback.assertNoCallback();
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID));
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
@@ -7610,6 +7630,7 @@
         defaultCallback.expectBlockedStatusCallback(true, mWiFiNetworkAgent);
         assertBlockedCallbackInAnyOrder(callback, true, mWiFiNetworkAgent, mCellNetworkAgent);
         vpnUidCallback.assertNoCallback();
+        vpnUidDefaultCallback.assertNoCallback();
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID));
         assertNull(mCm.getActiveNetwork());
         assertActiveNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED);
@@ -7620,6 +7641,7 @@
         assertUidRangesUpdatedForMyUid(true);
         defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn);
         vpnUidCallback.assertNoCallback();  // vpnUidCallback has NOT_VPN capability.
+        vpnUidDefaultCallback.assertNoCallback();  // VPN does not apply to VPN_UID
         assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetwork());
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(VPN_UID));
         assertActiveNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
@@ -7630,11 +7652,14 @@
         mMockVpn.disconnect();
         defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
         defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiNetworkAgent);
+        vpnUidCallback.assertNoCallback();
+        vpnUidDefaultCallback.assertNoCallback();
         assertNull(mCm.getActiveNetwork());
 
         mCm.unregisterNetworkCallback(callback);
         mCm.unregisterNetworkCallback(defaultCallback);
         mCm.unregisterNetworkCallback(vpnUidCallback);
+        mCm.unregisterNetworkCallback(vpnUidDefaultCallback);
     }
 
     private void setupLegacyLockdownVpn() {
@@ -7656,7 +7681,7 @@
         assertNotNull(underlying);
         mMockVpn.setVpnType(VpnManager.TYPE_VPN_LEGACY);
         // The legacy lockdown VPN only supports userId 0.
-        final Set<UidRange> ranges = Collections.singleton(createUidRange(PRIMARY_USER));
+        final Set<UidRange> ranges = Collections.singleton(PRIMARY_UIDRANGE);
         mMockVpn.registerAgent(ranges);
         mMockVpn.setUnderlyingNetworks(new Network[]{underlying});
         mMockVpn.connect(true);
@@ -8618,7 +8643,7 @@
         lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
         lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE));
         // The uid range needs to cover the test app so the network is visible to it.
-        final Set<UidRange> vpnRange = Collections.singleton(createUidRange(PRIMARY_USER));
+        final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE);
         mMockVpn.establish(lp, VPN_UID, vpnRange);
         assertVpnUidRangesUpdated(true, vpnRange, VPN_UID);
 
@@ -8646,7 +8671,7 @@
         lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
         lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
         // The uid range needs to cover the test app so the network is visible to it.
-        final Set<UidRange> vpnRange = Collections.singleton(createUidRange(PRIMARY_USER));
+        final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE);
         mMockVpn.establish(lp, Process.SYSTEM_UID, vpnRange);
         assertVpnUidRangesUpdated(true, vpnRange, Process.SYSTEM_UID);
 
@@ -8662,7 +8687,7 @@
         lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, "tun0"));
         lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE));
         // The uid range needs to cover the test app so the network is visible to it.
-        final Set<UidRange> vpnRange = Collections.singleton(createUidRange(PRIMARY_USER));
+        final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE);
         mMockVpn.establish(lp, Process.SYSTEM_UID, vpnRange);
         assertVpnUidRangesUpdated(true, vpnRange, Process.SYSTEM_UID);
 
@@ -8677,7 +8702,7 @@
         lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
         lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
         // The uid range needs to cover the test app so the network is visible to it.
-        final Set<UidRange> vpnRange = Collections.singleton(createUidRange(PRIMARY_USER));
+        final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE);
         mMockVpn.establish(lp, VPN_UID, vpnRange);
         assertVpnUidRangesUpdated(true, vpnRange, VPN_UID);
 
@@ -8729,7 +8754,7 @@
         lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE));
         lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
         // The uid range needs to cover the test app so the network is visible to it.
-        final UidRange vpnRange = createUidRange(PRIMARY_USER);
+        final UidRange vpnRange = PRIMARY_UIDRANGE;
         final Set<UidRange> vpnRanges = Collections.singleton(vpnRange);
         mMockVpn.establish(lp, VPN_UID, vpnRanges);
         assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID);
@@ -8834,29 +8859,34 @@
         final NetworkCapabilities netCap = new NetworkCapabilities().setOwnerUid(ownerUid);
 
         return mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
-                netCap, includeLocationSensitiveInfo, callerUid,
+                netCap, includeLocationSensitiveInfo, Process.myUid(), callerUid,
                 mContext.getPackageName(), getAttributionTag())
                 .getOwnerUid();
     }
 
-    private void verifyWifiInfoCopyNetCapsPermission(
+    private void verifyTransportInfoCopyNetCapsPermission(
             int callerUid, boolean includeLocationSensitiveInfo,
             boolean shouldMakeCopyWithLocationSensitiveFieldsParcelable) {
-        final WifiInfo wifiInfo = mock(WifiInfo.class);
-        when(wifiInfo.hasLocationSensitiveFields()).thenReturn(true);
-        final NetworkCapabilities netCap = new NetworkCapabilities().setTransportInfo(wifiInfo);
+        final TransportInfo transportInfo = mock(TransportInfo.class);
+        when(transportInfo.getApplicableRedactions()).thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION);
+        final NetworkCapabilities netCap =
+                new NetworkCapabilities().setTransportInfo(transportInfo);
 
         mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
-                netCap, includeLocationSensitiveInfo, callerUid,
+                netCap, includeLocationSensitiveInfo, Process.myPid(), callerUid,
                 mContext.getPackageName(), getAttributionTag());
-        verify(wifiInfo).makeCopy(eq(shouldMakeCopyWithLocationSensitiveFieldsParcelable));
+        if (shouldMakeCopyWithLocationSensitiveFieldsParcelable) {
+            verify(transportInfo).makeCopy(REDACT_NONE);
+        } else {
+            verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION);
+        }
     }
 
-    private void verifyOwnerUidAndWifiInfoNetCapsPermission(
+    private void verifyOwnerUidAndTransportInfoNetCapsPermission(
             boolean shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag,
             boolean shouldInclLocationSensitiveOwnerUidWithIncludeFlag,
-            boolean shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag,
-            boolean shouldInclLocationSensitiveWifiInfoWithIncludeFlag) {
+            boolean shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag,
+            boolean shouldInclLocationSensitiveTransportInfoWithIncludeFlag) {
         final int myUid = Process.myUid();
 
         final int expectedOwnerUidWithoutIncludeFlag =
@@ -8870,13 +8900,13 @@
         assertEquals(expectedOwnerUidWithIncludeFlag, getOwnerUidNetCapsPermission(
                 myUid, myUid, true /* includeLocationSensitiveInfo */));
 
-        verifyWifiInfoCopyNetCapsPermission(myUid,
+        verifyTransportInfoCopyNetCapsPermission(myUid,
                 false, /* includeLocationSensitiveInfo */
-                shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag);
+                shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag);
 
-        verifyWifiInfoCopyNetCapsPermission(myUid,
+        verifyTransportInfoCopyNetCapsPermission(myUid,
                 true, /* includeLocationSensitiveInfo */
-                shouldInclLocationSensitiveWifiInfoWithIncludeFlag);
+                shouldInclLocationSensitiveTransportInfoWithIncludeFlag);
 
     }
 
@@ -8886,15 +8916,15 @@
         setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
                 Manifest.permission.ACCESS_FINE_LOCATION);
 
-        verifyOwnerUidAndWifiInfoNetCapsPermission(
+        verifyOwnerUidAndTransportInfoNetCapsPermission(
                 // Ensure that we include owner uid even if the request asks to remove it since the
                 // app has necessary permissions and targetSdk < S.
                 true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
                 true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
-                false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+                false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */
                 // Ensure that we remove location info if the request asks to remove it even if the
                 // app has necessary permissions.
-                true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+                true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */
         );
     }
 
@@ -8904,15 +8934,15 @@
         setupLocationPermissions(Build.VERSION_CODES.R, true, AppOpsManager.OPSTR_FINE_LOCATION,
                 Manifest.permission.ACCESS_FINE_LOCATION);
 
-        verifyOwnerUidAndWifiInfoNetCapsPermission(
+        verifyOwnerUidAndTransportInfoNetCapsPermission(
                 // Ensure that we include owner uid even if the request asks to remove it since the
                 // app has necessary permissions and targetSdk < S.
                 true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
                 true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
-                false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+                false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */
                 // Ensure that we remove location info if the request asks to remove it even if the
                 // app has necessary permissions.
-                true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+                true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */
         );
     }
 
@@ -8923,15 +8953,15 @@
         setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_FINE_LOCATION,
                 Manifest.permission.ACCESS_FINE_LOCATION);
 
-        verifyOwnerUidAndWifiInfoNetCapsPermission(
+        verifyOwnerUidAndTransportInfoNetCapsPermission(
                 // Ensure that we owner UID if the request asks us to remove it even if the app
                 // has necessary permissions since targetSdk >= S.
                 false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
                 true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
-                false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+                false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */
                 // Ensure that we remove location info if the request asks to remove it even if the
                 // app has necessary permissions.
-                true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+                true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */
         );
     }
 
@@ -8941,15 +8971,15 @@
         setupLocationPermissions(Build.VERSION_CODES.P, true, AppOpsManager.OPSTR_COARSE_LOCATION,
                 Manifest.permission.ACCESS_COARSE_LOCATION);
 
-        verifyOwnerUidAndWifiInfoNetCapsPermission(
+        verifyOwnerUidAndTransportInfoNetCapsPermission(
                 // Ensure that we owner UID if the request asks us to remove it even if the app
                 // has necessary permissions since targetSdk >= S.
                 true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
                 true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
-                false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+                false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */
                 // Ensure that we remove location info if the request asks to remove it even if the
                 // app has necessary permissions.
-                true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+                true /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */
         );
     }
 
@@ -8959,11 +8989,11 @@
         setupLocationPermissions(Build.VERSION_CODES.Q, false, AppOpsManager.OPSTR_FINE_LOCATION,
                 Manifest.permission.ACCESS_FINE_LOCATION);
 
-        verifyOwnerUidAndWifiInfoNetCapsPermission(
+        verifyOwnerUidAndTransportInfoNetCapsPermission(
                 false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
                 false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
-                false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
-                false /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+                false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */
+                false /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */
         );
     }
 
@@ -8986,11 +9016,11 @@
         setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_COARSE_LOCATION,
                 Manifest.permission.ACCESS_COARSE_LOCATION);
 
-        verifyOwnerUidAndWifiInfoNetCapsPermission(
+        verifyOwnerUidAndTransportInfoNetCapsPermission(
                 false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
                 false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
-                false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
-                false /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+                false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */
+                false /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */
         );
     }
 
@@ -9000,17 +9030,196 @@
         // Test that not having fine location permission leads to sanitization.
         setupLocationPermissions(Build.VERSION_CODES.Q, true, null /* op */, null /* perm */);
 
-        verifyOwnerUidAndWifiInfoNetCapsPermission(
+        verifyOwnerUidAndTransportInfoNetCapsPermission(
                 false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
                 false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
-                false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
-                false /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+                false, /* shouldInclLocationSensitiveTransportInfoWithoutIncludeFlag */
+                false /* shouldInclLocationSensitiveTransportInfoWithIncludeFlag */
         );
     }
 
+    @Test
+    public void testCreateForCallerWithLocalMacAddressSanitizedWithLocalMacAddressPermission()
+            throws Exception {
+        mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_GRANTED);
+
+        final TransportInfo transportInfo = mock(TransportInfo.class);
+        when(transportInfo.getApplicableRedactions())
+                .thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS);
+        final NetworkCapabilities netCap =
+                new NetworkCapabilities().setTransportInfo(transportInfo);
+
+        mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
+                netCap, false /* includeLocationSensitiveInfoInTransportInfo */,
+                Process.myPid(), Process.myUid(),
+                mContext.getPackageName(), getAttributionTag());
+        // don't redact MAC_ADDRESS fields, only location sensitive fields.
+        verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION);
+    }
+
+    @Test
+    public void testCreateForCallerWithLocalMacAddressSanitizedWithoutLocalMacAddressPermission()
+            throws Exception {
+        mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_DENIED);
+
+        final TransportInfo transportInfo = mock(TransportInfo.class);
+        when(transportInfo.getApplicableRedactions())
+                .thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS);
+        final NetworkCapabilities netCap =
+                new NetworkCapabilities().setTransportInfo(transportInfo);
+
+        mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
+                netCap, false /* includeLocationSensitiveInfoInTransportInfo */,
+                Process.myPid(), Process.myUid(),
+                mContext.getPackageName(), getAttributionTag());
+        // redact both MAC_ADDRESS & location sensitive fields.
+        verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION
+                | REDACT_FOR_LOCAL_MAC_ADDRESS);
+    }
+
+    @Test
+    public void testCreateForCallerWithLocalMacAddressSanitizedWithSettingsPermission()
+            throws Exception {
+        mServiceContext.setPermission(Manifest.permission.NETWORK_SETTINGS, PERMISSION_GRANTED);
+
+        final TransportInfo transportInfo = mock(TransportInfo.class);
+        when(transportInfo.getApplicableRedactions())
+                .thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS);
+        final NetworkCapabilities netCap =
+                new NetworkCapabilities().setTransportInfo(transportInfo);
+
+        mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
+                netCap, false /* includeLocationSensitiveInfoInTransportInfo */,
+                Process.myPid(), Process.myUid(),
+                mContext.getPackageName(), getAttributionTag());
+        // don't redact NETWORK_SETTINGS fields, only location sensitive fields.
+        verify(transportInfo).makeCopy(REDACT_FOR_ACCESS_FINE_LOCATION);
+    }
+
+    @Test
+    public void testCreateForCallerWithLocalMacAddressSanitizedWithoutSettingsPermission()
+            throws Exception {
+        mServiceContext.setPermission(Manifest.permission.LOCAL_MAC_ADDRESS, PERMISSION_DENIED);
+
+        final TransportInfo transportInfo = mock(TransportInfo.class);
+        when(transportInfo.getApplicableRedactions())
+                .thenReturn(REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS);
+        final NetworkCapabilities netCap =
+                new NetworkCapabilities().setTransportInfo(transportInfo);
+
+        mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
+                netCap, false /* includeLocationSensitiveInfoInTransportInfo */,
+                Process.myPid(), Process.myUid(),
+                mContext.getPackageName(), getAttributionTag());
+        // redact both NETWORK_SETTINGS & location sensitive fields.
+        verify(transportInfo).makeCopy(
+                REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_NETWORK_SETTINGS);
+    }
+
+    /**
+     * Test TransportInfo to verify redaction mechanism.
+     */
+    private static class TestTransportInfo implements TransportInfo {
+        public final boolean locationRedacted;
+        public final boolean localMacAddressRedacted;
+        public final boolean settingsRedacted;
+
+        TestTransportInfo() {
+            locationRedacted = false;
+            localMacAddressRedacted = false;
+            settingsRedacted = false;
+        }
+
+        TestTransportInfo(boolean locationRedacted, boolean localMacAddressRedacted,
+                boolean settingsRedacted) {
+            this.locationRedacted = locationRedacted;
+            this.localMacAddressRedacted =
+                    localMacAddressRedacted;
+            this.settingsRedacted = settingsRedacted;
+        }
+
+        @Override
+        public TransportInfo makeCopy(@NetworkCapabilities.RedactionType long redactions) {
+            return new TestTransportInfo(
+                    (redactions & REDACT_FOR_ACCESS_FINE_LOCATION) != 0,
+                    (redactions & REDACT_FOR_LOCAL_MAC_ADDRESS) != 0,
+                    (redactions & REDACT_FOR_NETWORK_SETTINGS) != 0
+            );
+        }
+
+        @Override
+        public @NetworkCapabilities.RedactionType long getApplicableRedactions() {
+            return REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS
+                    | REDACT_FOR_NETWORK_SETTINGS;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (!(other instanceof TestTransportInfo)) return false;
+            TestTransportInfo that = (TestTransportInfo) other;
+            return that.locationRedacted == this.locationRedacted
+                    && that.localMacAddressRedacted == this.localMacAddressRedacted
+                    && that.settingsRedacted == this.settingsRedacted;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(locationRedacted, localMacAddressRedacted, settingsRedacted);
+        }
+    }
+
+    private void verifyNetworkCallbackLocationDataInclusionUsingTransportInfoAndOwnerUidInNetCaps(
+            @NonNull TestNetworkCallback wifiNetworkCallback, int actualOwnerUid,
+            @NonNull TransportInfo actualTransportInfo, int expectedOwnerUid,
+            @NonNull TransportInfo expectedTransportInfo) throws Exception {
+        when(mPackageManager.getTargetSdkVersion(anyString())).thenReturn(Build.VERSION_CODES.S);
+        final NetworkCapabilities ncTemplate =
+                new NetworkCapabilities()
+                        .addTransportType(TRANSPORT_WIFI)
+                        .setOwnerUid(actualOwnerUid);
+
+        final NetworkRequest wifiRequest = new NetworkRequest.Builder()
+                .addTransportType(TRANSPORT_WIFI).build();
+        mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback);
+
+        mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(),
+                ncTemplate);
+        mWiFiNetworkAgent.connect(false);
+
+        wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+
+        // Send network capabilities update with TransportInfo to trigger capabilities changed
+        // callback.
+        mWiFiNetworkAgent.setNetworkCapabilities(
+                ncTemplate.setTransportInfo(actualTransportInfo), true);
+
+        wifiNetworkCallback.expectCapabilitiesThat(mWiFiNetworkAgent,
+                nc -> Objects.equals(expectedOwnerUid, nc.getOwnerUid())
+                        && Objects.equals(expectedTransportInfo, nc.getTransportInfo()));
+
+    }
+
+    @Test
+    public void testVerifyLocationDataIsNotIncludedWhenInclFlagNotSet() throws Exception {
+        final TestNetworkCallback wifiNetworkCallack = new TestNetworkCallback();
+        final int ownerUid = Process.myUid();
+        final TransportInfo transportInfo = new TestTransportInfo();
+        // Even though the test uid holds privileged permissions, mask location fields since
+        // the callback did not explicitly opt-in to get location data.
+        final TransportInfo sanitizedTransportInfo = new TestTransportInfo(
+                true, /* locationRedacted */
+                true, /* localMacAddressRedacted */
+                true /* settingsRedacted */
+        );
+        // Should not expect location data since the callback does not set the flag for including
+        // location data.
+        verifyNetworkCallbackLocationDataInclusionUsingTransportInfoAndOwnerUidInNetCaps(
+                wifiNetworkCallack, ownerUid, transportInfo, INVALID_UID, sanitizedTransportInfo);
+    }
+
     private void setupConnectionOwnerUid(int vpnOwnerUid, @VpnManager.VpnType int vpnType)
             throws Exception {
-        final Set<UidRange> vpnRange = Collections.singleton(createUidRange(PRIMARY_USER));
+        final Set<UidRange> vpnRange = Collections.singleton(PRIMARY_UIDRANGE);
         mMockVpn.setVpnType(vpnType);
         mMockVpn.establish(new LinkProperties(), vpnOwnerUid, vpnRange);
         assertVpnUidRangesUpdated(true, vpnRange, vpnOwnerUid);
@@ -9570,7 +9779,7 @@
         lp.setInterfaceName("tun0");
         lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
         lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
-        final UidRange vpnRange = createUidRange(PRIMARY_USER);
+        final UidRange vpnRange = PRIMARY_UIDRANGE;
         Set<UidRange> vpnRanges = Collections.singleton(vpnRange);
         mMockVpn.establish(lp, VPN_UID, vpnRanges);
         assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID);
@@ -9768,7 +9977,7 @@
                 .thenReturn(hasFeature);
     }
 
-    private UidRange getNriFirstUidRange(
+    private Range<Integer> getNriFirstUidRange(
             @NonNull final ConnectivityService.NetworkRequestInfo nri) {
         return nri.mRequests.get(0).networkCapabilities.getUids().iterator().next();
     }
@@ -9951,11 +10160,11 @@
                                 pref));
 
         // Sort by uid to access nris by index
-        nris.sort(Comparator.comparingInt(nri -> getNriFirstUidRange(nri).start));
-        assertEquals(TEST_PACKAGE_UID, getNriFirstUidRange(nris.get(0)).start);
-        assertEquals(TEST_PACKAGE_UID, getNriFirstUidRange(nris.get(0)).stop);
-        assertEquals(testPackageNameUid2, getNriFirstUidRange(nris.get(1)).start);
-        assertEquals(testPackageNameUid2, getNriFirstUidRange(nris.get(1)).stop);
+        nris.sort(Comparator.comparingInt(nri -> getNriFirstUidRange(nri).getLower()));
+        assertEquals(TEST_PACKAGE_UID, (int) getNriFirstUidRange(nris.get(0)).getLower());
+        assertEquals(TEST_PACKAGE_UID, (int) getNriFirstUidRange(nris.get(0)).getUpper());
+        assertEquals(testPackageNameUid2, (int) getNriFirstUidRange(nris.get(1)).getLower());
+        assertEquals(testPackageNameUid2, (int) getNriFirstUidRange(nris.get(1)).getUpper());
     }
 
     @Test
@@ -9985,17 +10194,17 @@
         // UIDs for all users and all managed packages should be present.
         // Two users each with two packages.
         final int expectedUidSize = 2;
-        final List<UidRange> uids =
+        final List<Range<Integer>> uids =
                 new ArrayList<>(nris.get(0).mRequests.get(0).networkCapabilities.getUids());
         assertEquals(expectedUidSize, uids.size());
 
         // Sort by uid to access nris by index
-        uids.sort(Comparator.comparingInt(uid -> uid.start));
+        uids.sort(Comparator.comparingInt(uid -> uid.getLower()));
         final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID);
-        assertEquals(TEST_PACKAGE_UID, uids.get(0).start);
-        assertEquals(TEST_PACKAGE_UID, uids.get(0).stop);
-        assertEquals(secondUserTestPackageUid, uids.get(1).start);
-        assertEquals(secondUserTestPackageUid, uids.get(1).stop);
+        assertEquals(TEST_PACKAGE_UID, (int) uids.get(0).getLower());
+        assertEquals(TEST_PACKAGE_UID, (int) uids.get(0).getUpper());
+        assertEquals(secondUserTestPackageUid, (int) uids.get(1).getLower());
+        assertEquals(secondUserTestPackageUid, (int) uids.get(1).getUpper());
     }
 
     @Test
diff --git a/tests/net/java/com/android/server/connectivity/FullScoreTest.kt b/tests/net/java/com/android/server/connectivity/FullScoreTest.kt
new file mode 100644
index 0000000..eb3b4df
--- /dev/null
+++ b/tests/net/java/com/android/server/connectivity/FullScoreTest.kt
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.connectivity
+
+import android.net.NetworkAgentConfig
+import android.net.NetworkCapabilities
+import android.text.TextUtils
+import android.util.ArraySet
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.server.connectivity.FullScore.MAX_CS_MANAGED_POLICY
+import com.android.server.connectivity.FullScore.POLICY_ACCEPT_UNVALIDATED
+import com.android.server.connectivity.FullScore.POLICY_EVER_USER_SELECTED
+import com.android.server.connectivity.FullScore.POLICY_IS_VALIDATED
+import com.android.server.connectivity.FullScore.POLICY_IS_VPN
+import org.junit.Test
+import org.junit.runner.RunWith
+import kotlin.collections.minOfOrNull
+import kotlin.collections.maxOfOrNull
+import kotlin.reflect.full.staticProperties
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class FullScoreTest {
+    // Convenience methods
+    fun FullScore.withPolicies(
+        validated: Boolean = false,
+        vpn: Boolean = false,
+        onceChosen: Boolean = false,
+        acceptUnvalidated: Boolean = false
+    ): FullScore {
+        val nac = NetworkAgentConfig.Builder().apply {
+            setUnvalidatedConnectivityAcceptable(acceptUnvalidated)
+            setExplicitlySelected(onceChosen)
+        }.build()
+        val nc = NetworkCapabilities.Builder().apply {
+            if (vpn) addTransportType(NetworkCapabilities.TRANSPORT_VPN)
+            if (validated) addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
+        }.build()
+        return mixInScore(nc, nac)
+    }
+
+    @Test
+    fun testGetLegacyInt() {
+        val ns = FullScore(50, 0L /* policy */)
+        assertEquals(10, ns.legacyInt) // -40 penalty for not being validated
+        assertEquals(50, ns.legacyIntAsValidated)
+
+        val vpnNs = FullScore(101, 0L /* policy */).withPolicies(vpn = true)
+        assertEquals(101, vpnNs.legacyInt) // VPNs are not subject to unvalidation penalty
+        assertEquals(101, vpnNs.legacyIntAsValidated)
+        assertEquals(101, vpnNs.withPolicies(validated = true).legacyInt)
+        assertEquals(101, vpnNs.withPolicies(validated = true).legacyIntAsValidated)
+
+        val validatedNs = ns.withPolicies(validated = true)
+        assertEquals(50, validatedNs.legacyInt) // No penalty, this is validated
+        assertEquals(50, validatedNs.legacyIntAsValidated)
+
+        val chosenNs = ns.withPolicies(onceChosen = true)
+        assertEquals(10, chosenNs.legacyInt)
+        assertEquals(100, chosenNs.legacyIntAsValidated)
+        assertEquals(10, chosenNs.withPolicies(acceptUnvalidated = true).legacyInt)
+        assertEquals(50, chosenNs.withPolicies(acceptUnvalidated = true).legacyIntAsValidated)
+    }
+
+    @Test
+    fun testToString() {
+        val string = FullScore(10, 0L /* policy */)
+                .withPolicies(vpn = true, acceptUnvalidated = true).toString()
+        assertTrue(string.contains("Score(10"), string)
+        assertTrue(string.contains("ACCEPT_UNVALIDATED"), string)
+        assertTrue(string.contains("IS_VPN"), string)
+        assertFalse(string.contains("IS_VALIDATED"), string)
+        val foundNames = ArraySet<String>()
+        getAllPolicies().forEach {
+            val name = FullScore.policyNameOf(it.get() as Int)
+            assertFalse(TextUtils.isEmpty(name))
+            assertFalse(foundNames.contains(name))
+            foundNames.add(name)
+        }
+        assertFailsWith<IllegalArgumentException> {
+            FullScore.policyNameOf(MAX_CS_MANAGED_POLICY + 1)
+        }
+    }
+
+    fun getAllPolicies() = Regex("POLICY_.*").let { nameRegex ->
+        FullScore::class.staticProperties.filter { it.name.matches(nameRegex) }
+    }
+
+    @Test
+    fun testHasPolicy() {
+        val ns = FullScore(50, 0L /* policy */)
+        assertFalse(ns.hasPolicy(POLICY_IS_VALIDATED))
+        assertFalse(ns.hasPolicy(POLICY_IS_VPN))
+        assertFalse(ns.hasPolicy(POLICY_EVER_USER_SELECTED))
+        assertFalse(ns.hasPolicy(POLICY_ACCEPT_UNVALIDATED))
+        assertTrue(ns.withPolicies(validated = true).hasPolicy(POLICY_IS_VALIDATED))
+        assertTrue(ns.withPolicies(vpn = true).hasPolicy(POLICY_IS_VPN))
+        assertTrue(ns.withPolicies(onceChosen = true).hasPolicy(POLICY_EVER_USER_SELECTED))
+        assertTrue(ns.withPolicies(acceptUnvalidated = true).hasPolicy(POLICY_ACCEPT_UNVALIDATED))
+    }
+
+    @Test
+    fun testMinMaxPolicyConstants() {
+        val policies = getAllPolicies()
+
+        policies.forEach { policy ->
+            assertTrue(policy.get() as Int >= FullScore.MIN_CS_MANAGED_POLICY)
+            assertTrue(policy.get() as Int <= FullScore.MAX_CS_MANAGED_POLICY)
+        }
+        assertEquals(FullScore.MIN_CS_MANAGED_POLICY,
+                policies.minOfOrNull { it.get() as Int })
+        assertEquals(FullScore.MAX_CS_MANAGED_POLICY,
+                policies.maxOfOrNull { it.get() as Int })
+    }
+}
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index ea2b362..9ab60a4 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -357,7 +357,7 @@
         caps.addTransportType(transport);
         NetworkAgentInfo nai = new NetworkAgentInfo(null, new Network(netId), info,
                 new LinkProperties(), caps, new NetworkScore.Builder().setLegacyInt(50).build(),
-                mCtx, null, new NetworkAgentConfig() /* config */, mConnService, mNetd,
+                mCtx, null, new NetworkAgentConfig.Builder().build(), mConnService, mNetd,
                 mDnsResolver, NetworkProvider.ID_NONE, Binder.getCallingUid(),
                 mQosCallbackTracker, new ConnectivityService.Dependencies());
         nai.everValidated = true;
diff --git a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
index ff8c632..3adf08c 100644
--- a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
@@ -20,6 +20,7 @@
 
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
@@ -35,6 +36,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
+import android.net.ConnectivityResources;
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
 import android.os.UserHandle;
@@ -43,9 +45,10 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.internal.R;
+import com.android.connectivity.resources.R;
 import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
 
+import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -119,11 +122,25 @@
         when(mCtx.getSystemService(eq(Context.NOTIFICATION_SERVICE)))
                 .thenReturn(mNotificationManager);
         when(mNetworkInfo.getExtraInfo()).thenReturn(TEST_EXTRA_INFO);
+        ConnectivityResources.setResourcesContextForTest(mCtx);
         when(mResources.getColor(anyInt(), any())).thenReturn(0xFF607D8B);
 
+        // Come up with some credible-looking transport names. The actual values do not matter.
+        String[] transportNames = new String[NetworkCapabilities.MAX_TRANSPORT + 1];
+        for (int transport = 0; transport <= NetworkCapabilities.MAX_TRANSPORT; transport++) {
+            transportNames[transport] = NetworkCapabilities.transportNameOf(transport);
+        }
+        when(mResources.getStringArray(R.array.network_switch_type_name))
+            .thenReturn(transportNames);
+
         mManager = new NetworkNotificationManager(mCtx, mTelephonyManager);
     }
 
+    @After
+    public void tearDown() {
+        ConnectivityResources.setResourcesContextForTest(null);
+    }
+
     private void verifyTitleByNetwork(final int id, final NetworkAgentInfo nai, final int title) {
         final String tag = NetworkNotificationManager.tagFor(id);
         mManager.showNotification(id, PRIVATE_DNS_BROKEN, nai, null, null, true);
@@ -142,15 +159,15 @@
     public void testTitleOfPrivateDnsBroken() {
         // Test the title of mobile data.
         verifyTitleByNetwork(100, mCellNai, R.string.mobile_no_internet);
-        reset(mResources);
+        clearInvocations(mResources);
 
         // Test the title of wifi.
         verifyTitleByNetwork(101, mWifiNai, R.string.wifi_no_internet);
-        reset(mResources);
+        clearInvocations(mResources);
 
         // Test the title of other networks.
         verifyTitleByNetwork(102, mVpnNai, R.string.other_networks_no_internet);
-        reset(mResources);
+        clearInvocations(mResources);
     }
 
     @Test
diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java
index 11fcea6..6ad4900 100644
--- a/tests/net/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/net/java/com/android/server/connectivity/VpnTest.java
@@ -23,6 +23,7 @@
 import static android.net.ConnectivityManager.NetworkCallback;
 import static android.net.INetd.IF_STATE_DOWN;
 import static android.net.INetd.IF_STATE_UP;
+import static android.os.UserHandle.PER_USER_RANGE;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
@@ -74,7 +75,6 @@
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo.DetailedState;
 import android.net.RouteInfo;
-import android.net.UidRange;
 import android.net.UidRangeParcel;
 import android.net.VpnManager;
 import android.net.VpnService;
@@ -181,8 +181,7 @@
             mPackages.put(PKGS[i], PKG_UIDS[i]);
         }
     }
-    private static final UidRange PRI_USER_RANGE =
-            UidRange.createForUser(UserHandle.of(primaryUser.id));
+    private static final Range<Integer> PRI_USER_RANGE = uidRangeForUser(primaryUser.id);
 
     @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext;
     @Mock private UserManager mUserManager;
@@ -260,6 +259,21 @@
                 .thenReturn(tunnelResp);
     }
 
+    private Set<Range<Integer>> rangeSet(Range<Integer> ... ranges) {
+        final Set<Range<Integer>> range = new ArraySet<>();
+        for (Range<Integer> r : ranges) range.add(r);
+
+        return range;
+    }
+
+    private static Range<Integer> uidRangeForUser(int userId) {
+        return new Range<Integer>(userId * PER_USER_RANGE, (userId + 1) * PER_USER_RANGE - 1);
+    }
+
+    private Range<Integer> uidRange(int start, int stop) {
+        return new Range<Integer>(start, stop);
+    }
+
     @Test
     public void testRestrictedProfilesAreAddedToVpn() {
         setMockedUsers(primaryUser, secondaryUser, restrictedProfileA, restrictedProfileB);
@@ -268,12 +282,10 @@
 
         // Assume the user can have restricted profiles.
         doReturn(true).when(mUserManager).canHaveRestrictedProfile();
-        final Set<UidRange> ranges =
+        final Set<Range<Integer>> ranges =
                 vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, null, null);
 
-        assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] {
-                PRI_USER_RANGE, UidRange.createForUser(UserHandle.of(restrictedProfileA.id))
-        })), ranges);
+        assertEquals(rangeSet(PRI_USER_RANGE, uidRangeForUser(restrictedProfileA.id)), ranges);
     }
 
     @Test
@@ -281,10 +293,10 @@
         setMockedUsers(primaryUser, managedProfileA);
 
         final Vpn vpn = createVpn(primaryUser.id);
-        final Set<UidRange> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
+        final Set<Range<Integer>> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
                 null, null);
 
-        assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] { PRI_USER_RANGE })), ranges);
+        assertEquals(rangeSet(PRI_USER_RANGE), ranges);
     }
 
     @Test
@@ -292,35 +304,38 @@
         setMockedUsers(primaryUser, restrictedProfileA, managedProfileA);
 
         final Vpn vpn = createVpn(primaryUser.id);
-        final Set<UidRange> ranges = new ArraySet<>();
+        final Set<Range<Integer>> ranges = new ArraySet<>();
         vpn.addUserToRanges(ranges, primaryUser.id, null, null);
 
-        assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] { PRI_USER_RANGE })), ranges);
+        assertEquals(rangeSet(PRI_USER_RANGE), ranges);
     }
 
     @Test
     public void testUidAllowAndDenylist() throws Exception {
         final Vpn vpn = createVpn(primaryUser.id);
-        final UidRange user = PRI_USER_RANGE;
+        final Range<Integer> user = PRI_USER_RANGE;
+        final int userStart = user.getLower();
+        final int userStop = user.getUpper();
         final String[] packages = {PKGS[0], PKGS[1], PKGS[2]};
 
         // Allowed list
-        final Set<UidRange> allow = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
-                Arrays.asList(packages), null);
-        assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] {
-            new UidRange(user.start + PKG_UIDS[0], user.start + PKG_UIDS[0]),
-            new UidRange(user.start + PKG_UIDS[1], user.start + PKG_UIDS[2])
-        })), allow);
+        final Set<Range<Integer>> allow = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
+                Arrays.asList(packages), null /* disallowedApplications */);
+        assertEquals(rangeSet(
+                uidRange(userStart + PKG_UIDS[0], userStart + PKG_UIDS[0]),
+                uidRange(userStart + PKG_UIDS[1], userStart + PKG_UIDS[2])),
+                allow);
 
         // Denied list
-        final Set<UidRange> disallow = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
-                null, Arrays.asList(packages));
-        assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] {
-            new UidRange(user.start, user.start + PKG_UIDS[0] - 1),
-            new UidRange(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[1] - 1),
-            /* Empty range between UIDS[1] and UIDS[2], should be excluded, */
-            new UidRange(user.start + PKG_UIDS[2] + 1, user.stop)
-        })), disallow);
+        final Set<Range<Integer>> disallow =
+                vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
+                        null /* allowedApplications */, Arrays.asList(packages));
+        assertEquals(rangeSet(
+                uidRange(userStart, userStart + PKG_UIDS[0] - 1),
+                uidRange(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[1] - 1),
+                /* Empty range between UIDS[1] and UIDS[2], should be excluded, */
+                uidRange(userStart + PKG_UIDS[2] + 1, userStop)),
+                disallow);
     }
 
     @Test
@@ -350,84 +365,86 @@
     @Test
     public void testLockdownChangingPackage() throws Exception {
         final Vpn vpn = createVpn(primaryUser.id);
-        final UidRange user = PRI_USER_RANGE;
-
+        final Range<Integer> user = PRI_USER_RANGE;
+        final int userStart = user.getLower();
+        final int userStop = user.getUpper();
         // Set always-on without lockdown.
         assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false, null));
 
         // Set always-on with lockdown.
         assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true, null));
         verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
-                new UidRangeParcel(user.start, user.start + PKG_UIDS[1] - 1),
-                new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.stop)
+                new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1),
+                new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStop)
         }));
 
         // Switch to another app.
         assertTrue(vpn.setAlwaysOnPackage(PKGS[3], true, null));
         verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
-                new UidRangeParcel(user.start, user.start + PKG_UIDS[1] - 1),
-                new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.stop)
+                new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1),
+                new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStop)
         }));
         verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
-                new UidRangeParcel(user.start, user.start + PKG_UIDS[3] - 1),
-                new UidRangeParcel(user.start + PKG_UIDS[3] + 1, user.stop)
+                new UidRangeParcel(userStart, userStart + PKG_UIDS[3] - 1),
+                new UidRangeParcel(userStart + PKG_UIDS[3] + 1, userStop)
         }));
     }
 
     @Test
     public void testLockdownAllowlist() throws Exception {
         final Vpn vpn = createVpn(primaryUser.id);
-        final UidRange user = PRI_USER_RANGE;
-
+        final Range<Integer> user = PRI_USER_RANGE;
+        final int userStart = user.getLower();
+        final int userStop = user.getUpper();
         // Set always-on with lockdown and allow app PKGS[2] from lockdown.
         assertTrue(vpn.setAlwaysOnPackage(
                 PKGS[1], true, Collections.singletonList(PKGS[2])));
-        verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
-                new UidRangeParcel(user.start, user.start + PKG_UIDS[1] - 1),
-                new UidRangeParcel(user.start + PKG_UIDS[2] + 1, user.stop)
+        verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[]  {
+                new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1),
+                new UidRangeParcel(userStart + PKG_UIDS[2] + 1, userStop)
         }));
         // Change allowed app list to PKGS[3].
         assertTrue(vpn.setAlwaysOnPackage(
                 PKGS[1], true, Collections.singletonList(PKGS[3])));
         verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
-                new UidRangeParcel(user.start + PKG_UIDS[2] + 1, user.stop)
+                new UidRangeParcel(userStart + PKG_UIDS[2] + 1, userStop)
         }));
         verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
-                new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.start + PKG_UIDS[3] - 1),
-                new UidRangeParcel(user.start + PKG_UIDS[3] + 1, user.stop)
+                new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStart + PKG_UIDS[3] - 1),
+                new UidRangeParcel(userStart + PKG_UIDS[3] + 1, userStop)
         }));
 
         // Change the VPN app.
         assertTrue(vpn.setAlwaysOnPackage(
                 PKGS[0], true, Collections.singletonList(PKGS[3])));
         verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
-                new UidRangeParcel(user.start, user.start + PKG_UIDS[1] - 1),
-                new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.start + PKG_UIDS[3] - 1)
+                new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1),
+                new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStart + PKG_UIDS[3] - 1)
         }));
         verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
-                new UidRangeParcel(user.start, user.start + PKG_UIDS[0] - 1),
-                new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[3] - 1)
+                new UidRangeParcel(userStart, userStart + PKG_UIDS[0] - 1),
+                new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[3] - 1)
         }));
 
         // Remove the list of allowed packages.
         assertTrue(vpn.setAlwaysOnPackage(PKGS[0], true, null));
         verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
-                new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[3] - 1),
-                new UidRangeParcel(user.start + PKG_UIDS[3] + 1, user.stop)
+                new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[3] - 1),
+                new UidRangeParcel(userStart + PKG_UIDS[3] + 1, userStop)
         }));
         verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
-                new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.stop),
+                new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStop),
         }));
 
         // Add the list of allowed packages.
         assertTrue(vpn.setAlwaysOnPackage(
                 PKGS[0], true, Collections.singletonList(PKGS[1])));
         verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
-                new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.stop)
+                new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStop)
         }));
         verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
-                new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[1] - 1),
-                new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.stop)
+                new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[1] - 1),
+                new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStop)
         }));
 
         // Try allowing a package with a comma, should be rejected.
@@ -439,12 +456,12 @@
         assertTrue(vpn.setAlwaysOnPackage(
                 PKGS[0], true, Arrays.asList("com.foo.app", PKGS[2], "com.bar.app")));
         verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] {
-                new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[1] - 1),
-                new UidRangeParcel(user.start + PKG_UIDS[1] + 1, user.stop)
+                new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[1] - 1),
+                new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStop)
         }));
         verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] {
-                new UidRangeParcel(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[2] - 1),
-                new UidRangeParcel(user.start + PKG_UIDS[2] + 1, user.stop)
+                new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[2] - 1),
+                new UidRangeParcel(userStart + PKG_UIDS[2] + 1, userStop)
         }));
     }
 
@@ -452,7 +469,7 @@
     public void testLockdownRuleRepeatability() throws Exception {
         final Vpn vpn = createVpn(primaryUser.id);
         final UidRangeParcel[] primaryUserRangeParcel = new UidRangeParcel[] {
-                new UidRangeParcel(PRI_USER_RANGE.start, PRI_USER_RANGE.stop)};
+                new UidRangeParcel(PRI_USER_RANGE.getLower(), PRI_USER_RANGE.getUpper())};
         // Given legacy lockdown is already enabled,
         vpn.setLockdown(true);
         verify(mConnectivityManager, times(1)).setRequireVpnForUids(true,
@@ -484,7 +501,7 @@
     public void testLockdownRuleReversibility() throws Exception {
         final Vpn vpn = createVpn(primaryUser.id);
         final UidRangeParcel[] entireUser = {
-            new UidRangeParcel(PRI_USER_RANGE.start, PRI_USER_RANGE.stop)
+            new UidRangeParcel(PRI_USER_RANGE.getLower(), PRI_USER_RANGE.getUpper())
         };
         final UidRangeParcel[] exceptPkg0 = {
             new UidRangeParcel(entireUser[0].start, entireUser[0].start + PKG_UIDS[0] - 1),
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index 814cad4..a9d5822 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -32,9 +32,8 @@
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyBoolean;
 import static org.mockito.Mockito.argThat;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
@@ -656,7 +655,7 @@
                     .setNetworkSpecifier(new TelephonyNetworkSpecifier(TEST_SUBSCRIPTION_ID));
         } else if (transport == TRANSPORT_WIFI) {
             WifiInfo wifiInfo = mock(WifiInfo.class);
-            when(wifiInfo.makeCopy(anyBoolean())).thenReturn(wifiInfo);
+            when(wifiInfo.makeCopy(anyLong())).thenReturn(wifiInfo);
             when(mMockDeps.getSubIdForWifiInfo(eq(wifiInfo))).thenReturn(TEST_SUBSCRIPTION_ID);
 
             ncBuilder