Merge "Migrating to new footer button for ChooseLockPassword page"
diff --git a/res/drawable/ic_check_circle_green.xml b/res/drawable/ic_check_circle_green.xml
new file mode 100644
index 0000000..214d2cf
--- /dev/null
+++ b/res/drawable/ic_check_circle_green.xml
@@ -0,0 +1,28 @@
+<!--
+    Copyright 2019 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="24dp"
+    android:height="24dp"
+    android:viewportWidth="64.0"
+    android:viewportHeight="64.0">
+    <path
+        android:fillColor="#0F9D58"
+        android:pathData="M32,5.3C17.3,5.3 5.3,17.3 5.3,32s12,26.7 26.7,26.7s26.7,-12 26.7,-26.7S46.7,5.3 32,5.3z"/>
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M49.4,24.3l-20,20c-1,1 -2.7,1 -3.8,0l0,0l-11.1,-11c-1.1,-1 -1.1,-2.7 0,-3.8s2.7,-1.1 3.8,0l0,0l9.2,9.2l18.1,-18.1c1,-1 2.7,-1 3.8,0C50.4,21.6 50.4,23.3 49.4,24.3L49.4,24.3z"/>
+</vector>
diff --git a/res/drawable/ic_devices_other_opaque_black.xml b/res/drawable/ic_devices_other_opaque_black.xml
new file mode 100644
index 0000000..1b5af2d
--- /dev/null
+++ b/res/drawable/ic_devices_other_opaque_black.xml
@@ -0,0 +1,24 @@
+<!--
+    Copyright 2019 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="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+  <path
+      android:fillColor="#FF000000"
+      android:pathData="M3,6h18L21,4L3,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h4v-2L3,18L3,6zM13,12L9,12v1.78c-0.61,0.55 -1,1.33 -1,2.22 0,0.89 0.39,1.67 1,2.22L9,20h4v-1.78c0.61,-0.55 1,-1.34 1,-2.22s-0.39,-1.67 -1,-2.22L13,12zM11,17.5c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5 1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5zM22,8h-6c-0.5,0 -1,0.5 -1,1v10c0,0.5 0.5,1 1,1h6c0.5,0 1,-0.5 1,-1L23,9c0,-0.5 -0.5,-1 -1,-1zM21,18h-4v-8h4v8z"/>
+</vector>
diff --git a/res/layout/network_request_dialog_title.xml b/res/layout/network_request_dialog_title.xml
index fa01085..186768e 100644
--- a/res/layout/network_request_dialog_title.xml
+++ b/res/layout/network_request_dialog_title.xml
@@ -26,7 +26,8 @@
       android:id="@+id/network_request_title_text"
       android:layout_width="0dp"
       android:layout_height="match_parent"
-      android:paddingLeft="16dip"
+      android:paddingLeft="24dp"
+      android:paddingTop="18dp"
       android:layout_weight="1"
       android:textSize="18sp"
       android:gravity="center_vertical"
diff --git a/res/layout/radio_info.xml b/res/layout/radio_info.xml
index 60b23c8..100521e 100644
--- a/res/layout/radio_info.xml
+++ b/res/layout/radio_info.xml
@@ -174,6 +174,20 @@
             android:layout_height="1dip"
             android:background="?android:attr/listDivider" />
 
+        <!-- Enable/Disable CBRS data -->
+        <Switch android:id="@+id/cbrs_data_switch"
+                android:textSize="14sp"
+                android:layout_marginTop="8dip"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/cbrs_data_switch_string" />
+
+        <!-- Horizontal Rule -->
+        <View
+            android:layout_width="fill_parent"
+            android:layout_height="1dip"
+            android:background="?android:attr/listDivider" />
+
         <!-- Ping stats -->
         <Button android:id="@+id/ping_test"
                 android:textSize="14sp"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a082074..f77c10d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -63,6 +63,9 @@
     <!-- EAB provisioning flag on. Only shown in diagnostic screen, so precise translation is not needed. -->
     <string name="eab_provisioned_switch_string">EAB/Presence Provisioned</string>
 
+    <!-- Cbrs enable disable flag. Only shown in diagnostic screen, so precise translation is not needed -->
+    <string name="cbrs_data_switch_string">Cbrs Data</string>
+
     <!-- Title for controlling on/off for Mobile phone's radio power. Only shown in diagnostic screen, so precise translation is not needed. -->
     <string name="radio_info_radio_power">Mobile Radio Power</string>
 
@@ -10455,6 +10458,8 @@
     <string name="network_connection_timeout_dialog_ok">Try again</string>
     <!-- Message for Network connection error state Dialog [CHAR LIMIT=NONE] -->
     <string name="network_connection_errorstate_dialog_message">Something came up. The application has cancelled the request to choose a device.</string>
