Implement Wi-Fi QR code scanner flow.

1. Implements WifiNetworkConfig Wi-Fi connection method
2. Shows error message when the QR code is not valid and hides it after 2s
3. In configurator mode, launchs AddDeviceFragment for a valid QR code
4. In enrollee mode, connects Wi-Fi for a valid QR code

Bug: 118794978
Test: manual test
      atest WifiQrCodetest
      atest WifiDppConfiguratorActivityTest
      atest WifiDppEnrolleeActivityTest
      atest WifiDppQrCodeScannerFragmentTest

Change-Id: Ie4731b22df295c60906156d33ea28dad9c084ce4
diff --git a/res/layout/wifi_dpp_qrcode_scanner_fragment.xml b/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
index 913998f..93fd1eb 100644
--- a/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
+++ b/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
@@ -39,10 +39,13 @@
             android:layout_gravity="center"/>
     </com.android.settings.wifi.qrcode.QrPreviewLayout>
 
-    <TextView android:id="@+id/error_message"
+    <TextView
+        android:id="@+id/error_message"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_gravity="center"/>
+        android:layout_gravity="center"
+        android:layout_marginTop="8dp"
+        android:textColor="?android:attr/colorError"/>
 
 </LinearLayout>
 
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f7eedba..a45be06 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2090,6 +2090,8 @@
     <string name="wifi_dpp_share_wifi">Share Wi\u2011Fi</string>
     <!-- Hint for the user to use another device to scan QR code on screen to join Wi-Fi [CHAR LIMIT=NONE] -->
     <string name="wifi_dpp_scan_qr_code_with_another_device">Scan this QR code with another device to join \u201c<xliff:g id="ssid" example="OfficeWifi">%1$s</xliff:g>\u201d</string>
+    <!-- Hint for QR code detection [CHAR LIMIT=NONE]  -->
+    <string name="wifi_dpp_could_not_detect_valid_qr_code">Could not detect valid QR code</string>
     <!-- Label for the check box to share a network with other users on the same device -->
     <string name="wifi_shared">Share with other device users</string>
     <!-- Hint for unchanged fields -->
diff --git a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
index 6c95f09..e89ebaa 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
@@ -49,7 +49,9 @@
  */
 public class WifiDppConfiguratorActivity extends InstrumentedActivity implements
         WifiNetworkConfig.Retriever,
-        WifiDppQrCodeGeneratorFragment.OnQrCodeGeneratorFragmentAddButtonClickedListener {
+        WifiDppQrCodeGeneratorFragment.OnQrCodeGeneratorFragmentAddButtonClickedListener,
+        WifiDppQrCodeScannerFragment.OnScanWifiDppSuccessListener,
+        WifiDppQrCodeScannerFragment.OnScanZxingWifiFormatSuccessListener {
     private static final String TAG = "WifiDppConfiguratorActivity";
 
     public static final String ACTION_CONFIGURATOR_QR_CODE_SCANNER =
@@ -64,6 +66,12 @@
     /** The Wi-Fi network which will be configured */
     private WifiNetworkConfig mWifiNetworkConfig;
 
+    /** The public key from Wi-Fi DPP QR code */
+    private String mPublicKey;
+
+    /** The information from Wi-Fi DPP QR code */
+    private String mInformation;
+
     @Override
     public int getMetricsCategory() {
         return MetricsProto.MetricsEvent.SETTINGS_WIFI_DPP_CONFIGURATOR;
@@ -127,8 +135,8 @@
             return;
         }
 
-        WifiDppQrCodeScannerFragment fragment = new WifiDppQrCodeScannerFragment();
-        FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
+        final WifiDppQrCodeScannerFragment fragment = new WifiDppQrCodeScannerFragment();
+        final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
 
         fragmentTransaction.replace(R.id.fragment_container, fragment,
                 WifiDppUtils.TAG_FRAGMENT_QR_CODE_SCANNER);
@@ -145,8 +153,8 @@
             return;
         }
 
-        WifiDppQrCodeGeneratorFragment fragment = new WifiDppQrCodeGeneratorFragment();
-        FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
+        final WifiDppQrCodeGeneratorFragment fragment = new WifiDppQrCodeGeneratorFragment();
+        final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
 
         fragmentTransaction.replace(R.id.fragment_container, fragment,
                 WifiDppUtils.TAG_FRAGMENT_QR_CODE_GENERATOR);
@@ -160,9 +168,9 @@
             return;
         }
 
-        WifiDppChooseSavedWifiNetworkFragment fragment =
+        final WifiDppChooseSavedWifiNetworkFragment fragment =
                 new WifiDppChooseSavedWifiNetworkFragment();
