Merge "Change suggestion dismiss day"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 9320c72..c5c788d 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2554,7 +2554,7 @@
 
         <receiver android:name=".sim.SimSelectNotification">
             <intent-filter>
-                <action android:name="android.intent.action.SIM_STATE_CHANGED"/>
+                <action android:name="android.intent.action.PRIMARY_SUBSCRIPTION_LIST_CHANGED"/>
             </intent-filter>
         </receiver>
 
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index a93fb76..36230d1 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -22,6 +22,8 @@
 import static android.text.format.DateUtils.FORMAT_SHOW_DATE;
 
 import android.annotation.Nullable;
+import android.app.ActionBar;
+import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.AppGlobals;
 import android.app.IActivityManager;
@@ -92,6 +94,7 @@
 import androidx.annotation.StringRes;
 import androidx.core.graphics.drawable.IconCompat;
 import androidx.fragment.app.Fragment;
+import androidx.lifecycle.Lifecycle;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceGroup;
 
@@ -101,6 +104,7 @@
 import com.android.settings.core.FeatureFlags;
 import com.android.settings.development.featureflags.FeatureFlagPersistent;
 import com.android.settings.password.ChooseLockSettingsHelper;
+import com.android.settingslib.widget.ActionBarShadowController;
 
 import java.net.InetAddress;
 import java.util.Iterator;
@@ -1023,4 +1027,28 @@
         ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
         return !(am.isLowRamDevice() && (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q));
     }
+
+    /**
+     * Adds a shadow appear/disappear animation to action bar scroll.
+     *
+     * <p/>
+     * This method must be called after {@link Fragment#onCreate(Bundle)}.
+     */
+    public static void setActionBarShadowAnimation(Activity activity, Lifecycle lifecycle,
+            View scrollView) {
+        if (activity == null) {
+            Log.w(TAG, "No activity, cannot style actionbar.");
+            return;
+        }
+        final ActionBar actionBar = activity.getActionBar();
+        if (actionBar == null) {
+            Log.w(TAG, "No actionbar, cannot style actionbar.");
+            return;
+        }
+        actionBar.setElevation(0);
+
+        if (lifecycle != null && scrollView != null) {
+            ActionBarShadowController.attachToView(activity, lifecycle, scrollView);
+        }
+    }
 }
diff --git a/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java b/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java
index 7aaf80d..c32a33d 100644
--- a/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java
+++ b/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java
@@ -21,6 +21,7 @@
 import android.provider.SearchIndexableResource;
 
 import com.android.settings.R;
+import com.android.settings.Utils;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.notification.EmergencyBroadcastPreferenceController;
 import com.android.settings.search.BaseSearchIndexProvider;
@@ -85,6 +86,10 @@
 
         super.onResume();
         mIsFirstLaunch = false;
+
+        if (mRecentAppsPreferenceController.isAvailable()) {
+            Utils.setActionBarShadowAnimation(getActivity(), getSettingsLifecycle(), getListView());
+        }
     }
 
     @Override
diff --git a/src/com/android/settings/privacy/PrivacyDashboardFragment.java b/src/com/android/settings/privacy/PrivacyDashboardFragment.java
index be6701e..fa21f9d 100644
--- a/src/com/android/settings/privacy/PrivacyDashboardFragment.java
+++ b/src/com/android/settings/privacy/PrivacyDashboardFragment.java
@@ -16,25 +16,22 @@
 
 package com.android.settings.privacy;
 
-import android.app.ActionBar;
-import android.app.Activity;
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.os.Bundle;
 import android.provider.SearchIndexableResource;
-import android.util.Log;
 import android.view.View;
 
 import androidx.annotation.VisibleForTesting;
 
 import com.android.settings.R;
+import com.android.settings.Utils;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.notification.LockScreenNotificationPreferenceController;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.search.SearchIndexable;
-import com.android.settingslib.widget.ActionBarShadowController;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -87,29 +84,11 @@
     @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
-        styleActionBar();
+        Utils.setActionBarShadowAnimation(getActivity(), getSettingsLifecycle(), getListView());
         initLoadingBar();
     }
 
     @VisibleForTesting
