Merge ab/7061308 into stage.

Bug: 180401296
Merged-In: I35fe00aeeb112d5d9971985619e3ec5095dcdb7b
Change-Id: I07d008e38827280c9e9c6b7fa31393309f9de8a3
diff --git a/Android.bp b/Android.bp
index 03b4c36..866b706 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,3 +1,20 @@
+package {
+    default_applicable_licenses: ["packages_apps_Settings_license"],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+    name: "packages_apps_Settings_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+    ],
+    license_text: [
+        "NOTICE",
+    ],
+}
+
 java_library {
     name: "settings-logtags",
     srcs: ["src/**/*.logtags"],
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 9bf90c8..952e29b 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -207,6 +207,7 @@
                   android:label="@string/network_settings_title">
             <intent-filter android:priority="1">
                 <action android:name="android.settings.MOBILE_NETWORK_LIST" />
+                <action android:name="android.settings.MANAGE_ALL_SUBSCRIPTIONS_SETTINGS" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
diff --git a/protos/Android.bp b/protos/Android.bp
index 5184218..e09b941 100644
--- a/protos/Android.bp
+++ b/protos/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "packages_apps_Settings_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["packages_apps_Settings_license"],
+}
+
 java_library_static {
     name: "settings-contextual-card-protos-lite",
     host_supported: true,
@@ -14,4 +23,4 @@
         type: "lite",
     },
     srcs: ["settings_log_bridge.proto"],
-}
\ No newline at end of file
+}
diff --git a/res/layout/wifi_dpp_qrcode_generator_fragment.xml b/res/layout/wifi_dpp_qrcode_generator_fragment.xml
index 1f8b37c..756465a 100644
--- a/res/layout/wifi_dpp_qrcode_generator_fragment.xml
+++ b/res/layout/wifi_dpp_qrcode_generator_fragment.xml
@@ -42,6 +42,7 @@
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:gravity="center"
+            android:id="@+id/wifi_dpp_layout"
             android:orientation="vertical">
 
             <ImageView
@@ -54,8 +55,11 @@
                 android:id="@+id/password"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="16dp"
+                android:layout_marginBottom="24dp"
                 android:textAlignment="center"
+                android:textIsSelectable="true"
+                android:focusable="true"
+                android:longClickable="true"
                 android:textAppearance="@android:style/TextAppearance.Material.Body1"
                 android:textColor="?android:attr/textColorSecondary"/>
         </LinearLayout>
diff --git a/src/com/android/settings/ProxySelector.java b/src/com/android/settings/ProxySelector.java
index 625369e..a685841 100644
--- a/src/com/android/settings/ProxySelector.java
+++ b/src/com/android/settings/ProxySelector.java
@@ -23,7 +23,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.net.ConnectivityManager;
-import android.net.Proxy;
 import android.net.ProxyInfo;
 import android.os.Bundle;
 import android.text.Selection;
@@ -41,6 +40,7 @@
 
 import androidx.appcompat.app.AlertDialog;
 
+import com.android.net.module.util.ProxyUtils;
 import com.android.settings.SettingsPreferenceFragment.SettingsDialogFragment;
 import com.android.settings.core.InstrumentedFragment;
 