-        FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
+        final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
 
         fragmentTransaction.replace(R.id.fragment_container, fragment,
                 WifiDppUtils.TAG_FRAGMENT_CHOOSE_SAVED_WIFI_NETWORK);
@@ -172,11 +180,38 @@
         fragmentTransaction.commit();
     }
 
+    private void showAddDeviceFragment(boolean addToBackStack) {
+        // Avoid to replace the same fragment during configuration change
+        if (mFragmentManager.findFragmentByTag(
+                WifiDppUtils.TAG_FRAGMENT_ADD_DEVICE) != null) {
+            return;
+        }
+
+        final WifiDppAddDeviceFragment fragment =
+                new WifiDppAddDeviceFragment();
+        final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
+
+        fragmentTransaction.replace(R.id.fragment_container, fragment,
+                WifiDppUtils.TAG_FRAGMENT_ADD_DEVICE);
+        if (addToBackStack) {
+            fragmentTransaction.addToBackStack(/* name */ null);
+        }
+        fragmentTransaction.commit();
+    }
+
     @Override
     public WifiNetworkConfig getWifiNetworkConfig() {
         return mWifiNetworkConfig;
     }
 
+    public String getPublicKey() {
+        return mPublicKey;
+    }
+
+    public String getInformation() {
+        return mInformation;
+    }
+
     @Override
     public boolean setWifiNetworkConfig(WifiNetworkConfig config) {
         if(!WifiNetworkConfig.isValidConfig(config)) {
@@ -201,7 +236,26 @@
         return false;
     }
 
-    @Override public void onQrCodeGeneratorFragmentAddButtonClicked() {
+    @Override
+    public void onQrCodeGeneratorFragmentAddButtonClicked() {
         showQrCodeScannerFragment(/* addToBackStack */ true);
     }
+
+    @Override
+    public void onScanWifiDppSuccess(String publicKey, String information) {
+        mPublicKey = publicKey;
+        mInformation = information;
+        mWifiNetworkConfig = null;
+
+        showAddDeviceFragment(/* addToBackStack */ true);
+    }
+
+    @Override
+    public void onScanZxingWifiFormatSuccess(WifiNetworkConfig wifiNetworkConfig) {
+        mPublicKey = null;
+        mInformation = null;
+        mWifiNetworkConfig = new WifiNetworkConfig(wifiNetworkConfig);
+
+        showAddDeviceFragment(/* addToBackStack */ true);
+    }
 }
diff --git a/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivity.java b/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivity.java
index 920e736..584a819 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivity.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivity.java
@@ -16,9 +16,11 @@
 
 package com.android.settings.wifi.dpp;
 
+import android.provider.Settings;
 import android.app.ActionBar;
 import android.app.Activity;
 import android.content.Intent;
+import android.net.wifi.WifiManager;
 import android.os.Bundle;
 import android.util.Log;
 
@@ -36,7 +38,10 @@
  * To use intent action {@code ACTION_ENROLLEE_QR_CODE_SCANNER}, specify the SSID string of the
  * Wi-Fi network to be provisioned in {@code WifiDppUtils.EXTRA_WIFI_SSID}.
  */
-public class WifiDppEnrolleeActivity extends InstrumentedActivity {
+public class WifiDppEnrolleeActivity extends InstrumentedActivity implements
+        WifiManager.ActionListener,
+        WifiDppQrCodeScannerFragment.OnScanWifiDppSuccessListener,
+        WifiDppQrCodeScannerFragment.OnScanZxingWifiFormatSuccessListener {
     private static final String TAG = "WifiDppEnrolleeActivity";
 
     public static final String ACTION_ENROLLEE_QR_CODE_SCANNER =
@@ -101,4 +106,31 @@
         finish();
         return true;
     }
+
+    @Override
+    public void onScanWifiDppSuccess(String publicKey, String information) {
+        // TODO(b/1023597): starts DPP enrollee handshake here
+    }
+
+    @Override
+    public void onScanZxingWifiFormatSuccess(WifiNetworkConfig wifiNetworkConfig) {
+        wifiNetworkConfig.connect(/* context */ this, /* listener */ this);
+    }
+
+    @Override
+    public void onSuccess() {
+        startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
+        setResult(Activity.RESULT_OK);
+        finish();
+    }
+
+    @Override
+    public void onFailure(int reason) {
+        Log.d(TAG, "Wi-Fi connect onFailure reason - " + reason);
+
+        final Fragment fragment = mFragmentManager.findFragmentById(R.id.fragment_container);
+        if (fragment instanceof WifiDppQrCodeScannerFragment) {
+            ((WifiDppQrCodeScannerFragment)fragment).showErrorMessage(true);
+        }
+    }
 }
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeBaseFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeBaseFragment.java
index 6792dee..50e3ee5 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeBaseFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeBaseFragment.java
@@ -102,6 +102,13 @@
     }
 
     /** optional, for WifiDppQrCodeScannerFragment */