+    <!-- Toast message when connection is successful [CHAR LIMIT=30] -->
+    <string name="network_connection_connect_successful">Connection successful</string>
 
     <!-- Summary for bluetooth devices count in Bluetooth devices slice. [CHAR LIMIT=NONE] -->
     <plurals name="show_bluetooth_devices">
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index b23a9cb..6d22a1d 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -59,10 +59,12 @@
             android:entries="@array/hdcp_checking_titles"
             android:entryValues="@array/hdcp_checking_values" />
 
-        <SwitchPreference
+        <ListPreference
             android:key="bt_hci_snoop_log"
             android:title="@string/bt_hci_snoop_log"
-            android:summary="@string/bt_hci_snoop_log_summary" />
+            android:dialogTitle="@string/bt_hci_snoop_log_summary"
+            android:entries="@array/bt_hci_snoop_log_entries"
+            android:entryValues="@array/bt_hci_snoop_log_values" />
 
         <com.android.settingslib.RestrictedSwitchPreference
             android:key="oem_unlock_enable"
diff --git a/src/com/android/settings/RadioInfo.java b/src/com/android/settings/RadioInfo.java
index 2791efa..251bfbc 100644
--- a/src/com/android/settings/RadioInfo.java
+++ b/src/com/android/settings/RadioInfo.java
@@ -213,6 +213,7 @@
     private Switch imsVtProvisionedSwitch;
     private Switch imsWfcProvisionedSwitch;
     private Switch eabProvisionedSwitch;
+    private Switch cbrsDataSwitch;
     private Spinner preferredNetworkType;
     private Spinner cellInfoRefreshRateSpinner;
 
@@ -450,6 +451,9 @@
         imsWfcProvisionedSwitch = (Switch) findViewById(R.id.wfc_provisioned_switch);
         eabProvisionedSwitch = (Switch) findViewById(R.id.eab_provisioned_switch);
 
+        cbrsDataSwitch = (Switch) findViewById(R.id.cbrs_data_switch);
+        cbrsDataSwitch.setVisibility(isCbrsSupported() ? View.VISIBLE : View.GONE);
+
         radioPowerOnSwitch = (Switch) findViewById(R.id.radio_power);
 
         mDownlinkKbps = (TextView) findViewById(R.id.dl_kbps);
@@ -526,6 +530,11 @@
         imsWfcProvisionedSwitch.setOnCheckedChangeListener(mImsWfcCheckedChangeListener);
         eabProvisionedSwitch.setOnCheckedChangeListener(mEabCheckedChangeListener);
 
+        if (isCbrsSupported()) {
+            cbrsDataSwitch.setChecked(getCbrsDataState());
+            cbrsDataSwitch.setOnCheckedChangeListener(mCbrsDataSwitchChangeListener);
+        }
+
         mTelephonyManager.listen(mPhoneStateListener,
                   PhoneStateListener.LISTEN_CALL_STATE
         //b/27803938 - RadioInfo currently cannot read PRECISE_CALL_STATE
@@ -1483,4 +1492,38 @@
         }
     };
 
+    boolean isCbrsSupported() {
+        return getResources().getBoolean(
+              com.android.internal.R.bool.config_cbrs_supported);
+    }
+
+    void updateCbrsDataState(boolean state) {
+        Log.d(TAG, "setCbrsDataSwitchState() state:" + ((state)? "on":"off"));
+        if (mTelephonyManager != null) {
+            QueuedWork.queue(new Runnable() {
+                public void run() {
+                  mTelephonyManager.setOpportunisticNetworkState(state);
+                  cbrsDataSwitch.setChecked(getCbrsDataState());
+                }
+            }, false);
+        }
+    }
+
+    boolean getCbrsDataState() {
+        boolean state = false;
+        if (mTelephonyManager != null) {
+            state = mTelephonyManager.isOpportunisticNetworkEnabled();
+        }
+        Log.d(TAG, "getCbrsDataState() state:" +((state)? "on":"off"));
+        return state;
+    }
+
+    OnCheckedChangeListener mCbrsDataSwitchChangeListener = new OnCheckedChangeListener() {
+        @Override
+        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+            updateCbrsDataState(isChecked);
+        }
+    };
+
+
 }
diff --git a/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceController.java b/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceController.java
index a94bc6d..617a9bb 100644
--- a/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceController.java
+++ b/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceController.java
@@ -152,7 +152,7 @@
         if (!mHearingAidProfileSupported) {
             return null;
         }
-        if (!mBluetoothAdapter.isEnabled()) {
+        if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
             return null;
         }
         final List<BluetoothDevice> deviceList = mLocalBluetoothManager.getProfileManager()