@@ -151,7 +151,7 @@
         if (proxy != null) {
             hostname = proxy.getHost();
             port = proxy.getPort();
-            exclList = proxy.getExclusionListAsString();
+            exclList = ProxyUtils.exclusionListAsString(proxy.getExclusionList());
         }
 
         if (hostname == null) {
@@ -185,18 +185,18 @@
      * @return 0 on success, string resource ID on failure
      */
     public static int validate(String hostname, String port, String exclList) {
-        switch (Proxy.validate(hostname, port, exclList)) {
-            case Proxy.PROXY_VALID:
+        switch (ProxyUtils.validate(hostname, port, exclList)) {
+            case ProxyUtils.PROXY_VALID:
                 return 0;
-            case Proxy.PROXY_HOSTNAME_EMPTY:
+            case ProxyUtils.PROXY_HOSTNAME_EMPTY:
                 return R.string.proxy_error_empty_host_set_port;
-            case Proxy.PROXY_HOSTNAME_INVALID:
+            case ProxyUtils.PROXY_HOSTNAME_INVALID:
                 return R.string.proxy_error_invalid_host;
-            case Proxy.PROXY_PORT_EMPTY:
+            case ProxyUtils.PROXY_PORT_EMPTY:
                 return R.string.proxy_error_empty_port;
-            case Proxy.PROXY_PORT_INVALID:
+            case ProxyUtils.PROXY_PORT_INVALID:
                 return R.string.proxy_error_invalid_port;
-            case Proxy.PROXY_EXCLLIST_INVALID:
+            case ProxyUtils.PROXY_EXCLLIST_INVALID:
                 return R.string.proxy_error_invalid_exclusion_list;
             default:
                 // should neven happen
diff --git a/src/com/android/settings/ResetNetworkConfirm.java b/src/com/android/settings/ResetNetworkConfirm.java
index 784ffa7..9ad860e 100644
--- a/src/com/android/settings/ResetNetworkConfirm.java
+++ b/src/com/android/settings/ResetNetworkConfirm.java
@@ -28,6 +28,7 @@
 import android.net.ConnectivityManager;
 import android.net.NetworkPolicyManager;
 import android.net.Uri;
+import android.net.VpnManager;
 import android.net.wifi.WifiManager;
 import android.net.wifi.p2p.WifiP2pManager;
 import android.os.AsyncTask;
@@ -94,6 +95,11 @@
                 connectivityManager.factoryReset();
             }
 
+            VpnManager vpnManager = mContext.getSystemService(VpnManager.class);
+            if (vpnManager != null) {
+                vpnManager.factoryReset();
+            }
+
             WifiManager wifiManager = (WifiManager)
                     mContext.getSystemService(Context.WIFI_SERVICE);
             if (wifiManager != null) {
diff --git a/src/com/android/settings/core/FeatureFlags.java b/src/com/android/settings/core/FeatureFlags.java
index d2ad30d..0ee3740 100644
--- a/src/com/android/settings/core/FeatureFlags.java
+++ b/src/com/android/settings/core/FeatureFlags.java
@@ -21,7 +21,6 @@
  */
 public class FeatureFlags {
     public static final String AUDIO_SWITCHER_SETTINGS = "settings_audio_switcher";
-    public static final String DYNAMIC_SYSTEM = "settings_dynamic_system";
     public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
     public static final String SETTINGS_FUSE_FLAG = "settings_fuse";
     public static final String WIFI_DETAILS_DATAUSAGE_HEADER =
diff --git a/src/com/android/settings/datausage/DataSaverBackend.java b/src/com/android/settings/datausage/DataSaverBackend.java
index 92b2ef9..e8087c4 100644
--- a/src/com/android/settings/datausage/DataSaverBackend.java
+++ b/src/com/android/settings/datausage/DataSaverBackend.java
@@ -200,7 +200,8 @@
         }
 
         @Override
-        public void onSubscriptionOverride(int subId, int overrideMask, int overrideValue) {
+        public void onSubscriptionOverride(int subId, int overrideMask, int overrideValue,
+                int[] networkTypes) {
         }
 
         @Override
diff --git a/src/com/android/settings/development/DSULoader.java b/src/com/android/settings/development/DSULoader.java
index 1c897c4..d4fa0c6 100644
--- a/src/com/android/settings/development/DSULoader.java
+++ b/src/com/android/settings/development/DSULoader.java
@@ -55,8 +55,6 @@
  * also offers the flexibility to overwrite the default setting and load OEMs owned images.
  */
 public class DSULoader extends ListActivity {
-    public static final String PROPERTY_KEY_FEATURE_FLAG =
-            "persist.sys.fflag.override.settings_dynamic_system";
     private static final int Q_VNDK_BASE = 28;
     private static final int Q_OS_BASE = 10;
 
@@ -344,7 +342,6 @@
     @Override
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
-        SystemProperties.set(PROPERTY_KEY_FEATURE_FLAG, "1");
         String dsuList = SystemProperties.get(PROPERTY_KEY_LIST);
         Slog.e(TAG, "Try to get DSU list from: " + PROPERTY_KEY_LIST);
         if (dsuList == null || dsuList.isEmpty()) {
diff --git a/src/com/android/settings/development/WirelessDebuggingPreferenceController.java b/src/com/android/settings/development/WirelessDebuggingPreferenceController.java
index a3daede..c17803d 100644
--- a/src/com/android/settings/development/WirelessDebuggingPreferenceController.java
+++ b/src/com/android/settings/development/WirelessDebuggingPreferenceController.java
@@ -20,7 +20,8 @@
 import android.database.ContentObserver;
 import android.debug.IAdbManager;
 import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
+import android.net.Network;
+import android.net.NetworkCapabilities;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Looper;
@@ -141,10 +142,16 @@
     public static boolean isWifiConnected(Context context) {
         ConnectivityManager cm = (ConnectivityManager) context.getSystemService(
                 Context.CONNECTIVITY_SERVICE);
-        if (cm != null) {
-            NetworkInfo info = cm.getActiveNetworkInfo();
-            if (info != null && info.isConnected()) {
-                return info.getType() == ConnectivityManager.TYPE_WIFI;
+        if (cm == null) {
+            return false;
+        }
+        for (Network network : cm.getAllNetworks()) {
+            final NetworkCapabilities nc = cm.getNetworkCapabilities(network);
+            if (nc == null) {
+                continue;
+            }
+            if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
+                return true;
             }
         }
         return false;
diff --git a/src/com/android/settings/development/featureflags/FeatureFlagPersistent.java b/src/com/android/settings/development/featureflags/FeatureFlagPersistent.java
index fb84a72..c2ef0f5 100644
--- a/src/com/android/settings/development/featureflags/FeatureFlagPersistent.java
+++ b/src/com/android/settings/development/featureflags/FeatureFlagPersistent.java
@@ -35,7 +35,6 @@
     static {
         PERSISTENT_FLAGS = new HashSet<>();
         PERSISTENT_FLAGS.add(FeatureFlags.HEARING_AID_SETTINGS);
-        PERSISTENT_FLAGS.add(FeatureFlags.DYNAMIC_SYSTEM);
         PERSISTENT_FLAGS.add(FeatureFlags.SETTINGS_FUSE_FLAG);
     }
 
diff --git a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java
index 46f9b71..22fe760 100644
--- a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java
+++ b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java
@@ -85,11 +85,6 @@
     boolean isAlwaysOnVpnSetInManagedProfile();
 
     /**
-     * Returns whether the Device Owner set a recommended global HTTP proxy.
-     */
-    boolean isGlobalHttpProxySet();
-
-    /**
      * Returns the number of failed login attempts that the Device Owner or Profile Owner allows
      * before the current user is wiped, or zero if no such limit is set.
      */
diff --git a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java
index 429c537..ad57c3c 100644
--- a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java
+++ b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java
@@ -25,6 +25,7 @@
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.net.ConnectivityManager;
+import android.net.VpnManager;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
@@ -45,18 +46,20 @@
     private final PackageManager mPm;
     private final UserManager mUm;
     private final ConnectivityManager mCm;
+    private final VpnManager mVm;
     private final Resources mResources;
 
     private static final int MY_USER_ID = UserHandle.myUserId();
 
     public EnterprisePrivacyFeatureProviderImpl(Context context, DevicePolicyManager dpm,
-            PackageManager pm, UserManager um, ConnectivityManager cm,
+            PackageManager pm, UserManager um, ConnectivityManager cm, VpnManager vm,
             Resources resources) {
         mContext = context.getApplicationContext();
         mDpm = dpm;
         mPm = pm;
         mUm = um;
         mCm = cm;
+        mVm = vm;
         mResources = resources;
     }
 
@@ -130,19 +133,14 @@
 
     @Override
     public boolean isAlwaysOnVpnSetInCurrentUser() {
-        return VpnUtils.isAlwaysOnVpnSet(mCm, MY_USER_ID);
+        return VpnUtils.isAlwaysOnVpnSet(mVm, MY_USER_ID);
     }
 
     @Override
     public boolean isAlwaysOnVpnSetInManagedProfile() {
         final int managedProfileUserId = getManagedProfileUserId();
         return managedProfileUserId != UserHandle.USER_NULL &&
-                VpnUtils.isAlwaysOnVpnSet(mCm, managedProfileUserId);
-    }
-
-    @Override
-    public boolean isGlobalHttpProxySet() {
-        return mCm.getGlobalProxy() != null;
+                VpnUtils.isAlwaysOnVpnSet(mVm, managedProfileUserId);
     }
 
     @Override
diff --git a/src/com/android/settings/enterprise/GlobalHttpProxyPreferenceController.java b/src/com/android/settings/enterprise/GlobalHttpProxyPreferenceController.java
index 04e63aa..6de6cde 100644
--- a/src/com/android/settings/enterprise/GlobalHttpProxyPreferenceController.java
+++ b/src/com/android/settings/enterprise/GlobalHttpProxyPreferenceController.java
@@ -14,26 +14,25 @@
 package com.android.settings.enterprise;
 
 import android.content.Context;
+import android.net.ConnectivityManager;
 
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.AbstractPreferenceController;
 
 public class GlobalHttpProxyPreferenceController extends AbstractPreferenceController implements
         PreferenceControllerMixin {
 
     private static final String KEY_GLOBAL_HTTP_PROXY = "global_http_proxy";
-    private final EnterprisePrivacyFeatureProvider mFeatureProvider;
+    private final ConnectivityManager mCm;
 
     public GlobalHttpProxyPreferenceController(Context context) {
         super(context);
-        mFeatureProvider = FeatureFactory.getFactory(context)
-                .getEnterprisePrivacyFeatureProvider(context);
+        mCm = context.getSystemService(ConnectivityManager.class);
     }
 
     @Override
     public boolean isAvailable() {
-        return mFeatureProvider.isGlobalHttpProxySet();
+        return mCm.getGlobalProxy() != null;
     }
 
     @Override
diff --git a/src/com/android/settings/fuelgauge/OWNERS b/src/com/android/settings/fuelgauge/OWNERS
index 4e5ee0e..237d353 100644
--- a/src/com/android/settings/fuelgauge/OWNERS
+++ b/src/com/android/settings/fuelgauge/OWNERS
@@ -1,3 +1,4 @@
 # Default reviewers for this and subdirectories.
-millchen@google.com
-tmfang@google.com
+tifn@google.com
+wesleycwwang@google.com
+ykhung@google.com
\ No newline at end of file
diff --git a/src/com/android/settings/homepage/contextualcards/ControllerRendererPool.java b/src/com/android/settings/homepage/contextualcards/ControllerRendererPool.java
index 755a105..f556018 100644
--- a/src/com/android/settings/homepage/contextualcards/ControllerRendererPool.java
+++ b/src/com/android/settings/homepage/contextualcards/ControllerRendererPool.java
@@ -56,7 +56,7 @@
         final Class<? extends ContextualCardController> clz =
                 ContextualCardLookupTable.getCardControllerClass(cardType);
         for (ContextualCardController controller : mControllers) {
-            if (controller.getClass() == clz) {
+            if (controller.getClass().getName().equals(clz.getName())) {
                 Log.d(TAG, "Controller is already there.");
                 return (T) controller;
             }
diff --git a/src/com/android/settings/network/OWNERS b/src/com/android/settings/network/OWNERS
index 991ad43..4f17e3f 100644
--- a/src/com/android/settings/network/OWNERS
+++ b/src/com/android/settings/network/OWNERS
@@ -6,5 +6,6 @@
 leechou@google.com
 songferngwang@google.com
 tomhsu@google.com
+zoeychen@google.com
 
 # Emergency approvers in case the above are not available
diff --git a/src/com/android/settings/network/VpnPreferenceController.java b/src/com/android/settings/network/VpnPreferenceController.java
index 62589d5..9295414 100644
--- a/src/com/android/settings/network/VpnPreferenceController.java
+++ b/src/com/android/settings/network/VpnPreferenceController.java
@@ -19,12 +19,10 @@
 import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
 import android.net.ConnectivityManager;
-import android.net.IConnectivityManager;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
-import android.os.RemoteException;
-import android.os.ServiceManager;
+import android.net.VpnManager;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
@@ -64,7 +62,7 @@
     private final String mToggleable;
     private final UserManager mUserManager;
     private final ConnectivityManager mConnectivityManager;
-    private final IConnectivityManager mConnectivityManagerService;
+    private final VpnManager mVpnManager;
     private Preference mPreference;
 
     public VpnPreferenceController(Context context) {
@@ -74,8 +72,7 @@
         mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
         mConnectivityManager =
                 (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
-        mConnectivityManagerService = IConnectivityManager.Stub.asInterface(
-                ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
+        mVpnManager = context.getSystemService(VpnManager.class);
     }
 
     @Override
@@ -122,27 +119,20 @@
         }
         // Copied from SystemUI::SecurityControllerImpl
         SparseArray<VpnConfig> vpns = new SparseArray<>();
-        try {
-            final List<UserInfo> users = mUserManager.getUsers();
-            for (UserInfo user : users) {
-                VpnConfig cfg = mConnectivityManagerService.getVpnConfig(user.id);
-                if (cfg == null) {
+        final List<UserInfo> users = mUserManager.getUsers();
+        for (UserInfo user : users) {
+            VpnConfig cfg = mVpnManager.getVpnConfig(user.id);
+            if (cfg == null) {
+                continue;
+            } else if (cfg.legacy) {
+                // Legacy VPNs should do nothing if the network is disconnected. Third-party
+                // VPN warnings need to continue as traffic can still go to the app.
+                final LegacyVpnInfo legacyVpn = mVpnManager.getLegacyVpnInfo(user.id);
+                if (legacyVpn == null || legacyVpn.state != LegacyVpnInfo.STATE_CONNECTED) {
                     continue;
-                } else if (cfg.legacy) {
-                    // Legacy VPNs should do nothing if the network is disconnected. Third-party
-                    // VPN warnings need to continue as traffic can still go to the app.
-                    final LegacyVpnInfo legacyVpn =
-                            mConnectivityManagerService.getLegacyVpnInfo(user.id);
-                    if (legacyVpn == null || legacyVpn.state != LegacyVpnInfo.STATE_CONNECTED) {
-                        continue;
-                    }
                 }
-                vpns.put(user.id, cfg);
             }
-        } catch (RemoteException rme) {
-            // Roll back to previous state
-            Log.e(TAG, "Unable to list active VPNs", rme);
-            return;
+            vpns.put(user.id, cfg);
         }
         final UserInfo userInfo = mUserManager.getUserInfo(UserHandle.myUserId());
         final int uid;
diff --git a/src/com/android/settings/network/telephony/NetworkSelectSettings.java b/src/com/android/settings/network/telephony/NetworkSelectSettings.java
index ff641e9..c8121c4 100644
--- a/src/com/android/settings/network/telephony/NetworkSelectSettings.java
+++ b/src/com/android/settings/network/telephony/NetworkSelectSettings.java
@@ -343,16 +343,6 @@
                     mPreferenceCategory.getPreference(numberOfPreferences));
         }
 
-        // update selected preference instance by index
-        for (int index = 0; index < mCellInfoList.size(); index++) {
-            final CellInfo cellInfo = mCellInfoList.get(index);
-
-            if ((mSelectedPreference != null) && mSelectedPreference.isSameCell(cellInfo)) {
-                mSelectedPreference = (NetworkOperatorPreference)
-                        (mPreferenceCategory.getPreference(index));
-            }
-        }
-
         // update the content of preference
         NetworkOperatorPreference connectedPref = null;
         for (int index = 0; index < mCellInfoList.size(); index++) {
@@ -386,6 +376,16 @@
             }
         }
 
+        // update selected preference instance by index
+        for (int index = 0; index < mCellInfoList.size(); index++) {
+            final CellInfo cellInfo = mCellInfoList.get(index);
+
+            if ((mSelectedPreference != null) && mSelectedPreference.isSameCell(cellInfo)) {
+                mSelectedPreference = (NetworkOperatorPreference)
+                        (mPreferenceCategory.getPreference(index));
+            }
+        }
+
         return connectedPref;
     }
 
diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java
index d4d396f..41bfb21 100644
--- a/src/com/android/settings/overlay/FeatureFactoryImpl.java
+++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java
@@ -20,6 +20,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.net.ConnectivityManager;
+import android.net.VpnManager;
 import android.os.UserManager;
 
 import androidx.annotation.Keep;
@@ -169,7 +170,8 @@
                             Context.DEVICE_POLICY_SERVICE),
                     appContext.getPackageManager(),
                     UserManager.get(appContext),
-                    (ConnectivityManager) appContext.getSystemService(Context.CONNECTIVITY_SERVICE),
+                    appContext.getSystemService(ConnectivityManager.class),
+                    appContext.getSystemService(VpnManager.class),
                     appContext.getResources());
         }
         return mEnterprisePrivacyFeatureProvider;
diff --git a/src/com/android/settings/vpn2/AppDialogFragment.java b/src/com/android/settings/vpn2/AppDialogFragment.java
index ea9e546..626a271 100644
--- a/src/com/android/settings/vpn2/AppDialogFragment.java
+++ b/src/com/android/settings/vpn2/AppDialogFragment.java
@@ -18,17 +18,12 @@
 
 import android.app.Dialog;
 import android.app.settings.SettingsEnums;
-import android.content.Context;
 import android.content.DialogInterface;
 import android.content.pm.PackageInfo;
-import android.net.IConnectivityManager;
 import android.net.VpnManager;
 import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.util.Log;
 
 import androidx.appcompat.app.AlertDialog;
 import androidx.fragment.app.Fragment;
@@ -53,8 +48,7 @@
     private Listener mListener;
 
     private UserManager mUserManager;
-    private final IConnectivityManager mService = IConnectivityManager.Stub.asInterface(
-            ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
+    private VpnManager mVpnManager;
 
     @Override
     public int getMetricsCategory() {
@@ -98,6 +92,7 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         mUserManager = UserManager.get(getContext());
+        mVpnManager = getContext().getSystemService(VpnManager.class);
     }
 
     @Override
@@ -145,14 +140,9 @@
             return;
         }
         final int userId = getUserId();
-        try {
-            mService.setVpnPackageAuthorization(
-                    mPackageInfo.packageName, userId, VpnManager.TYPE_VPN_NONE);
-            onDisconnect(dialog);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to forget authorization of " + mPackageInfo.packageName +
-                    " for user " + userId, e);
-        }
+        mVpnManager.setVpnPackageAuthorization(
+                mPackageInfo.packageName, userId, VpnManager.TYPE_VPN_NONE);
+        onDisconnect(dialog);
 
         if (mListener != null) {
             mListener.onForget();
@@ -164,15 +154,10 @@
             return;
         }
         final int userId = getUserId();
-        try {
-            if (mPackageInfo.packageName.equals(VpnUtils.getConnectedPackage(mService, userId))) {
-                mService.setAlwaysOnVpnPackage(userId, null, /* lockdownEnabled */ false,
-                        /* lockdownWhitelist */ null);
-                mService.prepareVpn(mPackageInfo.packageName, VpnConfig.LEGACY_VPN, userId);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to disconnect package " + mPackageInfo.packageName +
-                    " for user " + userId, e);
+        if (mPackageInfo.packageName.equals(VpnUtils.getConnectedPackage(mVpnManager, userId))) {
+            mVpnManager.setAlwaysOnVpnPackageForUser(userId, null, /* lockdownEnabled */ false,
+                    /* lockdownAllowlist */ null);
+            mVpnManager.prepareVpn(mPackageInfo.packageName, VpnConfig.LEGACY_VPN, userId);
         }
     }
 
diff --git a/src/com/android/settings/vpn2/AppManagementFragment.java b/src/com/android/settings/vpn2/AppManagementFragment.java
index 8280a3d..0543fee 100644
--- a/src/com/android/settings/vpn2/AppManagementFragment.java
+++ b/src/com/android/settings/vpn2/AppManagementFragment.java
@@ -28,11 +28,8 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.net.ConnectivityManager;
-import android.net.IConnectivityManager;
+import android.net.VpnManager;
 import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.text.TextUtils;
@@ -71,8 +68,7 @@
 
     private PackageManager mPackageManager;
     private DevicePolicyManager mDevicePolicyManager;
-    private ConnectivityManager mConnectivityManager;
-    private IConnectivityManager mConnectivityService;
+    private VpnManager mVpnManager;
 
     // VPN app info
     private final int mUserId = UserHandle.myUserId();
@@ -124,9 +120,7 @@
 
         mPackageManager = getContext().getPackageManager();
         mDevicePolicyManager = getContext().getSystemService(DevicePolicyManager.class);
-        mConnectivityManager = getContext().getSystemService(ConnectivityManager.class);
-        mConnectivityService = IConnectivityManager.Stub
-                .asInterface(ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
+        mVpnManager = getContext().getSystemService(VpnManager.class);
 
         mPreferenceVersion = findPreference(KEY_VERSION);
         mPreferenceAlwaysOn = (RestrictedSwitchPreference) findPreference(KEY_ALWAYS_ON_VPN);
@@ -230,8 +224,8 @@
     }
 
     private boolean setAlwaysOnVpn(boolean isEnabled, boolean isLockdown) {
-        return mConnectivityManager.setAlwaysOnVpnPackageForUser(mUserId,
-                isEnabled ? mPackageName : null, isLockdown, /* lockdownWhitelist */ null);
+        return mVpnManager.setAlwaysOnVpnPackageForUser(mUserId,
+                isEnabled ? mPackageName : null, isLockdown, /* lockdownAllowlist */ null);
     }
 
     private void updateUI() {
@@ -264,7 +258,7 @@
                     mPreferenceLockdown.setDisabledByAdmin(admin);
                 }
             }
-            if (mConnectivityManager.isAlwaysOnVpnPackageSupportedForUser(mUserId, mPackageName)) {
+            if (mVpnManager.isAlwaysOnVpnPackageSupportedForUser(mUserId, mPackageName)) {
                 // setSummary doesn't override the admin message when user restriction is applied
                 mPreferenceAlwaysOn.setSummary(R.string.vpn_always_on_summary);
                 // setEnabled is not required here, as checkRestrictionAndSetDisabled
@@ -278,7 +272,7 @@
     }
 
     private String getAlwaysOnVpnPackage() {
-        return mConnectivityManager.getAlwaysOnVpnPackageForUser(mUserId);
+        return mVpnManager.getAlwaysOnVpnPackageForUser(mUserId);
     }
 
     private boolean isVpnAlwaysOn() {
@@ -335,13 +329,8 @@
      * @return {@code true} if another VPN (VpnService or legacy) is connected or set as always-on.
      */
     private boolean isAnotherVpnActive() {
-        try {
-            final VpnConfig config = mConnectivityService.getVpnConfig(mUserId);
-            return config != null && !TextUtils.equals(config.user, mPackageName);
-        } catch (RemoteException e) {
-            Log.w(TAG, "Failure to look up active VPN", e);
-            return false;
-        }
+        final VpnConfig config = mVpnManager.getVpnConfig(mUserId);
+        return config != null && !TextUtils.equals(config.user, mPackageName);
     }
 
     public static class CannotConnectFragment extends InstrumentedDialogFragment {
diff --git a/src/com/android/settings/vpn2/ConfigDialog.java b/src/com/android/settings/vpn2/ConfigDialog.java
index 26c1565..a0c7a1e 100644
--- a/src/com/android/settings/vpn2/ConfigDialog.java
+++ b/src/com/android/settings/vpn2/ConfigDialog.java
@@ -21,7 +21,6 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.pm.PackageManager;
-import android.net.Proxy;
 import android.net.ProxyInfo;
 import android.os.Bundle;
 import android.os.SystemProperties;
@@ -41,6 +40,7 @@
 import androidx.appcompat.app.AlertDialog;
 
 import com.android.internal.net.VpnProfile;
+import com.android.net.module.util.ProxyUtils;
 import com.android.settings.R;
 
 import java.net.InetAddress;
@@ -637,7 +637,7 @@
 
         final String host = mProxyHost.getText().toString().trim();
         final String port = mProxyPort.getText().toString().trim();
-        return Proxy.validate(host, port, "") == Proxy.PROXY_VALID;
+        return ProxyUtils.validate(host, port, "") == ProxyUtils.PROXY_VALID;
     }
 
 }
diff --git a/src/com/android/settings/vpn2/ConfigDialogFragment.java b/src/com/android/settings/vpn2/ConfigDialogFragment.java
index 57ba8bf..f339a69 100644
--- a/src/com/android/settings/vpn2/ConfigDialogFragment.java
+++ b/src/com/android/settings/vpn2/ConfigDialogFragment.java
@@ -20,11 +20,9 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.DialogInterface;
-import android.net.ConnectivityManager;
-import android.net.IConnectivityManager;
+import android.net.VpnManager;
 import android.os.Bundle;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.security.Credentials;
 import android.security.KeyStore;
@@ -52,9 +50,8 @@
     private static final String ARG_EDITING = "editing";
     private static final String ARG_EXISTS = "exists";
 
-    private final IConnectivityManager mService = IConnectivityManager.Stub.asInterface(
-            ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
     private Context mContext;
+    private VpnManager mService;
 
 
     @Override
@@ -80,6 +77,7 @@
     public void onAttach(final Context context) {
         super.onAttach(context);
         mContext = context;
+        mService = context.getSystemService(VpnManager.class);
     }
 
     @Override
@@ -178,9 +176,8 @@
                 return;
             }
 
-            final ConnectivityManager conn = ConnectivityManager.from(mContext);
-            conn.setAlwaysOnVpnPackageForUser(UserHandle.myUserId(), null,
-                    /* lockdownEnabled */ false, /* lockdownWhitelist */ null);
+            mService.setAlwaysOnVpnPackageForUser(UserHandle.myUserId(), null,
+                    /* lockdownEnabled */ false, /* lockdownAllowlist */ null);
             VpnUtils.setLockdownVpn(mContext, profile.key);
         } else {
             // update only if lockdown vpn has been changed
@@ -212,8 +209,6 @@
                 mService.startLegacyVpn(profile);
             } catch (IllegalStateException e) {
                 Toast.makeText(mContext, R.string.vpn_no_network, Toast.LENGTH_LONG).show();
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to connect", e);
             }
         }
     }
diff --git a/src/com/android/settings/vpn2/VpnSettings.java b/src/com/android/settings/vpn2/VpnSettings.java
index 8a2b465..0a3b2b0 100644
--- a/src/com/android/settings/vpn2/VpnSettings.java
+++ b/src/com/android/settings/vpn2/VpnSettings.java
@@ -30,16 +30,14 @@
 import android.content.pm.PackageManager;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
-import android.net.IConnectivityManager;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
+import android.net.VpnManager;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Message;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.security.Credentials;
@@ -92,10 +90,9 @@
             .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
             .build();
 
-    private final IConnectivityManager mConnectivityService = IConnectivityManager.Stub
-            .asInterface(ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
     private ConnectivityManager mConnectivityManager;
     private UserManager mUserManager;
+    private VpnManager mVpnManager;
 
     private final KeyStore mKeyStore = KeyStore.getInstance();
 
@@ -124,6 +121,7 @@
 
         mUserManager = (UserManager) getSystemService(Context.USER_SERVICE);
         mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
+        mVpnManager = (VpnManager) getSystemService(Context.VPN_MANAGEMENT_SERVICE);
 
         mUnavailable = isUiRestricted();
         setHasOptionsMenu(!mUnavailable);
@@ -467,13 +465,9 @@
 
     @WorkerThread
     private Map<String, LegacyVpnInfo> getConnectedLegacyVpns() {
-        try {
-            mConnectedLegacyVpn = mConnectivityService.getLegacyVpnInfo(UserHandle.myUserId());
-            if (mConnectedLegacyVpn != null) {
-                return Collections.singletonMap(mConnectedLegacyVpn.key, mConnectedLegacyVpn);
-            }
-        } catch (RemoteException e) {
-            Log.e(LOG_TAG, "Failure updating VPN list with connected legacy VPNs", e);
+        mConnectedLegacyVpn = mVpnManager.getLegacyVpnInfo(UserHandle.myUserId());
+        if (mConnectedLegacyVpn != null) {
+            return Collections.singletonMap(mConnectedLegacyVpn.key, mConnectedLegacyVpn);
         }
         return Collections.emptyMap();
     }
@@ -482,15 +476,11 @@
     private Set<AppVpnInfo> getConnectedAppVpns() {
         // Mark connected third-party services
         Set<AppVpnInfo> connections = new ArraySet<>();
-        try {
-            for (UserHandle profile : mUserManager.getUserProfiles()) {
-                VpnConfig config = mConnectivityService.getVpnConfig(profile.getIdentifier());
-                if (config != null && !config.legacy) {
-                    connections.add(new AppVpnInfo(profile.getIdentifier(), config.user));
-                }
+        for (UserHandle profile : mUserManager.getUserProfiles()) {
+            VpnConfig config = mVpnManager.getVpnConfig(profile.getIdentifier());
+            if (config != null && !config.legacy) {
+                connections.add(new AppVpnInfo(profile.getIdentifier(), config.user));
             }
-        } catch (RemoteException e) {
-            Log.e(LOG_TAG, "Failure updating VPN list with connected app VPNs", e);
         }
         return connections;
     }
@@ -500,7 +490,7 @@
         Set<AppVpnInfo> result = new ArraySet<>();
         for (UserHandle profile : mUserManager.getUserProfiles()) {
             final int profileId = profile.getIdentifier();
-            final String packageName = mConnectivityManager.getAlwaysOnVpnPackageForUser(profileId);
+            final String packageName = mVpnManager.getAlwaysOnVpnPackageForUser(profileId);
             if (packageName != null) {
                 result.add(new AppVpnInfo(profileId, packageName));
             }
diff --git a/src/com/android/settings/vpn2/VpnUtils.java b/src/com/android/settings/vpn2/VpnUtils.java
index 38c56c5..4c9338c 100644
--- a/src/com/android/settings/vpn2/VpnUtils.java
+++ b/src/com/android/settings/vpn2/VpnUtils.java
@@ -16,14 +16,11 @@
 package com.android.settings.vpn2;
 
 import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.IConnectivityManager;
+import android.net.VpnManager;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.provider.Settings;
 import android.security.Credentials;
 import android.security.KeyStore;
-import android.util.Log;
 
 import com.android.internal.net.LegacyVpnInfo;
 import com.android.internal.net.VpnConfig;
@@ -45,15 +42,15 @@
 
     public static void clearLockdownVpn(Context context) {
         KeyStore.getInstance().delete(Credentials.LOCKDOWN_VPN);
-        // Always notify ConnectivityManager after keystore update
-        getConnectivityManager(context).updateLockdownVpn();
+        // Always notify VpnManager after keystore update
+        getVpnManager(context).updateLockdownVpn();
     }
 
     public static void setLockdownVpn(Context context, String lockdownKey) {
         KeyStore.getInstance().put(Credentials.LOCKDOWN_VPN, lockdownKey.getBytes(),
                 KeyStore.UID_SELF, /* flags */ 0);
-        // Always notify ConnectivityManager after keystore update
-        getConnectivityManager(context).updateLockdownVpn();
+        // Always notify VpnManager after keystore update
+        getVpnManager(context).updateLockdownVpn();
     }
 
     public static boolean isVpnLockdown(String key) {
@@ -65,46 +62,35 @@
         if (getLockdownVpn() != null) {
             return true;
         }
-        return getConnectivityManager(context).getAlwaysOnVpnPackageForUser(userId) != null
+        return getVpnManager(context).getAlwaysOnVpnPackageForUser(userId) != null
                 && Settings.Secure.getIntForUser(context.getContentResolver(),
                         Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN, /* default */ 0, userId) != 0;
     }
 
     public static boolean isVpnActive(Context context) throws RemoteException {
-        return getIConnectivityManager().getVpnConfig(context.getUserId()) != null;
+        return getVpnManager(context).getVpnConfig(context.getUserId()) != null;
     }
 
-    public static String getConnectedPackage(IConnectivityManager service, final int userId)
-            throws RemoteException {
-        final VpnConfig config = service.getVpnConfig(userId);
+    public static String getConnectedPackage(VpnManager vpnManager, final int userId) {
+        final VpnConfig config = vpnManager.getVpnConfig(userId);
         return config != null ? config.user : null;
     }
 
-    private static ConnectivityManager getConnectivityManager(Context context) {
-        return context.getSystemService(ConnectivityManager.class);
+    private static VpnManager getVpnManager(Context context) {
+        return context.getSystemService(VpnManager.class);
     }
 
-    private static IConnectivityManager getIConnectivityManager() {
-        return IConnectivityManager.Stub.asInterface(
-                ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
-    }
-
-    public static boolean isAlwaysOnVpnSet(ConnectivityManager cm, final int userId) {
-        return cm.getAlwaysOnVpnPackageForUser(userId) != null;
+    public static boolean isAlwaysOnVpnSet(VpnManager vm, final int userId) {
+        return vm.getAlwaysOnVpnPackageForUser(userId) != null;
     }
 
     public static boolean disconnectLegacyVpn(Context context) {
-        try {
-            int userId = context.getUserId();
-            IConnectivityManager connectivityService = getIConnectivityManager();
-            LegacyVpnInfo currentLegacyVpn = connectivityService.getLegacyVpnInfo(userId);
-            if (currentLegacyVpn != null) {
-                clearLockdownVpn(context);
-                connectivityService.prepareVpn(null, VpnConfig.LEGACY_VPN, userId);
-                return true;
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Legacy VPN could not be disconnected", e);
+        int userId = context.getUserId();
+        LegacyVpnInfo currentLegacyVpn = getVpnManager(context).getLegacyVpnInfo(userId);
+        if (currentLegacyVpn != null) {
+            clearLockdownVpn(context);
+            getVpnManager(context).prepareVpn(null, VpnConfig.LEGACY_VPN, userId);
+            return true;
         }
         return false;
     }
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index 07d270d..29e4fb7 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -69,6 +69,7 @@
 
 import androidx.annotation.VisibleForTesting;
 
+import com.android.net.module.util.ProxyUtils;
 import com.android.settings.ProxySelector;
 import com.android.settings.R;
 import com.android.settings.wifi.details.WifiPrivacyPreferenceController;
@@ -1428,7 +1429,8 @@
                 if (proxyProperties != null) {
                     mProxyHostView.setText(proxyProperties.getHost());
                     mProxyPortView.setText(Integer.toString(proxyProperties.getPort()));
-                    mProxyExclusionListView.setText(proxyProperties.getExclusionListAsString());
+                    mProxyExclusionListView.setText(
+                            ProxyUtils.exclusionListAsString(proxyProperties.getExclusionList()));
                 }
             }
         } else if (mProxySettingsSpinner.getSelectedItemPosition() == PROXY_PAC) {
diff --git a/src/com/android/settings/wifi/WifiConfigController2.java b/src/com/android/settings/wifi/WifiConfigController2.java
index a177f1a..b0e4447 100644
--- a/src/com/android/settings/wifi/WifiConfigController2.java
+++ b/src/com/android/settings/wifi/WifiConfigController2.java
@@ -67,6 +67,7 @@
 
 import androidx.annotation.VisibleForTesting;
 
+import com.android.net.module.util.ProxyUtils;
 import com.android.settings.ProxySelector;
 import com.android.settings.R;
 import com.android.settings.wifi.details.WifiPrivacyPreferenceController;
@@ -1412,7 +1413,8 @@
                 if (proxyProperties != null) {
                     mProxyHostView.setText(proxyProperties.getHost());
                     mProxyPortView.setText(Integer.toString(proxyProperties.getPort()));
-                    mProxyExclusionListView.setText(proxyProperties.getExclusionListAsString());
+                    mProxyExclusionListView.setText(
+                            ProxyUtils.exclusionListAsString(proxyProperties.getExclusionList()));
                 }
             }
         } else if (mProxySettingsSpinner.getSelectedItemPosition() == PROXY_PAC) {
diff --git a/src/com/android/settings/wifi/WifiSettings2.java b/src/com/android/settings/wifi/WifiSettings2.java
index 79f48fb..8fbe293 100644
--- a/src/com/android/settings/wifi/WifiSettings2.java
+++ b/src/com/android/settings/wifi/WifiSettings2.java
@@ -103,6 +103,7 @@
     @VisibleForTesting
     static final int MENU_ID_FORGET = Menu.FIRST + 3;
     static final int MENU_ID_MODIFY = Menu.FIRST + 4;
+    static final int MENU_ID_SHARE = Menu.FIRST + 5;
 
     // Max age of tracked WifiEntries
     private static final long MAX_SCAN_AGE_MILLIS = 15_000;
@@ -485,7 +486,8 @@
         }
 
         if (mSelectedWifiEntry.canDisconnect()) {
-            menu.add(Menu.NONE, MENU_ID_DISCONNECT, 0 /* order */,
+            menu.add(Menu.NONE, MENU_ID_SHARE, 0 /* order */, R.string.share);
+            menu.add(Menu.NONE, MENU_ID_DISCONNECT, 1 /* order */,
                     R.string.wifi_disconnect_button_text);
         }
 
@@ -524,6 +526,10 @@
             case MENU_ID_FORGET:
                 forget(mSelectedWifiEntry);
                 return true;
+            case MENU_ID_SHARE:
+                WifiDppUtils.showLockScreen(getContext(),
+                        () -> launchWifiDppConfiguratorActivity(mSelectedWifiEntry));
+                return true;
             case MENU_ID_MODIFY:
                 showDialog(mSelectedWifiEntry, WifiConfigUiBase2.MODE_MODIFY);
                 return true;
@@ -558,6 +564,23 @@
         return true;
     }
 
+    private void launchWifiDppConfiguratorActivity(WifiEntry wifiEntry) {
+        final Intent intent = WifiDppUtils.getConfiguratorQrCodeGeneratorIntentOrNull(getContext(),
+                mWifiManager, wifiEntry);
+
+        if (intent == null) {
+            Log.e(TAG, "Launch Wi-Fi DPP QR code generator with a wrong Wi-Fi network!");
+        } else {
+            mMetricsFeatureProvider.action(SettingsEnums.PAGE_UNKNOWN,
+                    SettingsEnums.ACTION_SETTINGS_SHARE_WIFI_QR_CODE,
+                    SettingsEnums.SETTINGS_WIFI_DPP_CONFIGURATOR,
+                    /* key */ null,
+                    /* value */ Integer.MIN_VALUE);
+
+            startActivity(intent);
+        }
+    }
+
     private void showDialog(WifiEntry wifiEntry, int dialogMode) {
         if (WifiUtils.isNetworkLockedDown(getActivity(), wifiEntry.getWifiConfiguration())
                 && wifiEntry.getConnectedState() == WifiEntry.CONNECTED_STATE_CONNECTED) {
@@ -698,8 +721,8 @@
      */
     private void updateWifiEntryPreferencesDelayed() {
         // Safeguard from some delayed event handling
-        if (getActivity() != null && !mIsRestricted &&
-                mWifiPickerTracker.getWifiState() == WifiManager.WIFI_STATE_ENABLED) {
+        if (getActivity() != null && !mIsRestricted
+                && mWifiPickerTracker.getWifiState() == WifiManager.WIFI_STATE_ENABLED) {
             final View view = getView();
             final Handler handler = view.getHandler();
             if (handler != null && handler.hasCallbacks(mUpdateWifiEntryPreferencesRunnable)) {
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java
index 603ea10..2ec960e 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java
@@ -16,9 +16,17 @@
 
 package com.android.settings.wifi.dpp;
 
+import android.annotation.Nullable;
 import android.app.settings.SettingsEnums;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
 import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
 import android.os.Bundle;
+import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.LayoutInflater;
@@ -27,9 +35,13 @@
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.app.chooser.DisplayResolveInfo;
+import com.android.internal.app.chooser.TargetInfo;
 import com.android.settings.R;
 import com.android.settings.wifi.qrcode.QrCodeGenerator;
 
@@ -45,6 +57,15 @@
     private ImageView mQrCodeView;
     private String mQrCode;
 
+    private static final String CHIP_LABEL_METADATA_KEY = "android.service.chooser.chip_label";
+    private static final String CHIP_ICON_METADATA_KEY = "android.service.chooser.chip_icon";
+    private static final String EXTRA_WIFI_CREDENTIALS_BUNDLE =
+            "android.intent.extra.WIFI_CREDENTIALS_BUNDLE";
+    private static final String EXTRA_SSID = "android.intent.extra.SSID";
+    private static final String EXTRA_PASSWORD = "android.intent.extra.PASSWORD";
+    private static final String EXTRA_SECURITY_TYPE = "android.intent.extra.SECURITY_TYPE";
+    private static final String EXTRA_HIDDEN_SSID = "android.intent.extra.HIDDEN_SSID";
+
     @Override
     public int getMetricsCategory() {
         return SettingsEnums.SETTINGS_WIFI_DPP_CONFIGURATOR;
@@ -56,10 +77,12 @@
 
         // setTitle for TalkBack
         final WifiNetworkConfig wifiNetworkConfig = getWifiNetworkConfigFromHostActivity();
-        if (wifiNetworkConfig.isHotspot()) {
-            getActivity().setTitle(R.string.wifi_dpp_share_hotspot);
-        } else {
-            getActivity().setTitle(R.string.wifi_dpp_share_wifi);
+        if (getActivity() != null) {
+            if (wifiNetworkConfig.isHotspot()) {
+                getActivity().setTitle(R.string.wifi_dpp_share_hotspot);
+            } else {
+                getActivity().setTitle(R.string.wifi_dpp_share_wifi);
+            }
         }
     }
 
@@ -112,10 +135,130 @@
             }
         }
 
+        final Intent intent = new Intent().setComponent(getNearbySharingComponent());
+        addActionButton(view.findViewById(R.id.wifi_dpp_layout), createNearbyButton(intent, v -> {
+            intent.setAction(Intent.ACTION_SEND);
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+
+            Bundle wifiCredentialBundle = new Bundle();
+
+            String ssid = WifiDppUtils.removeFirstAndLastDoubleQuotes(wifiNetworkConfig.getSsid());
+
+            String passwordExtra = wifiNetworkConfig.getPreSharedKey();
+            String securityType = wifiNetworkConfig.getSecurity();
+            boolean hiddenSsid = wifiNetworkConfig.getHiddenSsid();
+
+            wifiCredentialBundle.putString(EXTRA_SSID, ssid);
+            wifiCredentialBundle.putString(EXTRA_PASSWORD, passwordExtra);
+            wifiCredentialBundle.putString(EXTRA_SECURITY_TYPE, securityType);
+            wifiCredentialBundle.putBoolean(EXTRA_HIDDEN_SSID, hiddenSsid);
+
+            intent.putExtra(EXTRA_WIFI_CREDENTIALS_BUNDLE, wifiCredentialBundle);
+            startActivity(intent);
+        }));
+
         mQrCode = wifiNetworkConfig.getQrCode();
         setQrCode();
     }
 
+    @VisibleForTesting
+    ComponentName getNearbySharingComponent() {
+        String nearbyComponent = Settings.Secure.getString(
+                getContext().getContentResolver(),
+                Settings.Secure.NEARBY_SHARING_COMPONENT);
+        if (TextUtils.isEmpty(nearbyComponent)) {
+            nearbyComponent = getString(
+                    com.android.internal.R.string.config_defaultNearbySharingComponent);
+        }
+        if (TextUtils.isEmpty(nearbyComponent)) {
+            return null;
+        }
+        return ComponentName.unflattenFromString(nearbyComponent);
+    }
+
+    private TargetInfo getNearbySharingTarget(Intent originalIntent) {
+        final ComponentName cn = getNearbySharingComponent();
+        if (cn == null) return null;
+
+        final Intent resolveIntent = new Intent(originalIntent);
+        resolveIntent.setComponent(cn);
+        PackageManager pm = getContext().getPackageManager();
+        final ResolveInfo resolveInfo = pm.resolveActivity(
+                resolveIntent, PackageManager.GET_META_DATA);
+        if (resolveInfo == null || resolveInfo.activityInfo == null) {
+            Log.e(TAG, "Device-specified nearby sharing component (" + cn
+                    + ") not available");
+            return null;
+        }
+
+        // Allow the nearby sharing component to provide a more appropriate icon and label
+        // for the chip.
+        CharSequence name = null;
+        Drawable icon = null;
+        final Bundle metaData = resolveInfo.activityInfo.metaData;
+        if (metaData != null) {
+            try {
+                final Resources pkgRes = pm.getResourcesForActivity(cn);
+                final int nameResId = metaData.getInt(CHIP_LABEL_METADATA_KEY);
+                name = pkgRes.getString(nameResId);
+                final int resId = metaData.getInt(CHIP_ICON_METADATA_KEY);
+                icon = pkgRes.getDrawable(resId);
+            } catch (Resources.NotFoundException ex) {
+            } catch (PackageManager.NameNotFoundException ex) {
+            }
+        }
+        if (TextUtils.isEmpty(name)) {
+            name = resolveInfo.loadLabel(pm);
+        }
+        if (icon == null) {
+            icon = resolveInfo.loadIcon(pm);
+        }
+
+        final DisplayResolveInfo dri = new DisplayResolveInfo(
+                originalIntent, resolveInfo, name, "", resolveIntent, null);
+        dri.setDisplayIcon(icon);
+        return dri;
+    }
+
+    private Button createActionButton(Drawable icon, CharSequence title, View.OnClickListener r) {
+        final Button b = (Button) LayoutInflater.from(getContext()).inflate(
+                com.android.internal.R.layout.chooser_action_button, null);
+        if (icon != null) {
+            final int size = getResources()
+                    .getDimensionPixelSize(
+                            com.android.internal.R.dimen.chooser_action_button_icon_size);
+            icon.setBounds(0, 0, size, size);
+            b.setCompoundDrawablesRelative(icon, null, null, null);
+        }
+        b.setText(title);
+        b.setOnClickListener(r);
+        return b;
+    }
+
+    private void addActionButton(ViewGroup parent, Button b) {
+        if (b == null) return;
+        final ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams(
+                ViewGroup.LayoutParams.WRAP_CONTENT,
+                ViewGroup.LayoutParams.WRAP_CONTENT
+        );
+        final int gap = getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.resolver_icon_margin) / 2;
+        lp.setMarginsRelative(gap, 0, gap, 0);
+        parent.addView(b, lp);
+    }
+
+    @VisibleForTesting
+    @Nullable
+    Button createNearbyButton(Intent originalIntent, View.OnClickListener r) {
+        final TargetInfo ti = getNearbySharingTarget(originalIntent);
+        if (ti == null) return null;
+        final Button button = createActionButton(ti.getDisplayIcon(getContext()),
+                ti.getDisplayLabel(), r);
+        button.setAllCaps(false);
+        return button;
+    }
+
     private void setQrCode() {
         try {
             final int qrcodeSize = getContext().getResources().getDimensionPixelSize(
diff --git a/src/com/android/settings/wifi/dpp/WifiDppUtils.java b/src/com/android/settings/wifi/dpp/WifiDppUtils.java
index 7a502c9..71301d5 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppUtils.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppUtils.java
@@ -149,7 +149,7 @@
         return wifiConfiguration.preSharedKey;
     }
 
-    private static String removeFirstAndLastDoubleQuotes(String str) {
+    static String removeFirstAndLastDoubleQuotes(String str) {
         if (TextUtils.isEmpty(str)) {
             return str;
         }
diff --git a/tests/anomaly-tester/Android.bp b/tests/anomaly-tester/Android.bp
index 29181af..c897d75 100644
--- a/tests/anomaly-tester/Android.bp
+++ b/tests/anomaly-tester/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "packages_apps_Settings_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["packages_apps_Settings_license"],
+}
+
 android_test {
     name: "AnomalyTester",
 
diff --git a/tests/componenttests/OWNERS b/tests/componenttests/OWNERS
new file mode 100644
index 0000000..d270196
--- /dev/null
+++ b/tests/componenttests/OWNERS
@@ -0,0 +1,3 @@
+# People who can approve changes for submission
+jyhsu@google.com
+syaoranx@google.com
diff --git a/tests/perftests/Android.bp b/tests/perftests/Android.bp
index 1ba5d9c..c03c57f 100644
--- a/tests/perftests/Android.bp
+++ b/tests/perftests/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "packages_apps_Settings_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["packages_apps_Settings_license"],
+}
+
 android_test {
     name: "SettingsPerfTests",
 
diff --git a/tests/robotests/Android.bp b/tests/robotests/Android.bp
index d6c56be..6f0931e 100644
--- a/tests/robotests/Android.bp
+++ b/tests/robotests/Android.bp
@@ -2,6 +2,15 @@
 // Build SettingsRoboTestStub.apk which includes test-only resources.#
 //############################################################
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "packages_apps_Settings_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["packages_apps_Settings_license"],
+}
+
 android_app {
     name: "SettingsRoboTestStub",
     defaults: [
diff --git a/tests/robotests/src/com/android/settings/development/compat/PlatformCompatDashboardTest.java b/tests/robotests/src/com/android/settings/development/compat/PlatformCompatDashboardTest.java
index 15e9bda..dffd7fb 100644
--- a/tests/robotests/src/com/android/settings/development/compat/PlatformCompatDashboardTest.java
+++ b/tests/robotests/src/com/android/settings/development/compat/PlatformCompatDashboardTest.java
@@ -88,14 +88,16 @@
     public void setUp() throws RemoteException, NameNotFoundException {
         MockitoAnnotations.initMocks(this);
         mChanges = new CompatibilityChangeInfo[5];
-        mChanges[0] = new CompatibilityChangeInfo(1L, "Default_Enabled", 0, 0, false, false, "");
-        mChanges[1] = new CompatibilityChangeInfo(2L, "Default_Disabled", 0, 0, true, false, "");
-        mChanges[2] = new CompatibilityChangeInfo(3L, "Enabled_Since_SDK_1_1", -1, 1, false, false,
-                                                  "");
-        mChanges[3] = new CompatibilityChangeInfo(4L, "Enabled_Since_SDK_1_2", -1, 1, false, false,
-                                                  "");
-        mChanges[4] = new CompatibilityChangeInfo(5L, "Enabled_Since_SDK_2", -1, 2, false, false,
-                                                  "");
+        mChanges[0] = new CompatibilityChangeInfo(
+                1L, "Default_Enabled", 0, 0, false, false, "", false);
+        mChanges[1] = new CompatibilityChangeInfo(
+                2L, "Default_Disabled", 0, 0, true, false, "", false);
+        mChanges[2] = new CompatibilityChangeInfo(
+                3L, "Enabled_Since_SDK_1_1", -1, 1, false, false, "", false);
+        mChanges[3] = new CompatibilityChangeInfo(
+                4L, "Enabled_Since_SDK_1_2", -1, 1, false, false, "", false);
+        mChanges[4] = new CompatibilityChangeInfo(
+                5L, "Enabled_Since_SDK_2", -1, 2, false, false, "", false);
         when(mPlatformCompat.listUIChanges()).thenReturn(mChanges);
         when(mPlatformCompat.getOverrideValidator()).thenReturn(mOverrideValidator);
         // By default, allow any change
@@ -208,7 +210,8 @@
         for (int i = 0; i < mChanges.length; ++i) {
             changesToAdd.add(new CompatibilityChangeInfo(mChanges[i].getId(), mChanges[i].getName(),
                     -1, mChanges[i].getEnableSinceTargetSdk(), mChanges[i].getDisabled(),
-                    mChanges[i].getLoggingOnly(), mChanges[i].getDescription()));
+                    mChanges[i].getLoggingOnly(), mChanges[i].getDescription(),
+                    mChanges[i].getOverridable()));
         }
 
         PreferenceCategory category = mDashboard.createChangeCategoryPreference(changesToAdd,
diff --git a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
index f539350..43fe0f6 100644
--- a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
@@ -39,7 +39,7 @@
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.net.ConnectivityManager;
-import android.net.ProxyInfo;
+import android.net.VpnManager;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
@@ -84,6 +84,7 @@
     private @Mock PackageManager mPackageManager;
     private @Mock UserManager mUserManager;
     private @Mock ConnectivityManager mConnectivityManger;
+    private @Mock VpnManager mVpnManager;
     private Resources mResources;
 
     private EnterprisePrivacyFeatureProvider mProvider;
@@ -99,7 +100,7 @@
         mResources = RuntimeEnvironment.application.getResources();
 
         mProvider = new EnterprisePrivacyFeatureProviderImpl(mContext, mDevicePolicyManager,
-                mPackageManager, mUserManager, mConnectivityManger, mResources);
+                mPackageManager, mUserManager, mConnectivityManger, mVpnManager, mResources);
     }
 
     @Test
@@ -201,11 +202,10 @@
 
     @Test
     public void testIsAlwaysOnVpnSetInCurrentUser() {
-        when(mConnectivityManger.getAlwaysOnVpnPackageForUser(MY_USER_ID)).thenReturn(null);
+        when(mVpnManager.getAlwaysOnVpnPackageForUser(MY_USER_ID)).thenReturn(null);
         assertThat(mProvider.isAlwaysOnVpnSetInCurrentUser()).isFalse();
 
-        when(mConnectivityManger.getAlwaysOnVpnPackageForUser(MY_USER_ID))
-                .thenReturn(VPN_PACKAGE_ID);
+        when(mVpnManager.getAlwaysOnVpnPackageForUser(MY_USER_ID)).thenReturn(VPN_PACKAGE_ID);
         assertThat(mProvider.isAlwaysOnVpnSetInCurrentUser()).isTrue();
     }
 
@@ -215,26 +215,15 @@
 
         mProfiles.add(new UserInfo(MANAGED_PROFILE_USER_ID, "", "", UserInfo.FLAG_MANAGED_PROFILE));
 
-        when(mConnectivityManger.getAlwaysOnVpnPackageForUser(MANAGED_PROFILE_USER_ID))
-                .thenReturn(null);
+        when(mVpnManager.getAlwaysOnVpnPackageForUser(MANAGED_PROFILE_USER_ID)).thenReturn(null);
         assertThat(mProvider.isAlwaysOnVpnSetInManagedProfile()).isFalse();
 
-        when(mConnectivityManger.getAlwaysOnVpnPackageForUser(MANAGED_PROFILE_USER_ID))
+        when(mVpnManager.getAlwaysOnVpnPackageForUser(MANAGED_PROFILE_USER_ID))
                 .thenReturn(VPN_PACKAGE_ID);
         assertThat(mProvider.isAlwaysOnVpnSetInManagedProfile()).isTrue();
     }
 
     @Test
-    public void testIsGlobalHttpProxySet() {
-        when(mConnectivityManger.getGlobalProxy()).thenReturn(null);
-        assertThat(mProvider.isGlobalHttpProxySet()).isFalse();
-
-        when(mConnectivityManger.getGlobalProxy())
-            .thenReturn(ProxyInfo.buildDirectProxy("localhost", 123));
-        assertThat(mProvider.isGlobalHttpProxySet()).isTrue();
-    }
-
-    @Test
     public void testGetMaximumFailedPasswordsForWipeInCurrentUser() {
         when(mDevicePolicyManager.getDeviceOwnerComponentOnCallingUser()).thenReturn(null);
         when(mDevicePolicyManager.getProfileOwnerAsUser(MY_USER_ID)).thenReturn(null);
diff --git a/tests/robotests/src/com/android/settings/enterprise/GlobalHttpProxyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/GlobalHttpProxyPreferenceControllerTest.java
index 05d1c64..11676a2 100644
--- a/tests/robotests/src/com/android/settings/enterprise/GlobalHttpProxyPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/GlobalHttpProxyPreferenceControllerTest.java
@@ -21,11 +21,11 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.ProxyInfo;
 
 import androidx.preference.Preference;
 
-import com.android.settings.testutils.FakeFeatureFactory;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -41,25 +41,23 @@
 
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private Context mContext;
-    private FakeFeatureFactory mFeatureFactory;
+    @Mock
+    private ConnectivityManager mCm;
 
     private GlobalHttpProxyPreferenceController mController;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mFeatureFactory = FakeFeatureFactory.setupForTest();
         mController = new GlobalHttpProxyPreferenceController(mContext);
     }
 
     @Test
     public void testIsAvailable() {
-        when(mFeatureFactory.enterprisePrivacyFeatureProvider.isGlobalHttpProxySet())
-                .thenReturn(false);
+        when(mCm.getGlobalProxy()).thenReturn(null);
         assertThat(mController.isAvailable()).isFalse();
 
-        when(mFeatureFactory.enterprisePrivacyFeatureProvider.isGlobalHttpProxySet())
-                .thenReturn(true);
+        when(mCm.getGlobalProxy()).thenReturn(ProxyInfo.buildDirectProxy("localhost", 123));
         assertThat(mController.isAvailable()).isTrue();
     }
 
diff --git a/tests/robotests/src/com/android/settings/vpn2/VpnUtilsTest.java b/tests/robotests/src/com/android/settings/vpn2/VpnUtilsTest.java
index 7856b06..08a9242 100644
--- a/tests/robotests/src/com/android/settings/vpn2/VpnUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/vpn2/VpnUtilsTest.java
@@ -21,7 +21,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import android.net.ConnectivityManager;
+import android.net.VpnManager;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -31,11 +31,11 @@
 public final class VpnUtilsTest {
     @Test
     public void testIsAlwaysOnVpnSet() {
-        final ConnectivityManager cm = mock(ConnectivityManager.class);
-        when(cm.getAlwaysOnVpnPackageForUser(0)).thenReturn("com.example.vpn");
-        assertThat(VpnUtils.isAlwaysOnVpnSet(cm, 0)).isTrue();
+        final VpnManager vm = mock(VpnManager.class);
+        when(vm.getAlwaysOnVpnPackageForUser(0)).thenReturn("com.example.vpn");
+        assertThat(VpnUtils.isAlwaysOnVpnSet(vm, 0)).isTrue();
 
-        when(cm.getAlwaysOnVpnPackageForUser(0)).thenReturn(null);
-        assertThat(VpnUtils.isAlwaysOnVpnSet(cm, 0)).isFalse();
+        when(vm.getAlwaysOnVpnPackageForUser(0)).thenReturn(null);
+        assertThat(VpnUtils.isAlwaysOnVpnSet(vm, 0)).isFalse();
     }
 }
diff --git a/tests/robotests/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragmentTest.java b/tests/robotests/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragmentTest.java
new file mode 100644
index 0000000..b36d7f5
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragmentTest.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.wifi.dpp;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+
+import androidx.fragment.app.FragmentTransaction;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+
+@RunWith(AndroidJUnit4.class)
+public class WifiDppQrCodeGeneratorFragmentTest {
+
+    private WifiDppConfiguratorActivity mActivity;
+    private WifiDppQrCodeGeneratorFragment mFragment;
+    private Context mContext;
+
+
+    @Before
+    public void setUp() {
+        Intent intent =
+                new Intent(WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_GENERATOR);
+        intent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, "GoogleGuest");
+        intent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY, "WPA");
+        intent.putExtra(WifiDppUtils.EXTRA_WIFI_PRE_SHARED_KEY, "\\012345678,");
+
+        MockitoAnnotations.initMocks(this);
+        mActivity = Robolectric.setupActivity(WifiDppConfiguratorActivity.class);
+        mActivity.setWifiNetworkConfig(WifiNetworkConfig.getValidConfigOrNull(intent));
+        mActivity.startActivity(intent);
+
+        mFragment = spy(new WifiDppQrCodeGeneratorFragment());
+        FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction();
+        ft.add(mFragment, null);
+        ft.commit();
+
+        mContext = spy(InstrumentationRegistry.getTargetContext());
+        when(mFragment.getContext()).thenReturn(mContext);
+    }
+
+    @Test
+    public void rotateScreen_shouldNotCrash() {
+        mActivity.setRequestedOrientation(
+                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+        mActivity.setRequestedOrientation(
+                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+    }
+
+    @Test
+    public void createNearbyButton_returnsNull() {
+        assertThat(mFragment.createNearbyButton(new Intent(), v -> {
+        })).isNull();
+    }
+
+    private static ResolveInfo createResolveInfo(int userId) {
+        final ResolveInfo resolveInfo = new ResolveInfo();
+        resolveInfo.activityInfo = createActivityInfo();
+        resolveInfo.targetUserId = userId;
+        return resolveInfo;
+    }
+
+    private static ActivityInfo createActivityInfo() {
+        ActivityInfo ai = new ActivityInfo();
+        ai.name = "activity_name";
+        ai.packageName = "foo_bar";
+        ai.enabled = true;
+        ai.exported = true;
+        ai.permission = null;
+        ai.applicationInfo = new ApplicationInfo();
+        ai.applicationInfo.packageName = "com.google.android.gms";
+
+        Bundle metadata = mock(Bundle.class);
+        when(metadata.getInt(anyString())).thenReturn(1);
+        ai.metaData = metadata;
+        return ai;
+    }
+
+    @Test
+    public void createNearbyButtonFromSetting_notNull()
+            throws PackageManager.NameNotFoundException {
+        doReturn(ComponentName.unflattenFromString(
+                "com.google.android.gms/com.google.android.gms.nearby.sharing.ShareSheetActivity"))
+                .when(mFragment).getNearbySharingComponent();
+        PackageManager packageManager = mock(PackageManager.class);
+        doReturn(createResolveInfo(0)).when(packageManager).resolveActivity(any(), anyInt());
+
+        Resources resources = mock(Resources.class);
+        when(resources.getString(anyInt())).thenReturn("Nearby");
+        Drawable drawable = mock(Drawable.class);
+        when(resources.getDrawable(anyInt())).thenReturn(drawable);
+
+        when(packageManager.getResourcesForActivity(any())).thenReturn(resources);
+
+        when(mContext.getPackageManager()).thenReturn(packageManager);
+
+
+        assertThat(mFragment.createNearbyButton(new Intent(), v -> {
+        })).isNotNull();
+    }
+
+    @Test
+    public void createNearbyButtonFromConfig_notNull() throws PackageManager.NameNotFoundException {
+        doReturn(
+                "com.google.android.gms/com.google.android.gms.nearby.sharing.ShareSheetActivity")
+                .when(mFragment).getString(anyInt());
+        PackageManager packageManager = mock(PackageManager.class);
+        doReturn(createResolveInfo(0)).when(packageManager).resolveActivity(any(), anyInt());
+
+        Resources resources = mock(Resources.class);
+        when(resources.getString(anyInt())).thenReturn("Nearby");
+        Drawable drawable = mock(Drawable.class);
+        when(resources.getDrawable(anyInt())).thenReturn(drawable);
+
+        when(packageManager.getResourcesForActivity(any())).thenReturn(resources);
+
+        when(mContext.getPackageManager()).thenReturn(packageManager);
+
+
+        assertThat(mFragment.createNearbyButton(new Intent(), v -> {
+        })).isNotNull();
+    }
+}
diff --git a/tests/uitests/Android.bp b/tests/uitests/Android.bp
index 8a3e374..8636c81 100644
--- a/tests/uitests/Android.bp
+++ b/tests/uitests/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "packages_apps_Settings_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["packages_apps_Settings_license"],
+}
+
 android_test {
     name: "SettingsUITests",
     platform_apis: true,
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp
index 7556cbe..b94e891 100644
--- a/tests/unit/Android.bp
+++ b/tests/unit/Android.bp
@@ -1,3 +1,12 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "packages_apps_Settings_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["packages_apps_Settings_license"],
+}
+
 android_test {
     name: "SettingsUnitTests",
 
diff --git a/tests/unit/InstrumentedEntitlementApp/Android.bp b/tests/unit/InstrumentedEntitlementApp/Android.bp
index dacd32a..1ec108a 100644
--- a/tests/unit/InstrumentedEntitlementApp/Android.bp
+++ b/tests/unit/InstrumentedEntitlementApp/Android.bp
@@ -12,6 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "packages_apps_Settings_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["packages_apps_Settings_license"],
+}
+
 android_test {
     name: "InstrumentedEntitlementApp",
     srcs: ["src/**/*.java"],