+    protected void showErrorMessage(boolean show) {
+        if (mErrorMessage != null) {
+            mErrorMessage.setVisibility(show ? View.VISIBLE : View.INVISIBLE);
+        }
+    }
+
+    /** optional, for WifiDppQrCodeScannerFragment */
     protected void setErrorMessage(String errorMessage) {
         if (mErrorMessage != null) {
             mErrorMessage.setText(errorMessage);
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
index 8cd3c562..4ec19a6 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
@@ -25,6 +25,8 @@
 import android.graphics.Rect;
 import android.graphics.SurfaceTexture;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
 import android.text.TextUtils;
 import android.util.Size;
 import android.view.Menu;
@@ -41,16 +43,40 @@
 public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment implements
         SurfaceTextureListener,
         QrCamera.ScannerCallback {
+    private static final String TAG = "WifiDppQrCodeScannerFragment";
+
+    /** Message sent to hide error message */
+    private static final int MESSAGE_HIDE_ERROR_MESSAGE = 1;
+
+    /** Message sent to show error message */
+    private static final int MESSAGE_SHOW_ERROR_MESSAGE = 2;
+
+    /** Message sent to manipulate Wi-Fi DPP QR code */
+    private static final int MESSAGE_SCAN_WIFI_DPP_SUCCESS = 3;
+
+    /** Message sent to manipulate ZXing Wi-Fi QR code */
+    private static final int MESSAGE_SCAN_ZXING_WIFI_FORMAT_SUCCESS = 4;
+
+    private static final long SHOW_ERROR_MESSAGE_INTERVAL = 2000;
+    private static final long SHOW_SUCCESS_SQUARE_INTERVAL = 1000;
+
+    // Keys for Bundle usage
+    private static final String KEY_PUBLIC_KEY = "key_public_key";
+    private static final String KEY_INFORMATION = "key_information";
+
     private QrCamera mCamera;
     private TextureView mTextureView;
     private QrDecorateView mDecorateView;
 
     /** true if the fragment working for configurator, false enrollee*/
-    private final boolean mConfiguratorMode;
+    private final boolean mIsConfiguratorMode;
 
     /** The SSID of the Wi-Fi network which the user specify to enroll */
     private String mSsid;
 
+    /** QR code data scanned by camera */
+    private WifiQrCode mWifiQrCode;
+
     @Override
     protected int getLayout() {
         return R.layout.wifi_dpp_qrcode_scanner_fragment;
@@ -58,20 +84,32 @@
 
     @Override
     public int getMetricsCategory() {
-        if (mConfiguratorMode) {
+        if (mIsConfiguratorMode) {
             return MetricsProto.MetricsEvent.SETTINGS_WIFI_DPP_CONFIGURATOR;
         } else {
             return MetricsProto.MetricsEvent.SETTINGS_WIFI_DPP_ENROLLEE;
         }
     }
 
+    // Container Activity must implement this interface
+    public interface OnScanWifiDppSuccessListener {
+        public void onScanWifiDppSuccess(String publicKey, String information);
+    }
+    OnScanWifiDppSuccessListener mScanWifiDppSuccessListener;
+
+    // Container Activity must implement this interface
+    public interface OnScanZxingWifiFormatSuccessListener {
+        public void onScanZxingWifiFormatSuccess(WifiNetworkConfig wifiNetworkConfig);
+    }
+    OnScanZxingWifiFormatSuccessListener mScanScanZxingWifiFormatSuccessListener;
+
     /**
      * Configurator container activity of the fragment should create instance with this constructor.
      */
     public WifiDppQrCodeScannerFragment() {
         super();
 
-        mConfiguratorMode = true;
+        mIsConfiguratorMode = true;
     }
 
     /**
@@ -81,7 +119,7 @@
     public WifiDppQrCodeScannerFragment(String ssid) {
         super();
 
-        mConfiguratorMode = false;
+        mIsConfiguratorMode = false;
         mSsid = ssid;
     }
 
@@ -91,7 +129,7 @@
 
         setHeaderIconImageResource(R.drawable.ic_scan_24dp);
 
-        if (mConfiguratorMode) {
+        if (mIsConfiguratorMode) {
             setTitle(getString(R.string.wifi_dpp_add_device_to_network));
 
             WifiNetworkConfig wifiNetworkConfig = ((WifiNetworkConfig.Retriever) getActivity())
@@ -112,11 +150,30 @@
             setDescription(description);
         }
 
-        ActionBar actionBar = getActivity().getActionBar();
+        final ActionBar actionBar = getActivity().getActionBar();
         if (actionBar != null) {
             actionBar.setDisplayHomeAsUpEnabled(true);
             actionBar.show();
         }
+
+        setErrorMessage(getString(R.string.wifi_dpp_could_not_detect_valid_qr_code));
+        showErrorMessage(false);
+    }
+
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+
+        mScanWifiDppSuccessListener = (OnScanWifiDppSuccessListener) context;
+        mScanScanZxingWifiFormatSuccessListener = (OnScanZxingWifiFormatSuccessListener) context;
+    }
+
+    @Override
+    public void onDetach() {
+        mScanWifiDppSuccessListener = null;
+        mScanScanZxingWifiFormatSuccessListener = null;
+
+        super.onDetach();
     }
 
     @Override
@@ -173,10 +230,75 @@
     }
 
     @Override
+    public boolean isValid(String qrCode) {
+        try {
+            mWifiQrCode = new WifiQrCode(qrCode);
+        } catch (IllegalArgumentException e) {
+            mHandler.sendEmptyMessage(MESSAGE_SHOW_ERROR_MESSAGE);
+            return false;
+        }
+
+        final String scheme = mWifiQrCode.getScheme();
+
+        // When SSID is specified for enrollee, avoid to connect to the Wi-Fi of different SSID
+        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);
+                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);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * This method is only called when QrCamera.ScannerCallback.isValid returns true; 
+     */
+    @Override
     public void handleSuccessfulResult(String qrCode) {
+        switch (mWifiQrCode.getScheme()) {
+            case WifiQrCode.SCHEME_DPP:
+                handleWifiDpp(mWifiQrCode.getPublicKey(), mWifiQrCode.getInformation());
+                break;
+
+            case WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG:
+                handleZxingWifiFormat(mWifiQrCode.getWifiNetworkConfig());
+                break;
+
+            default:
+                // continue below
+        }
+    }
+
+    private void handleWifiDpp(String publicKey, String information) {
         destroyCamera();
         mDecorateView.setFocused(true);
-        // TODO(b/120243131): Add a network by Wi-Fi Network config shared via QR code.
+
+        final Bundle bundle = new Bundle();
+        bundle.putString(KEY_PUBLIC_KEY, publicKey);
+        bundle.putString(KEY_INFORMATION, information);
+
+        Message message = mHandler.obtainMessage(MESSAGE_SCAN_WIFI_DPP_SUCCESS);
+        message.setData(bundle);
+
+        mHandler.sendMessageDelayed(message, SHOW_SUCCESS_SQUARE_INTERVAL);
+    }
+
+    private void handleZxingWifiFormat(WifiNetworkConfig wifiNetworkConfig) {
+        destroyCamera();
+        mDecorateView.setFocused(true);
+
+        Message message = mHandler.obtainMessage(MESSAGE_SCAN_ZXING_WIFI_FORMAT_SUCCESS);
+        message.obj = wifiNetworkConfig;
+
+        mHandler.sendMessageDelayed(message, SHOW_SUCCESS_SQUARE_INTERVAL);
     }
 
     @Override
@@ -198,4 +320,52 @@
             mCamera = null;
         }
     }
+
+    @Override
+    public void showErrorMessage(boolean show) {
+        super.showErrorMessage(show);
+
+        if (show) {
+            mHandler.removeMessages(MESSAGE_HIDE_ERROR_MESSAGE);
+            mHandler.sendEmptyMessageDelayed(MESSAGE_HIDE_ERROR_MESSAGE,
+                    SHOW_ERROR_MESSAGE_INTERVAL);
+        }
+    }
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MESSAGE_HIDE_ERROR_MESSAGE:
+                    showErrorMessage(false);
+                    break;
+
+                case MESSAGE_SHOW_ERROR_MESSAGE:
+                    showErrorMessage(true);
+                    break;
+
+                case MESSAGE_SCAN_WIFI_DPP_SUCCESS:
+                    if (mScanWifiDppSuccessListener == null) {
+                        return;
+                    }
+                    final Bundle bundle = msg.getData();
+                    final String publicKey = bundle.getString(KEY_PUBLIC_KEY);
+                    final String information = bundle.getString(KEY_INFORMATION);
+
+                    mScanWifiDppSuccessListener.onScanWifiDppSuccess(publicKey, information);
+                    break;
+
+                case MESSAGE_SCAN_ZXING_WIFI_FORMAT_SUCCESS:
+                    if (mScanScanZxingWifiFormatSuccessListener == null) {
+                        return;
+                    }
+                    mScanScanZxingWifiFormatSuccessListener.onScanZxingWifiFormatSuccess(
+                            (WifiNetworkConfig)msg.obj);
+                    break;
+
+                default:
+                    return;
+            }
+        }
+    };
 }