@@ -166,6 +166,9 @@
     }
 
     private boolean isHearingAidProfileSupported() {
+        if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
+            return false;
+        }
         final List<Integer> supportedList = mBluetoothAdapter.getSupportedProfiles();
         if (supportedList.contains(BluetoothProfile.HEARING_AID)) {
             return true;
diff --git a/src/com/android/settings/development/BluetoothSnoopLogPreferenceController.java b/src/com/android/settings/development/BluetoothSnoopLogPreferenceController.java
index c92fe90..d26f0dd 100644
--- a/src/com/android/settings/development/BluetoothSnoopLogPreferenceController.java
+++ b/src/com/android/settings/development/BluetoothSnoopLogPreferenceController.java
@@ -17,12 +17,19 @@
 package com.android.settings.development;
 
 import android.content.Context;
+import android.os.Build;
 import android.os.SystemProperties;
+import android.provider.Settings;
+import android.text.TextUtils;
+
+import android.util.Log;
 
 import androidx.annotation.VisibleForTesting;
+import androidx.preference.ListPreference;
 import androidx.preference.Preference;
 import androidx.preference.SwitchPreference;
 
+import com.android.settings.R;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settingslib.development.DeveloperOptionsPreferenceController;
 
@@ -31,11 +38,40 @@
 
     private static final String PREFERENCE_KEY = "bt_hci_snoop_log";
     @VisibleForTesting
-    static final String BLUETOOTH_BTSNOOP_ENABLE_PROPERTY =
-            "persist.bluetooth.btsnoopenable";
+    static final int BTSNOOP_LOG_MODE_DISABLED_INDEX = 0;
+    @VisibleForTesting
+    static final int BTSNOOP_LOG_MODE_FILTERED_INDEX = 1;
+    @VisibleForTesting
+    static final int BTSNOOP_LOG_MODE_FULL_INDEX = 2;
+    @VisibleForTesting
+    static final String BLUETOOTH_BTSNOOP_LOG_MODE_PROPERTY = "persist.bluetooth.btsnooplogmode";
+
+    private final String[] mListValues;
+    private final String[] mListEntries;
 
     public BluetoothSnoopLogPreferenceController(Context context) {
         super(context);
+        mListValues = context.getResources().getStringArray(R.array.bt_hci_snoop_log_values);
+        mListEntries = context.getResources().getStringArray(R.array.bt_hci_snoop_log_entries);
+    }
+
+    // Default mode is FILTERED on userdebug/eng build, DISABLED on user build,
+    // or can be changed by modifying the global setting.
+    public int getDefaultModeIndex() {
+        if (!Build.IS_DEBUGGABLE) {
+            return BTSNOOP_LOG_MODE_DISABLED_INDEX;
+        }
+
+        final String default_mode = Settings.Global.getString(mContext.getContentResolver(),
+                Settings.Global.BLUETOOTH_BTSNOOP_DEFAULT_MODE);
+
+        for (int i = 0; i < mListValues.length; i++) {
+            if (TextUtils.equals(default_mode, mListValues[i])) {
+                return i;
+            }
+        }
+
+        return BTSNOOP_LOG_MODE_FILTERED_INDEX;
     }
 
     @Override
@@ -45,23 +81,32 @@
 
     @Override
     public boolean onPreferenceChange(Preference preference, Object newValue) {
-        final boolean enableBtSnoopLog = (Boolean) newValue;
-        SystemProperties.set(BLUETOOTH_BTSNOOP_ENABLE_PROPERTY, Boolean.toString(enableBtSnoopLog));
+        SystemProperties.set(BLUETOOTH_BTSNOOP_LOG_MODE_PROPERTY, newValue.toString());
+        updateState(mPreference);
         return true;
     }
 
     @Override
     public void updateState(Preference preference) {
-        super.updateState(preference);
-        final boolean enableBtSnoopLog = SystemProperties.getBoolean(
-                BLUETOOTH_BTSNOOP_ENABLE_PROPERTY, false /* def */);
-        ((SwitchPreference) mPreference).setChecked(enableBtSnoopLog);
+        final ListPreference listPreference = (ListPreference) preference;
+        final String currentValue = SystemProperties.get(BLUETOOTH_BTSNOOP_LOG_MODE_PROPERTY);
+
+        int index = getDefaultModeIndex();
+        for (int i = 0; i < mListValues.length; i++) {
+            if (TextUtils.equals(currentValue, mListValues[i])) {
+                index = i;
+                break;
+            }
+        }
+        listPreference.setValue(mListValues[index]);
+        listPreference.setSummary(mListEntries[index]);
     }
 
     @Override
     protected void onDeveloperOptionsSwitchDisabled() {
         super.onDeveloperOptionsSwitchDisabled();
-        SystemProperties.set(BLUETOOTH_BTSNOOP_ENABLE_PROPERTY, Boolean.toString(false));
-        ((SwitchPreference) mPreference).setChecked(false);
+        SystemProperties.set(BLUETOOTH_BTSNOOP_LOG_MODE_PROPERTY, null);
+        ((ListPreference) mPreference).setValue(mListValues[getDefaultModeIndex()]);
+        ((ListPreference) mPreference).setSummary(mListEntries[getDefaultModeIndex()]);
     }
 }