-    void styleActionBar() {
-        final Activity activity = getActivity();
-        final ActionBar actionBar = activity.getActionBar();
-        final Lifecycle lifecycle = getSettingsLifecycle();
-        final View scrollView = getListView();
-
-        if (actionBar == null) {
-            Log.w(TAG, "No actionbar, cannot style actionbar.");
-            return;
-        }
-
-        actionBar.setElevation(0);
-        if (lifecycle != null && scrollView != null) {
-            ActionBarShadowController.attachToView(activity, lifecycle, scrollView);
-        }
-    }
-
-    @VisibleForTesting
     void initLoadingBar() {
         mProgressHeader = setPinnedHeaderView(R.layout.progress_header);
         mProgressAnimation = mProgressHeader.findViewById(R.id.progress_bar_animation);
diff --git a/src/com/android/settings/sim/SimSelectNotification.java b/src/com/android/settings/sim/SimSelectNotification.java
index cf67f5e..891d171 100644
--- a/src/com/android/settings/sim/SimSelectNotification.java
+++ b/src/com/android/settings/sim/SimSelectNotification.java
@@ -16,6 +16,12 @@
 
 package com.android.settings.sim;
 
+import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_ID;
+import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_FOR_ALL_TYPES;
+import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE;
+import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA;
+import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE;
+
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -23,19 +29,12 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
-import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.util.Log;
 
-import androidx.core.app.NotificationCompat;
-
-import com.android.internal.telephony.IccCardConstants;
 import com.android.settings.R;
 import com.android.settings.Settings.SimSettingsActivity;
-import com.android.settings.Utils;
 
-import java.util.List;
+import androidx.core.app.NotificationCompat;
 
 public class SimSelectNotification extends BroadcastReceiver {
     private static final String TAG = "SimSelectNotification";
@@ -46,71 +45,24 @@
 
     @Override
     public void onReceive(Context context, Intent intent) {
-        final TelephonyManager telephonyManager = (TelephonyManager)
-                context.getSystemService(Context.TELEPHONY_SERVICE);
-        final SubscriptionManager subscriptionManager = SubscriptionManager.from(context);
-        final int numSlots = telephonyManager.getSimCount();
-
-        // Do not create notifications on single SIM devices or when provisioning i.e. Setup Wizard.
-        if (numSlots < 2 || !Utils.isDeviceProvisioned(context)) {
-            return;
-        }
-
         // Cancel any previous notifications
         cancelNotification(context);
-
-        // If sim state is not ABSENT or LOADED then ignore
-        String simStatus = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
-        if (!(IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(simStatus) ||
-                IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(simStatus))) {
-            Log.d(TAG, "sim state is not Absent or Loaded");
-            return;
-        } else {
-            Log.d(TAG, "simstatus = " + simStatus);
-        }
-
-        int state;
-        for (int i = 0; i < numSlots; i++) {
-            state = telephonyManager.getSimState(i);
-            if (!(state == TelephonyManager.SIM_STATE_ABSENT
-                    || state == TelephonyManager.SIM_STATE_READY
-                    || state == TelephonyManager.SIM_STATE_UNKNOWN)) {
-                Log.d(TAG, "All sims not in valid state yet");
-                return;
-            }
-        }
-
-        List<SubscriptionInfo> sil = subscriptionManager.getActiveSubscriptionInfoList(true);
-        if (sil == null || sil.size() < 1) {
-            Log.d(TAG, "Subscription list is empty");
-            return;
-        }
-
-        // Clear defaults for any subscriptions which no longer exist
-        subscriptionManager.clearDefaultsForInactiveSubIds();
-
-        boolean dataSelected = SubscriptionManager.isUsableSubIdValue(
-                SubscriptionManager.getDefaultDataSubscriptionId());
-        boolean smsSelected = SubscriptionManager.isUsableSubIdValue(
-                SubscriptionManager.getDefaultSmsSubscriptionId());
-
-        // If data and sms defaults are selected, dont show notification (Calls default is optional)
-        if (dataSelected && smsSelected) {
-            Log.d(TAG, "Data & SMS default sims are selected. No notification");
-            return;
-        }
-
         // Create a notification to tell the user that some defaults are missing
         createNotification(context);
 
-        if (sil.size() == 1) {
+        int dialogType = intent.getIntExtra(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE,
+                EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE);
+        if (dialogType == EXTRA_DEFAULT_SUBSCRIPTION_SELECT_FOR_ALL_TYPES) {
+            int subId = intent.getIntExtra(EXTRA_DEFAULT_SUBSCRIPTION_ID,
+                    SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
+            int slotIndex = SubscriptionManager.getSlotIndex(subId);
             // If there is only one subscription, ask if user wants to use if for everything
             Intent newIntent = new Intent(context, SimDialogActivity.class);
             newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             newIntent.putExtra(SimDialogActivity.DIALOG_TYPE_KEY, SimDialogActivity.PREFERRED_PICK);
-            newIntent.putExtra(SimDialogActivity.PREFERRED_SIM, sil.get(0).getSimSlotIndex());
+            newIntent.putExtra(SimDialogActivity.PREFERRED_SIM, slotIndex);
             context.startActivity(newIntent);
-        } else if (!dataSelected) {
+        } else if (dialogType == EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA) {
             // If there are mulitple, ensure they pick default data
             Intent newIntent = new Intent(context, SimDialogActivity.class);
             newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
index 4535599..905d3a0 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
@@ -45,6 +45,7 @@
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
+import androidx.annotation.StringRes;
 import androidx.lifecycle.ViewModelProviders;
 
 import com.android.settings.R;
@@ -52,12 +53,17 @@
 import com.android.settings.wifi.qrcode.QrCamera;
 import com.android.settings.wifi.qrcode.QrDecorateView;
 
+import com.android.settingslib.wifi.AccessPoint;
+import com.android.settingslib.wifi.WifiTracker;
+import com.android.settingslib.wifi.WifiTrackerFactory;
+
 import java.util.List;
 
 public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment implements
         SurfaceTextureListener,
         QrCamera.ScannerCallback,
-        WifiManager.ActionListener {
+        WifiManager.ActionListener,
+        WifiTracker.WifiListener {
     private static final String TAG = "WifiDppQrCodeScannerFragment";
 
     /** Message sent to hide error message */
@@ -80,6 +86,8 @@
     private static final String KEY_LATEST_ERROR_CODE = "key_latest_error_code";
     private static final String KEY_WIFI_CONFIGURATION = "key_wifi_configuration";
 
+    private static final int ARG_RESTART_CAMERA = 1;
+
     private ProgressBar mProgressBar;
     private QrCamera mCamera;
     private TextureView mTextureView;
@@ -100,6 +108,68 @@
 
     private int mLatestStatusCode = WifiDppUtils.EASY_CONNECT_EVENT_FAILURE_NONE;
 
+    private WifiTracker mWifiTracker;
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MESSAGE_HIDE_ERROR_MESSAGE:
+                    mErrorMessage.setVisibility(View.INVISIBLE);
+                    break;
+
+                case MESSAGE_SHOW_ERROR_MESSAGE:
+                    final String errorMessage = (String) msg.obj;
+
+                    mErrorMessage.setVisibility(View.VISIBLE);
+                    mErrorMessage.setText(errorMessage);
+                    mErrorMessage.sendAccessibilityEvent(
+                            AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+
+                    // Cancel any pending messages to hide error view and requeue the message so
+                    // user has time to see error
+                    removeMessages(MESSAGE_HIDE_ERROR_MESSAGE);
+                    sendEmptyMessageDelayed(MESSAGE_HIDE_ERROR_MESSAGE,
+                            SHOW_ERROR_MESSAGE_INTERVAL);
+
+                    if (msg.arg1 == ARG_RESTART_CAMERA) {
+                        mProgressBar.setVisibility(View.INVISIBLE);
+                        restartCamera();
+                    }
+                    break;
+
+                case MESSAGE_SCAN_WIFI_DPP_SUCCESS:
+                    mErrorMessage.setVisibility(View.INVISIBLE);
+
+                    if (mScanWifiDppSuccessListener == null) {
+                        return;
+                    }
+                    mScanWifiDppSuccessListener.onScanWifiDppSuccess((WifiQrCode)msg.obj);
+
+                    if (!mIsConfiguratorMode) {
+                        mProgressBar.setVisibility(View.VISIBLE);
+                        startWifiDppEnrolleeInitiator((WifiQrCode)msg.obj);
+                        updateEnrolleeSummary();
+                        mSummary.sendAccessibilityEvent(
+                                AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+                    }
+                    break;
+
+                case MESSAGE_SCAN_ZXING_WIFI_FORMAT_SUCCESS:
+                    mErrorMessage.setVisibility(View.INVISIBLE);
+
+                    final WifiNetworkConfig wifiNetworkConfig = (WifiNetworkConfig)msg.obj;
+                    mWifiConfiguration = wifiNetworkConfig.getWifiConfigurationOrNull();
+                    wifiNetworkConfig.connect(getContext(),
+                            /* listener */ WifiDppQrCodeScannerFragment.this);
+                    break;
+
+                default:
+                    return;
+            }
+        }
+    };
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -175,6 +245,9 @@
     public void onActivityCreated(Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
 
+        mWifiTracker = WifiTrackerFactory.create(getActivity(), /* wifiListener */ this,
+                getSettingsLifecycle(), /* includeSaved */ false, /* includeScans */ true);
+
         // setTitle for Talkback
         if (mIsConfiguratorMode) {
             getActivity().setTitle(R.string.wifi_dpp_add_device_to_network);
@@ -291,7 +364,7 @@
         try {
             mWifiQrCode = new WifiQrCode(qrCode);
         } catch (IllegalArgumentException e) {
-            mHandler.sendEmptyMessage(MESSAGE_SHOW_ERROR_MESSAGE);
+            showErrorMessage(R.string.wifi_dpp_could_not_detect_valid_qr_code);
             return false;
         }
 
@@ -301,14 +374,14 @@
         if (!mIsConfiguratorMode && WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG.equals(scheme)) {
             final String ssidQrCode = mWifiQrCode.getWifiNetworkConfig().getSsid();
             if (!TextUtils.isEmpty(mSsid) && !mSsid.equals(ssidQrCode)) {
-                mHandler.sendEmptyMessage(MESSAGE_SHOW_ERROR_MESSAGE);
+                showErrorMessage(R.string.wifi_dpp_could_not_detect_valid_qr_code);
                 return false;
             }
         }
 
         // It's impossible to provision other device with ZXing Wi-Fi Network config format
         if (mIsConfiguratorMode && WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG.equals(scheme)) {
-            mHandler.sendEmptyMessage(MESSAGE_SHOW_ERROR_MESSAGE);
+            showErrorMessage(R.string.wifi_dpp_could_not_detect_valid_qr_code);
             return false;
         }
 
@@ -385,59 +458,18 @@
         }
     }
 
-    public void showErrorMessage(String message) {
-        mErrorMessage.setVisibility(View.VISIBLE);
-        mErrorMessage.setText(message);
-        mErrorMessage.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
-
-        mHandler.removeMessages(MESSAGE_HIDE_ERROR_MESSAGE);
-        mHandler.sendEmptyMessageDelayed(MESSAGE_HIDE_ERROR_MESSAGE,
-                SHOW_ERROR_MESSAGE_INTERVAL);
+    private void showErrorMessage(@StringRes int messageResId) {
+        final Message message = mHandler.obtainMessage(MESSAGE_SHOW_ERROR_MESSAGE,
+                getString(messageResId));
+        message.sendToTarget();
     }
 
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MESSAGE_HIDE_ERROR_MESSAGE:
-                    mErrorMessage.setVisibility(View.INVISIBLE);
-                    break;
-
-                case MESSAGE_SHOW_ERROR_MESSAGE:
-                    showErrorMessage(getString(R.string.wifi_dpp_could_not_detect_valid_qr_code));
-                    break;
-
-                case MESSAGE_SCAN_WIFI_DPP_SUCCESS:
-                    mErrorMessage.setVisibility(View.INVISIBLE);
-
-                    if (mScanWifiDppSuccessListener == null) {
-                        return;
-                    }
-                    mScanWifiDppSuccessListener.onScanWifiDppSuccess((WifiQrCode)msg.obj);
-
-                    if (!mIsConfiguratorMode) {
-                        mProgressBar.setVisibility(View.VISIBLE);
-                        startWifiDppEnrolleeInitiator((WifiQrCode)msg.obj);
-                        updateEnrolleeSummary();
-                        mSummary.sendAccessibilityEvent(
-                                AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
-                    }
-                    break;
-
-                case MESSAGE_SCAN_ZXING_WIFI_FORMAT_SUCCESS:
-                    mErrorMessage.setVisibility(View.INVISIBLE);
-
-                    final WifiNetworkConfig wifiNetworkConfig = (WifiNetworkConfig)msg.obj;
-                    mWifiConfiguration = wifiNetworkConfig.getWifiConfigurationOrNull();
-                    wifiNetworkConfig.connect(getContext(),
-                            /* listener */ WifiDppQrCodeScannerFragment.this);
-                    break;
-
-                default:
-                    return;
-            }
-        }
-    };
+    private void showErrorMessageAndRestartCamera(@StringRes int messageResId) {
+        final Message message = mHandler.obtainMessage(MESSAGE_SHOW_ERROR_MESSAGE,
+                getString(messageResId));
+        message.arg1 = ARG_RESTART_CAMERA;
+        message.sendToTarget();
+    }
 
     @Override
     public void onSaveInstanceState(Bundle outState) {
@@ -468,9 +500,7 @@
             Log.e(TAG, "Invalid networkId " + newNetworkId);
             mLatestStatusCode = EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_GENERIC;
             updateEnrolleeSummary();
-            mProgressBar.setVisibility(View.INVISIBLE);
-            showErrorMessage(getString(R.string.wifi_dpp_check_connection_try_again));
-            restartCamera();
+            showErrorMessageAndRestartCamera(R.string.wifi_dpp_check_connection_try_again);
         }
 
         @Override
@@ -482,23 +512,22 @@
         public void onFailure(int code) {
             Log.d(TAG, "EasyConnectEnrolleeStatusCallback.onFailure " + code);
 
+            int errorMessageResId = 0;
             switch (code) {
                 case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_INVALID_URI:
-                    showErrorMessage(getString(R.string.wifi_dpp_could_not_detect_valid_qr_code));
+                    errorMessageResId = R.string.wifi_dpp_could_not_detect_valid_qr_code;
                     break;
 
                 case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_AUTHENTICATION:
-                    showErrorMessage(
-                            getString(R.string.wifi_dpp_failure_authentication_or_configuration));
+                    errorMessageResId = R.string.wifi_dpp_failure_authentication_or_configuration;
                     break;
 
                 case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_NOT_COMPATIBLE:
-                    showErrorMessage(getString(R.string.wifi_dpp_failure_not_compatible));
+                    errorMessageResId = R.string.wifi_dpp_failure_not_compatible;
                     break;
 
                 case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_CONFIGURATION:
-                    showErrorMessage(
-                            getString(R.string.wifi_dpp_failure_authentication_or_configuration));
+                    errorMessageResId = R.string.wifi_dpp_failure_authentication_or_configuration;
                     break;
 
                 case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_BUSY:
@@ -515,11 +544,11 @@
                     return;
 
                 case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_TIMEOUT:
-                    showErrorMessage(getString(R.string.wifi_dpp_failure_timeout));
+                    errorMessageResId = R.string.wifi_dpp_failure_timeout;
                     break;
 
                 case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_GENERIC:
-                    showErrorMessage(getString(R.string.wifi_dpp_failure_generic));
+                    errorMessageResId = R.string.wifi_dpp_failure_generic;
                     break;
 
                 case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED:
@@ -536,8 +565,7 @@
 
             mLatestStatusCode = code;
             updateEnrolleeSummary();
-            mProgressBar.setVisibility(View.INVISIBLE);
-            restartCamera();
+            showErrorMessageAndRestartCamera(errorMessageResId);
         }
 
         @Override
@@ -555,21 +583,39 @@
 
     @Override
     public void onSuccess() {
-        final Intent resultIntent = new Intent();
-        resultIntent.putExtra(WifiDialogActivity.KEY_WIFI_CONFIGURATION, mWifiConfiguration);
+        if (isEnrollingWifiNetworkReachable()) {
+            final Intent resultIntent = new Intent();
+            resultIntent.putExtra(WifiDialogActivity.KEY_WIFI_CONFIGURATION, mWifiConfiguration);
 
-        final Activity hostActivity = getActivity();
-        hostActivity.setResult(Activity.RESULT_OK, resultIntent);
-        hostActivity.finish();
+            final Activity hostActivity = getActivity();
+            hostActivity.setResult(Activity.RESULT_OK, resultIntent);
+            hostActivity.finish();
+        } else {
+            Log.d(TAG, "Enroll Wi-Fi network succeeded but it's not reachable");
+            showErrorMessageAndRestartCamera(R.string.wifi_dpp_check_connection_try_again);
+        }
     }
 
     @Override
     public void onFailure(int reason) {
         Log.d(TAG, "Wi-Fi connect onFailure reason - " + reason);
+        showErrorMessageAndRestartCamera(R.string.wifi_dpp_check_connection_try_again);
+    }
 
-        mProgressBar.setVisibility(View.INVISIBLE);
-        showErrorMessage(getString(R.string.wifi_dpp_check_connection_try_again));
-        restartCamera();
+    private boolean isEnrollingWifiNetworkReachable() {
+        if (mWifiConfiguration == null) {
+            Log.e(TAG, "Connect succeeded but lost WifiConfiguration");
+            return false;
+        }
+
+        final List<AccessPoint> scannedAccessPoints = mWifiTracker.getAccessPoints();
+        for (AccessPoint accessPoint : scannedAccessPoints) {
+            if (accessPoint.matches(mWifiConfiguration) &&
+                    accessPoint.isReachable()) {
+                return true;
+            }
+        }
+        return false;
     }
 
     // Check is Easy Connect handshaking or not
@@ -610,4 +656,25 @@
             mSummary.setText(description);
         }
     }
+
+    /** Called when the state of Wifi has changed. */
+    @Override
+    public void onWifiStateChanged(int state) {
+        // Do nothing.
+    }
+
+    /** Called when the connection state of wifi has changed. */
+    @Override
+    public void onConnectedChanged() {
+        // Do nothing.
+    }
+
+    /**
+     * Called to indicate the list of AccessPoints has been updated and
+     * getAccessPoints should be called to get the latest information.
+     */
+    @Override
+    public void onAccessPointsChanged() {
+        // Do nothing.
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/UtilsTest.java b/tests/robotests/src/com/android/settings/UtilsTest.java
index 37186ca..3d3aff4 100644
--- a/tests/robotests/src/com/android/settings/UtilsTest.java
+++ b/tests/robotests/src/com/android/settings/UtilsTest.java
@@ -28,6 +28,8 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.ActionBar;
+import android.app.Activity;
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
@@ -51,15 +53,18 @@
 import android.os.storage.VolumeInfo;
 import android.util.IconDrawableFactory;
 import android.widget.EditText;
+import android.widget.ScrollView;
 import android.widget.TextView;
 
 import androidx.core.graphics.drawable.IconCompat;
+import androidx.fragment.app.FragmentActivity;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 
@@ -259,4 +264,21 @@
     public void isPackageEnabled_noApp_returnFalse() {
         assertThat(Utils.isPackageEnabled(mContext, PACKAGE_NAME)).isFalse();
     }
+
+    @Test
+    public void setActionBarShadowAnimation_nullParameters_shouldNotCrash() {
+        // no crash here
+        Utils.setActionBarShadowAnimation(null, null, null);
+    }
+
+    @Test
+    public void setActionBarShadowAnimation_shouldSetElevationToZero() {
+        final FragmentActivity activity = Robolectric.setupActivity(FragmentActivity.class);
+        final ActionBar actionBar = activity.getActionBar();
+
+        Utils.setActionBarShadowAnimation(activity, activity.getLifecycle(),
+                new ScrollView(mContext));
+
+        assertThat(actionBar.getElevation()).isEqualTo(0.f);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/privacy/PrivacyDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/privacy/PrivacyDashboardFragmentTest.java
index 482eaeb..80f3900 100644
--- a/tests/robotests/src/com/android/settings/privacy/PrivacyDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/privacy/PrivacyDashboardFragmentTest.java
@@ -80,10 +80,10 @@
     }
 
     @Test
-    public void onViewCreated_shouldCallStyleActionBar() {
+    public void onViewCreated_shouldSetActionBarShadowAnimation() {
         mFragment.onViewCreated(new View(mContext), new Bundle());
 
-        verify(mFragment).styleActionBar();
+        assertThat(mFragment.getActivity().getActionBar().getElevation()).isEqualTo(0.f);
     }
 
     @Test