diff --git a/src/com/android/settings/wifi/qrcode/QrCamera.java b/src/com/android/settings/wifi/qrcode/QrCamera.java
index c60c30e..af366bc 100644
--- a/src/com/android/settings/wifi/qrcode/QrCamera.java
+++ b/src/com/android/settings/wifi/qrcode/QrCamera.java
@@ -152,6 +152,15 @@
          * @param transform The transform to apply to the content of preview
          */
         void setTransform(Matrix transform);
+
+        /**
+         * Verify QR code is valid or not. The camera will stop scanning if this callback returns
+         * true.
+         *
+         * @param qrCode The result QR code after decoding.
+         * @return Returns true if qrCode hold valid information.
+         */
+        boolean isValid(String qrCode);
     }
 
     private void setCameraParameter() {
@@ -245,7 +254,9 @@
                         mReader.reset();
                     }
                     if (qrCode != null) {
-                        return qrCode.getText();
+                        if (mScannerCallback.isValid(qrCode.getText())) {
+                            return qrCode.getText();
+                        }
                     }
                 } catch (InterruptedException e) {
                     Thread.currentThread().interrupt();
diff --git a/tests/robotests/src/com/android/settings/wifi/qrcode/QrCameraTest.java b/tests/robotests/src/com/android/settings/wifi/qrcode/QrCameraTest.java
index 0ef0273..a57fefc 100644
--- a/tests/robotests/src/com/android/settings/wifi/qrcode/QrCameraTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/qrcode/QrCameraTest.java
@@ -85,6 +85,11 @@
         public void setTransform(Matrix transform) {
             // Do nothing
         }
+
+        @Override
+        public boolean isValid(String qrCode) {
+            return true;
+        }
     }
 
     private ScannerTestCallback mScannerCallback;
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
index 235f182..61033e9 100644
--- a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
+++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
@@ -80,4 +80,20 @@
         assertThat(activity instanceof WifiDppQrCodeGeneratorFragment
                 .OnQrCodeGeneratorFragmentAddButtonClickedListener).isEqualTo(true);
     }