diff --git a/src/com/android/settings/sound/MediaOutputPreferenceController.java b/src/com/android/settings/sound/MediaOutputPreferenceController.java
index 2ac460c..ce476ad 100644
--- a/src/com/android/settings/sound/MediaOutputPreferenceController.java
+++ b/src/com/android/settings/sound/MediaOutputPreferenceController.java
@@ -74,18 +74,7 @@
         }
 
         final int numDevices = mConnectedDevices.size();
-        if (numDevices == 0) {
-            // Disable switch entry if there is no connected devices.
-            mPreference.setVisible(false);
-            final CharSequence summary = mContext.getText(R.string.media_output_default_summary);
-            final CharSequence[] defaultMediaOutput = new CharSequence[]{summary};
-            mSelectedIndex = getDefaultDeviceIndex();
-            preference.setSummary(summary);
-            setPreference(defaultMediaOutput, defaultMediaOutput, preference);
-            return;
-        }
-
-        mPreference.setVisible(true);
+        mPreference.setVisible((numDevices == 0) ? false : true);
         CharSequence[] mediaOutputs = new CharSequence[numDevices + 1];
         CharSequence[] mediaValues = new CharSequence[numDevices + 1];
 
diff --git a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
index 0ed8544..921552d 100644
--- a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
+++ b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.wifi;
 
+import android.app.Activity;
 import android.app.Dialog;
 import android.app.settings.SettingsEnums;
 import android.content.Context;
@@ -29,6 +30,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
+import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -36,6 +38,7 @@
 import android.widget.BaseAdapter;
 import android.widget.ProgressBar;
 import android.widget.TextView;
+import android.widget.Toast;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
@@ -65,15 +68,9 @@
     /** Message sent to us to stop scanning wifi and pop up timeout dialog. */
     private static final int MESSAGE_STOP_SCAN_WIFI_LIST = 0;
 
-    /** Message sent to us to finish activity. */
-    private static final int MESSAGE_FINISH_ACTIVITY = 1;
-
     /** Spec defines there should be 5 wifi ap on the list at most. */
     private static final int MAX_NUMBER_LIST_ITEM = 5;
 
-    /** Holding time to let user be aware that selected wifi ap is connected */
-    private static final int DELAY_TIME_USER_AWARE_CONNECTED_MS = 1 * 1000;
-
     /** Delayed time to stop scanning wifi. */
     private static final int DELAY_TIME_STOP_SCAN_MS = 30 * 1000;
 