+
+    @Test
+    public void testActivity_shouldImplementsOnScanWifiDppSuccessCallback() {
+        WifiDppConfiguratorActivity activity = mActivityRule.getActivity();
+
+        assertThat(activity instanceof WifiDppQrCodeScannerFragment
+                .OnScanWifiDppSuccessListener).isEqualTo(true);
+    }
+
+    @Test
+    public void testActivity_shouldImplementsOnScanZxingWifiFormatSuccessCallback() {
+        WifiDppConfiguratorActivity activity = mActivityRule.getActivity();
+
+        assertThat(activity instanceof WifiDppQrCodeScannerFragment
+                .OnScanZxingWifiFormatSuccessListener).isEqualTo(true);
+    }
 }
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivityTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivityTest.java
new file mode 100644
index 0000000..283da13
--- /dev/null
+++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivityTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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 androidx.test.rule.ActivityTestRule;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class WifiDppEnrolleeActivityTest {
+    @Rule
+    public final ActivityTestRule<WifiDppEnrolleeActivity> mActivityRule =
+            new ActivityTestRule<>(WifiDppEnrolleeActivity.class);
+
+    @Test
+    public void testActivity_shouldImplementsOnScanWifiDppSuccessCallback() {
+        WifiDppEnrolleeActivity activity = mActivityRule.getActivity();
+
+        assertThat(activity instanceof WifiDppQrCodeScannerFragment
+                .OnScanWifiDppSuccessListener).isEqualTo(true);
+    }
+
+    @Test
+    public void testActivity_shouldImplementsOnScanZxingWifiFormatSuccessCallback() {
+        WifiDppEnrolleeActivity activity = mActivityRule.getActivity();
+
+        assertThat(activity instanceof WifiDppQrCodeScannerFragment
+                .OnScanZxingWifiFormatSuccessListener).isEqualTo(true);
+    }
+}