@@ -184,7 +181,6 @@
     public void onDestroy() {
         super.onDestroy();
 
-        mHandler.removeMessages(MESSAGE_FINISH_ACTIVITY);
         if (mFilterWifiTracker != null) {
             mFilterWifiTracker.onDestroy();
             mFilterWifiTracker = null;
@@ -215,10 +211,7 @@
             switch (msg.what) {
                 case MESSAGE_STOP_SCAN_WIFI_LIST:
                     removeMessages(MESSAGE_STOP_SCAN_WIFI_LIST);
-                    stopScanningAndMaybePopErrorDialog(ERROR_DIALOG_TYPE.TIME_OUT);
-                    break;
-                case MESSAGE_FINISH_ACTIVITY:
-                    stopScanningAndMaybePopErrorDialog(/* ERROR_DIALOG_TYPE */ null);
+                    stopScanningAndPopErrorDialog(ERROR_DIALOG_TYPE.TIME_OUT);
                     break;
                 default:
                     // Do nothing.
@@ -227,29 +220,21 @@
         }
     };
 
-    protected void stopScanningAndMaybePopErrorDialog(ERROR_DIALOG_TYPE type) {
+    protected void stopScanningAndPopErrorDialog(ERROR_DIALOG_TYPE type) {
         // Dismisses current dialog.
         final Dialog dialog =  getDialog();
         if (dialog != null && dialog.isShowing()) {
             dismiss();
         }
 
-        if (type  == null) {
-            // If no error, finishes activity.
-            if (getActivity() != null) {
-                getActivity().finish();
-            }
-        } else {
-            // Throws error dialog.
-            final NetworkRequestErrorDialogFragment fragment = NetworkRequestErrorDialogFragment
-                    .newInstance();
-            final Bundle bundle = new Bundle();
-            bundle.putSerializable(NetworkRequestErrorDialogFragment.DIALOG_TYPE, type);
-            fragment.setArguments(bundle);
-            fragment.show(getActivity().getSupportFragmentManager(),
-                    NetworkRequestDialogFragment.class.getSimpleName());
-        }
-
+        // Throws error dialog.
+        final NetworkRequestErrorDialogFragment fragment = NetworkRequestErrorDialogFragment
+                .newInstance();
+        final Bundle bundle = new Bundle();
+        bundle.putSerializable(NetworkRequestErrorDialogFragment.DIALOG_TYPE, type);
+        fragment.setArguments(bundle);
+        fragment.show(getActivity().getSupportFragmentManager(),
+                NetworkRequestDialogFragment.class.getSimpleName());
     }
 
     @Override
@@ -287,7 +272,13 @@
 
             final TextView summary = view.findViewById(android.R.id.summary);
             if (summary != null) {
-                summary.setText(accessPoint.getSettingsSummary());
+                final String summaryString = accessPoint.getSettingsSummary();
+                if (TextUtils.isEmpty(summaryString)) {
+                    summary.setVisibility(View.GONE);
+                } else {
+                    summary.setVisibility(View.VISIBLE);
+                    summary.setText(summaryString);
+                }
             }
 
             final PreferenceImageView imageView = view.findViewById(android.R.id.icon);
@@ -306,7 +297,7 @@
 
     @Override
     public void onAbort() {
-        stopScanningAndMaybePopErrorDialog(ERROR_DIALOG_TYPE.ABORT);
+        stopScanningAndPopErrorDialog(ERROR_DIALOG_TYPE.ABORT);
     }
 
     @Override
@@ -354,24 +345,17 @@
 
     @Override
     public void onUserSelectionConnectSuccess(WifiConfiguration wificonfiguration) {
-        // Removes the progress icon.
-        final Dialog dialog = getDialog();
-        if (dialog != null) {
-            final View view = dialog.findViewById(R.id.network_request_title_progress);
-            if (view != null) {
-                view.setVisibility(View.GONE);
-            }
+        final Activity activity = getActivity();
+        if (activity != null) {
+            Toast.makeText(activity, R.string.network_connection_connect_successful,
+                    Toast.LENGTH_SHORT).show();
+            activity.finish();
         }
-
-        // Posts delay to finish self since connection is success.
-        mHandler.removeMessages(MESSAGE_STOP_SCAN_WIFI_LIST);
-        mHandler.sendEmptyMessageDelayed(MESSAGE_FINISH_ACTIVITY,
-                DELAY_TIME_USER_AWARE_CONNECTED_MS);
     }
 
     @Override
     public void onUserSelectionConnectFailure(WifiConfiguration wificonfiguration) {
-        stopScanningAndMaybePopErrorDialog(ERROR_DIALOG_TYPE.ABORT);
+        stopScanningAndPopErrorDialog(ERROR_DIALOG_TYPE.ABORT);
     }
 
     private final class FilterWifiTracker {
diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
index a49ce40..1105f74 100644
--- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
+++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
@@ -442,9 +442,9 @@
 
     private void updateIpLayerInfo() {
         mButtonsPref.setButton2Visible(canSignIntoNetwork());
-        mButtonsPref.setButton3Visible(isSharingNetworkEnabled());
+        mButtonsPref.setButton3Visible(canShareNetwork());
         mButtonsPref.setVisible(
-                canSignIntoNetwork() || canForgetNetwork() || isSharingNetworkEnabled());
+                canSignIntoNetwork() || canForgetNetwork() || canShareNetwork());
 
         if (mNetwork == null || mLinkProperties == null) {
             mIpAddressPref.setVisible(false);
@@ -532,8 +532,9 @@
     /**
      * Returns whether the user can share the network represented by this preference with QR code.
      */
-    private boolean isSharingNetworkEnabled() {
-        return FeatureFlagUtils.isEnabled(mContext, FeatureFlags.WIFI_SHARING);
+    private boolean canShareNetwork() {
+        return mAccessPoint.getConfig() != null && FeatureFlagUtils.isEnabled(mContext,
+                FeatureFlags.WIFI_SHARING);
     }
 
     /**
diff --git a/src/com/android/settings/wifi/dpp/WifiDppAddDeviceFragment.java b/src/com/android/settings/wifi/dpp/WifiDppAddDeviceFragment.java
index 9a9a313..9864ea9 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppAddDeviceFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppAddDeviceFragment.java
@@ -55,6 +55,7 @@
         @Override
         public void onConfiguratorSuccess(int code) {
             // Update success UI.
+            mHeaderIcon.setImageResource(R.drawable.ic_check_circle_green);
             mTitle.setText(R.string.wifi_dpp_wifi_shared_with_device);
             mSummary.setVisibility(View.INVISIBLE);
             mWifiApPictureView.setImageResource(R.drawable.wifi_dpp_success);
@@ -109,6 +110,8 @@
     public void onViewCreated(View view, Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
 
+        mHeaderIcon.setImageResource(R.drawable.ic_devices_other_opaque_black);
+
         final WifiQrCode wifiQrCode = ((WifiDppConfiguratorActivity) getActivity())
                 .getWifiDppQrCode();
         final String information = wifiQrCode.getInformation();
diff --git a/src/com/android/settings/wifi/dpp/WifiDppChooseSavedWifiNetworkFragment.java b/src/com/android/settings/wifi/dpp/WifiDppChooseSavedWifiNetworkFragment.java
index b396512..3817615 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppChooseSavedWifiNetworkFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppChooseSavedWifiNetworkFragment.java
@@ -19,6 +19,7 @@
 import android.app.ActionBar;
 import android.app.Activity;
 import android.app.settings.SettingsEnums;
+import android.content.Intent;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -83,9 +84,20 @@
         mButtonLeft = view.findViewById(R.id.button_left);
         mButtonLeft.setText(R.string.cancel);
         mButtonLeft.setOnClickListener(v -> {
-            Activity activity = getActivity();
-            activity.setResult(Activity.RESULT_CANCELED);
-            activity.finish();
+            String action = null;
+            final Intent intent = getActivity().getIntent();
+            if (intent != null) {
+                action = intent.getAction();
+            }
+            if (WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_SCANNER.equals(action) ||
+                    WifiDppConfiguratorActivity
+                    .ACTION_CONFIGURATOR_QR_CODE_GENERATOR.equals(action)) {
+                getFragmentManager().popBackStack();
+            } else {
+                final Activity activity = getActivity();
+                activity.setResult(Activity.RESULT_CANCELED);
+                activity.finish();
+            }
         });
 
         mButtonRight = view.findViewById(R.id.button_right);
diff --git a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
index b387c40..3955456 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
@@ -314,8 +314,6 @@
 
     @Override
     public void onClickChooseDifferentNetwork() {
-        mWifiNetworkConfig = null;
-
         showChooseSavedWifiNetworkFragment(/* addToBackStack */ true);
     }
 
diff --git a/tests/robotests/src/com/android/settings/development/BluetoothSnoopLogPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/BluetoothSnoopLogPreferenceControllerTest.java
index 88cb295..630fd5f 100644
--- a/tests/robotests/src/com/android/settings/development/BluetoothSnoopLogPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/BluetoothSnoopLogPreferenceControllerTest.java
@@ -16,86 +16,123 @@
 
 package com.android.settings.development;
 
-import static com.android.settings.development.BluetoothSnoopLogPreferenceController
-        .BLUETOOTH_BTSNOOP_ENABLE_PROPERTY;
-
+import static com.android.settings.development.BluetoothSnoopLogPreferenceController.BLUETOOTH_BTSNOOP_LOG_MODE_PROPERTY;
 import static com.google.common.truth.Truth.assertThat;
-
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.content.res.Resources;
 import android.os.SystemProperties;
 
+import androidx.preference.ListPreference;
 import androidx.preference.PreferenceScreen;
-import androidx.preference.SwitchPreference;
+
+import com.android.settings.R;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
 import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
 
 @RunWith(RobolectricTestRunner.class)
 public class BluetoothSnoopLogPreferenceControllerTest {
 
-    @Mock
-    private Context mContext;
-    @Mock
-    private SwitchPreference mPreference;
+    @Spy
+    private Context mSpyContext = RuntimeEnvironment.application;
+    @Spy
+    private Resources mSpyResources = RuntimeEnvironment.application.getResources();
+    private ListPreference mPreference;
     @Mock
     private PreferenceScreen mPreferenceScreen;
     private BluetoothSnoopLogPreferenceController mController;
 
+    private CharSequence[] mListValues;
+    private CharSequence[] mListEntries;
+
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
-        mController = new BluetoothSnoopLogPreferenceController(mContext);
+        doReturn(mSpyResources).when(mSpyContext).getResources();
+        // Get XML values without mock
+        // Setup test list preference using XML values
+        mPreference = new ListPreference(mSpyContext);
+        mPreference.setEntries(R.array.bt_hci_snoop_log_entries);
+        mPreference.setEntryValues(R.array.bt_hci_snoop_log_values);
+        // Init the actual controller
+        mController = new BluetoothSnoopLogPreferenceController(mSpyContext);
+        // Construct preference in the controller via a mocked preference screen object
         when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
             .thenReturn(mPreference);
         mController.displayPreference(mPreferenceScreen);
+        mListValues = mPreference.getEntryValues();
+        mListEntries = mPreference.getEntries();
     }
 
     @Test
-    public void onPreferenceChanged_turnOnBluetoothSnoopLog() {
-        mController.onPreferenceChange(null, true);
+    public void verifyResourceSizeAndRange() {
+        // Verify normal list entries and default preference entries have the same size
+        assertThat(mListEntries.length).isEqualTo(mListValues.length);
+        // Update the preference
+        mController.updateState(mPreference);
+        // Verify default preference value, entry and summary
+        final int defaultIndex = mController.getDefaultModeIndex();
+        assertThat(mPreference.getValue()).isEqualTo(mListValues[defaultIndex]);
+        assertThat(mPreference.getEntry()).isEqualTo(mListEntries[defaultIndex]);
+        assertThat(mPreference.getSummary()).isEqualTo(mListEntries[defaultIndex]);
+    }
 
-        final boolean mode = SystemProperties.getBoolean(BLUETOOTH_BTSNOOP_ENABLE_PROPERTY, false);
+    @Test
+    public void onPreferenceChanged_turnOnFullBluetoothSnoopLog() {
+        mController.onPreferenceChange(null,
+                mListValues[BluetoothSnoopLogPreferenceController.BTSNOOP_LOG_MODE_FULL_INDEX]);
+        final String mode = SystemProperties.get(BLUETOOTH_BTSNOOP_LOG_MODE_PROPERTY);
+        // "full" is hard-coded between Settings and system/bt
+        assertThat(mode).isEqualTo("full");
+    }
 
-        assertThat(mode).isTrue();
+    @Test
+    public void onPreferenceChanged_turnOnFilteredBluetoothSnoopLog() {
+        mController.onPreferenceChange(null,
+                mListValues[BluetoothSnoopLogPreferenceController.BTSNOOP_LOG_MODE_FILTERED_INDEX]);
+        final String mode = SystemProperties.get(BLUETOOTH_BTSNOOP_LOG_MODE_PROPERTY);
+        // "filtered" is hard-coded between Settings and system/bt
+        assertThat(mode).isEqualTo("filtered");
     }
 
     @Test
     public void onPreferenceChanged_turnOffBluetoothSnoopLog() {
-        mController.onPreferenceChange(null, false);
-
-        final boolean mode = SystemProperties.getBoolean(BLUETOOTH_BTSNOOP_ENABLE_PROPERTY, false);
-
-        assertThat(mode).isFalse();
+        mController.onPreferenceChange(null,
+                mListValues[BluetoothSnoopLogPreferenceController.BTSNOOP_LOG_MODE_DISABLED_INDEX]);
+        final String mode = SystemProperties.get(BLUETOOTH_BTSNOOP_LOG_MODE_PROPERTY);
+        // "disabled" is hard-coded between Settings and system/bt
+        assertThat(mode).isEqualTo("disabled");
     }
 
     @Test
-    public void updateState_preferenceShouldBeChecked() {
-        SystemProperties.set(BLUETOOTH_BTSNOOP_ENABLE_PROPERTY, Boolean.toString(true));
-        mController.updateState(mPreference);
-
-        verify(mPreference).setChecked(true);
-    }
-
-    @Test
-    public void updateState_preferenceShouldNotBeChecked() {
-        SystemProperties.set(BLUETOOTH_BTSNOOP_ENABLE_PROPERTY, Boolean.toString(false));
-        mController.updateState(mPreference);
-
-        verify(mPreference).setChecked(false);
+    public void updateState_preferenceShouldBeSetToRightValue() {
+        for (int i = 0; i < mListValues.length; ++i) {
+            SystemProperties.set(BLUETOOTH_BTSNOOP_LOG_MODE_PROPERTY, mListValues[i].toString());
+            mController.updateState(mPreference);
+            assertThat(mPreference.getValue()).isEqualTo(mListValues[i].toString());
+            assertThat(mPreference.getSummary()).isEqualTo(mListEntries[i].toString());
+        }
     }
 
     @Test
     public void onDeveloperOptionsDisabled_shouldDisablePreference() {
         mController.onDeveloperOptionsDisabled();
-
-        verify(mPreference).setEnabled(false);
-        verify(mPreference).setChecked(false);
+        assertThat(mPreference.isEnabled()).isFalse();
+        assertThat(mPreference.getValue()).isEqualTo(
+                mListValues[mController.getDefaultModeIndex()]
+                        .toString());
+        assertThat(mPreference.getSummary()).isEqualTo(
+                mListEntries[mController.getDefaultModeIndex()]
+                        .toString());
     }
 }
diff --git a/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogFragmentTest.java b/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogFragmentTest.java
index 17516e9..d84d665 100644
--- a/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogFragmentTest.java
@@ -119,7 +119,7 @@
         ERROR_DIALOG_TYPE errorType = null;
 
         @Override
-        public void stopScanningAndMaybePopErrorDialog(ERROR_DIALOG_TYPE type) {
+        public void stopScanningAndPopErrorDialog(ERROR_DIALOG_TYPE type) {
             bCalledStopAndPop = true;
             errorType = type;
         }
@@ -152,25 +152,19 @@
     }
 
     @Test
-    public void updateAccessPointList_onUserSelectionConnectSuccess_shouldCloseTheDialog() {
+    public void updateAccessPointList_onUserSelectionConnectSuccess_shouldFinishActivity() {
         // Assert
-        FakeNetworkRequestDialogFragment fakeFragment = new FakeNetworkRequestDialogFragment();
-        FakeNetworkRequestDialogFragment spyFakeFragment = spy(fakeFragment);
-
-        List<AccessPoint> accessPointList = createAccessPointList();
-        when(spyFakeFragment.getAccessPointList()).thenReturn(accessPointList);
-
-        spyFakeFragment.show(mActivity.getSupportFragmentManager(), null);
+        final FragmentActivity spyActivity = spy(mActivity);
+        when(networkRequestDialogFragment.getActivity()).thenReturn(spyActivity);
+        networkRequestDialogFragment.show(spyActivity.getSupportFragmentManager(), "onUserSelectionConnectSuccess");
 
         // Action
-        WifiConfiguration config = new WifiConfiguration();
+        final WifiConfiguration config = new WifiConfiguration();
         config.SSID = "Test AP 3";
-        spyFakeFragment.onUserSelectionConnectSuccess(config);
+        networkRequestDialogFragment.onUserSelectionConnectSuccess(config);
 
         // Check
-        ShadowLooper.getShadowMainLooper().runToEndOfTasks();
-        assertThat(fakeFragment.bCalledStopAndPop).isTrue();
-        assertThat(fakeFragment.errorType).isNull();
+        verify(spyActivity).finish();
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
index e80e931..308d4b5 100644
--- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
@@ -686,6 +686,15 @@
     }
 
     @Test
+    public void canShareNetwork_noNetwork() {
+        when(mockAccessPoint.getConfig()).thenReturn(null);
+
+        displayAndResume();
+
+        verify(mockButtonsPref).setButton3Visible(false);
+    }
+
+    @Test
     public void canModifyNetwork_saved() {
         assertThat(mController.canModifyNetwork()).isTrue();
     }
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppChooseSavedWifiNetworkFragmentTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppChooseSavedWifiNetworkFragmentTest.java
new file mode 100644
index 0000000..d2f6e6c
--- /dev/null
+++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppChooseSavedWifiNetworkFragmentTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2019 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 androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
+
+import static com.android.settings.wifi.dpp.WifiDppUtils.TAG_FRAGMENT_ADD_DEVICE;
+import static com.android.settings.wifi.dpp.WifiDppUtils.TAG_FRAGMENT_CHOOSE_SAVED_WIFI_NETWORK;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+
+import androidx.fragment.app.FragmentManager;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.rule.ActivityTestRule;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class WifiDppChooseSavedWifiNetworkFragmentTest {
+    // Valid Wi-Fi DPP QR code
+    private static final String VALID_WIFI_DPP_QR_CODE = "DPP:I:SN=4774LH2b4044;M:010203040506;K:"
+            + "MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;";
+
+    // Keys used to lookup resources by name (see the resourceId/resourceString helper methods).
+    private static final String STRING = "string";
+    private static final String WIFI_DPP_CHOOSE_DIFFERENT_NETWORK =
+            "wifi_dpp_choose_different_network";
+    private static final String CANCEL = "cancel";
+
+    @Rule
+    public final ActivityTestRule<WifiDppConfiguratorActivity> mActivityRule =
+            new ActivityTestRule<>(WifiDppConfiguratorActivity.class, /* initialTouchMode */true,
+            /* launchActivity */ false);
+
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        mContext = InstrumentationRegistry.getTargetContext();
+    }
+
+    @Test
+    public void clickCancelButton_configuratorQrCodeScannerIntent_shouldPopBackStack() {
+        final Intent intent =
+                new Intent(WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_SCANNER);
+        intent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY, "WEP");
+        intent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, "GoogleGuest");
+        intent.putExtra(WifiDppUtils.EXTRA_WIFI_PRE_SHARED_KEY, "password");
+        final WifiDppConfiguratorActivity hostActivity = mActivityRule.launchActivity(intent);
+
+        // Go to WifiDppChooseSavedWifiNetworkFragment and click the cancel button
+        final FragmentManager fragmentManager = hostActivity.getSupportFragmentManager();
+        final WifiQrCode wifiQrCode = new WifiQrCode(VALID_WIFI_DPP_QR_CODE);
+        hostActivity.runOnUiThread(() ->
+            ((WifiDppConfiguratorActivity)hostActivity).onScanWifiDppSuccess(wifiQrCode)
+        );
+        onView(withText(resourceString(WIFI_DPP_CHOOSE_DIFFERENT_NETWORK))).perform(click());
+        onView(withText(resourceString(CANCEL))).perform(click());
+
+        assertThat(fragmentManager.findFragmentByTag(TAG_FRAGMENT_ADD_DEVICE)).isNotNull();
+        assertThat(fragmentManager.findFragmentByTag(TAG_FRAGMENT_CHOOSE_SAVED_WIFI_NETWORK))
+                .isNull();
+    }
+
+    @Test
+    public void clickCancelButton_processWifiDppQrCodeIntent_shouldFinish() {
+        final Intent intent =
+                new Intent(WifiDppConfiguratorActivity.ACTION_PROCESS_WIFI_DPP_QR_CODE);
+        intent.putExtra(WifiDppUtils.EXTRA_QR_CODE, VALID_WIFI_DPP_QR_CODE);
+        final WifiDppConfiguratorActivity hostActivity = mActivityRule.launchActivity(intent);
+
+        onView(withText(resourceString(CANCEL))).perform(click());
+
+        assertThat(hostActivity.isFinishing()).isEqualTo(true);
+    }
+
+    private int resourceId(String type, String name) {
+        return mContext.getResources().getIdentifier(name, type, mContext.getPackageName());
+    }
+
+    /** Similar to {@link #resourceId}, but for accessing R.string.<name> values. */
+    private String resourceString(String name) {
+        return mContext.getResources().getString(resourceId(STRING, name));
+    }
+}