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
This commit is contained in:
@@ -39,10 +39,13 @@
|
|||||||
android:layout_gravity="center"/>
|
android:layout_gravity="center"/>
|
||||||
</com.android.settings.wifi.qrcode.QrPreviewLayout>
|
</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_width="wrap_content"
|
||||||
android:layout_height="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>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@@ -2090,6 +2090,8 @@
|
|||||||
<string name="wifi_dpp_share_wifi">Share Wi\u2011Fi</string>
|
<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] -->
|
<!-- 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>
|
<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 -->
|
<!-- 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>
|
<string name="wifi_shared">Share with other device users</string>
|
||||||
<!-- Hint for unchanged fields -->
|
<!-- Hint for unchanged fields -->
|
||||||
|
@@ -49,7 +49,9 @@ import com.android.settings.R;
|
|||||||
*/
|
*/
|
||||||
public class WifiDppConfiguratorActivity extends InstrumentedActivity implements
|
public class WifiDppConfiguratorActivity extends InstrumentedActivity implements
|
||||||
WifiNetworkConfig.Retriever,
|
WifiNetworkConfig.Retriever,
|
||||||
WifiDppQrCodeGeneratorFragment.OnQrCodeGeneratorFragmentAddButtonClickedListener {
|
WifiDppQrCodeGeneratorFragment.OnQrCodeGeneratorFragmentAddButtonClickedListener,
|
||||||
|
WifiDppQrCodeScannerFragment.OnScanWifiDppSuccessListener,
|
||||||
|
WifiDppQrCodeScannerFragment.OnScanZxingWifiFormatSuccessListener {
|
||||||
private static final String TAG = "WifiDppConfiguratorActivity";
|
private static final String TAG = "WifiDppConfiguratorActivity";
|
||||||
|
|
||||||
public static final String ACTION_CONFIGURATOR_QR_CODE_SCANNER =
|
public static final String ACTION_CONFIGURATOR_QR_CODE_SCANNER =
|
||||||
@@ -64,6 +66,12 @@ public class WifiDppConfiguratorActivity extends InstrumentedActivity implements
|
|||||||
/** The Wi-Fi network which will be configured */
|
/** The Wi-Fi network which will be configured */
|
||||||
private WifiNetworkConfig mWifiNetworkConfig;
|
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
|
@Override
|
||||||
public int getMetricsCategory() {
|
public int getMetricsCategory() {
|
||||||
return MetricsProto.MetricsEvent.SETTINGS_WIFI_DPP_CONFIGURATOR;
|
return MetricsProto.MetricsEvent.SETTINGS_WIFI_DPP_CONFIGURATOR;
|
||||||
@@ -127,8 +135,8 @@ public class WifiDppConfiguratorActivity extends InstrumentedActivity implements
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WifiDppQrCodeScannerFragment fragment = new WifiDppQrCodeScannerFragment();
|
final WifiDppQrCodeScannerFragment fragment = new WifiDppQrCodeScannerFragment();
|
||||||
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
|
final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
|
||||||
|
|
||||||
fragmentTransaction.replace(R.id.fragment_container, fragment,
|
fragmentTransaction.replace(R.id.fragment_container, fragment,
|
||||||
WifiDppUtils.TAG_FRAGMENT_QR_CODE_SCANNER);
|
WifiDppUtils.TAG_FRAGMENT_QR_CODE_SCANNER);
|
||||||
@@ -145,8 +153,8 @@ public class WifiDppConfiguratorActivity extends InstrumentedActivity implements
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WifiDppQrCodeGeneratorFragment fragment = new WifiDppQrCodeGeneratorFragment();
|
final WifiDppQrCodeGeneratorFragment fragment = new WifiDppQrCodeGeneratorFragment();
|
||||||
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
|
final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
|
||||||
|
|
||||||
fragmentTransaction.replace(R.id.fragment_container, fragment,
|
fragmentTransaction.replace(R.id.fragment_container, fragment,
|
||||||
WifiDppUtils.TAG_FRAGMENT_QR_CODE_GENERATOR);
|
WifiDppUtils.TAG_FRAGMENT_QR_CODE_GENERATOR);
|
||||||
@@ -160,9 +168,9 @@ public class WifiDppConfiguratorActivity extends InstrumentedActivity implements
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WifiDppChooseSavedWifiNetworkFragment fragment =
|
final WifiDppChooseSavedWifiNetworkFragment fragment =
|
||||||
new WifiDppChooseSavedWifiNetworkFragment();
|
new WifiDppChooseSavedWifiNetworkFragment();
|
||||||
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
|
final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
|
||||||
|
|
||||||
fragmentTransaction.replace(R.id.fragment_container, fragment,
|
fragmentTransaction.replace(R.id.fragment_container, fragment,
|
||||||
WifiDppUtils.TAG_FRAGMENT_CHOOSE_SAVED_WIFI_NETWORK);
|
WifiDppUtils.TAG_FRAGMENT_CHOOSE_SAVED_WIFI_NETWORK);
|
||||||
@@ -172,11 +180,38 @@ public class WifiDppConfiguratorActivity extends InstrumentedActivity implements
|
|||||||
fragmentTransaction.commit();
|
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
|
@Override
|
||||||
public WifiNetworkConfig getWifiNetworkConfig() {
|
public WifiNetworkConfig getWifiNetworkConfig() {
|
||||||
return mWifiNetworkConfig;
|
return mWifiNetworkConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getPublicKey() {
|
||||||
|
return mPublicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInformation() {
|
||||||
|
return mInformation;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setWifiNetworkConfig(WifiNetworkConfig config) {
|
public boolean setWifiNetworkConfig(WifiNetworkConfig config) {
|
||||||
if(!WifiNetworkConfig.isValidConfig(config)) {
|
if(!WifiNetworkConfig.isValidConfig(config)) {
|
||||||
@@ -201,7 +236,26 @@ public class WifiDppConfiguratorActivity extends InstrumentedActivity implements
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void onQrCodeGeneratorFragmentAddButtonClicked() {
|
@Override
|
||||||
|
public void onQrCodeGeneratorFragmentAddButtonClicked() {
|
||||||
showQrCodeScannerFragment(/* addToBackStack */ true);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,9 +16,11 @@
|
|||||||
|
|
||||||
package com.android.settings.wifi.dpp;
|
package com.android.settings.wifi.dpp;
|
||||||
|
|
||||||
|
import android.provider.Settings;
|
||||||
import android.app.ActionBar;
|
import android.app.ActionBar;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.net.wifi.WifiManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@@ -36,7 +38,10 @@ import com.android.settings.R;
|
|||||||
* To use intent action {@code ACTION_ENROLLEE_QR_CODE_SCANNER}, specify the SSID string of the
|
* 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}.
|
* 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";
|
private static final String TAG = "WifiDppEnrolleeActivity";
|
||||||
|
|
||||||
public static final String ACTION_ENROLLEE_QR_CODE_SCANNER =
|
public static final String ACTION_ENROLLEE_QR_CODE_SCANNER =
|
||||||
@@ -101,4 +106,31 @@ public class WifiDppEnrolleeActivity extends InstrumentedActivity {
|
|||||||
finish();
|
finish();
|
||||||
return true;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -101,6 +101,13 @@ public abstract class WifiDppQrCodeBaseFragment extends InstrumentedFragment {
|
|||||||
mDescription.setText(description);
|
mDescription.setText(description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** optional, for WifiDppQrCodeScannerFragment */
|
||||||
|
protected void showErrorMessage(boolean show) {
|
||||||
|
if (mErrorMessage != null) {
|
||||||
|
mErrorMessage.setVisibility(show ? View.VISIBLE : View.INVISIBLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** optional, for WifiDppQrCodeScannerFragment */
|
/** optional, for WifiDppQrCodeScannerFragment */
|
||||||
protected void setErrorMessage(String errorMessage) {
|
protected void setErrorMessage(String errorMessage) {
|
||||||
if (mErrorMessage != null) {
|
if (mErrorMessage != null) {
|
||||||
|
@@ -25,6 +25,8 @@ import android.graphics.Matrix;
|
|||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.SurfaceTexture;
|
import android.graphics.SurfaceTexture;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Size;
|
import android.util.Size;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
@@ -41,16 +43,40 @@ import com.android.settings.wifi.qrcode.QrDecorateView;
|
|||||||
public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment implements
|
public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment implements
|
||||||
SurfaceTextureListener,
|
SurfaceTextureListener,
|
||||||
QrCamera.ScannerCallback {
|
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 QrCamera mCamera;
|
||||||
private TextureView mTextureView;
|
private TextureView mTextureView;
|
||||||
private QrDecorateView mDecorateView;
|
private QrDecorateView mDecorateView;
|
||||||
|
|
||||||
/** true if the fragment working for configurator, false enrollee*/
|
/** 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 */
|
/** The SSID of the Wi-Fi network which the user specify to enroll */
|
||||||
private String mSsid;
|
private String mSsid;
|
||||||
|
|
||||||
|
/** QR code data scanned by camera */
|
||||||
|
private WifiQrCode mWifiQrCode;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getLayout() {
|
protected int getLayout() {
|
||||||
return R.layout.wifi_dpp_qrcode_scanner_fragment;
|
return R.layout.wifi_dpp_qrcode_scanner_fragment;
|
||||||
@@ -58,20 +84,32 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMetricsCategory() {
|
public int getMetricsCategory() {
|
||||||
if (mConfiguratorMode) {
|
if (mIsConfiguratorMode) {
|
||||||
return MetricsProto.MetricsEvent.SETTINGS_WIFI_DPP_CONFIGURATOR;
|
return MetricsProto.MetricsEvent.SETTINGS_WIFI_DPP_CONFIGURATOR;
|
||||||
} else {
|
} else {
|
||||||
return MetricsProto.MetricsEvent.SETTINGS_WIFI_DPP_ENROLLEE;
|
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.
|
* Configurator container activity of the fragment should create instance with this constructor.
|
||||||
*/
|
*/
|
||||||
public WifiDppQrCodeScannerFragment() {
|
public WifiDppQrCodeScannerFragment() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
mConfiguratorMode = true;
|
mIsConfiguratorMode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -81,7 +119,7 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
|
|||||||
public WifiDppQrCodeScannerFragment(String ssid) {
|
public WifiDppQrCodeScannerFragment(String ssid) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
mConfiguratorMode = false;
|
mIsConfiguratorMode = false;
|
||||||
mSsid = ssid;
|
mSsid = ssid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +129,7 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
|
|||||||
|
|
||||||
setHeaderIconImageResource(R.drawable.ic_scan_24dp);
|
setHeaderIconImageResource(R.drawable.ic_scan_24dp);
|
||||||
|
|
||||||
if (mConfiguratorMode) {
|
if (mIsConfiguratorMode) {
|
||||||
setTitle(getString(R.string.wifi_dpp_add_device_to_network));
|
setTitle(getString(R.string.wifi_dpp_add_device_to_network));
|
||||||
|
|
||||||
WifiNetworkConfig wifiNetworkConfig = ((WifiNetworkConfig.Retriever) getActivity())
|
WifiNetworkConfig wifiNetworkConfig = ((WifiNetworkConfig.Retriever) getActivity())
|
||||||
@@ -112,11 +150,30 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
|
|||||||
setDescription(description);
|
setDescription(description);
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionBar actionBar = getActivity().getActionBar();
|
final ActionBar actionBar = getActivity().getActionBar();
|
||||||
if (actionBar != null) {
|
if (actionBar != null) {
|
||||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||||
actionBar.show();
|
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
|
@Override
|
||||||
@@ -172,11 +229,76 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
|
|||||||
mTextureView.setTransform(transform);
|
mTextureView.setTransform(transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
@Override
|
||||||
public void handleSuccessfulResult(String qrCode) {
|
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();
|
destroyCamera();
|
||||||
mDecorateView.setFocused(true);
|
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
|
@Override
|
||||||
@@ -198,4 +320,52 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
|
|||||||
mCamera = null;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@@ -152,6 +152,15 @@ public class QrCamera extends Handler {
|
|||||||
* @param transform The transform to apply to the content of preview
|
* @param transform The transform to apply to the content of preview
|
||||||
*/
|
*/
|
||||||
void setTransform(Matrix transform);
|
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() {
|
private void setCameraParameter() {
|
||||||
@@ -245,8 +254,10 @@ public class QrCamera extends Handler {
|
|||||||
mReader.reset();
|
mReader.reset();
|
||||||
}
|
}
|
||||||
if (qrCode != null) {
|
if (qrCode != null) {
|
||||||
|
if (mScannerCallback.isValid(qrCode.getText())) {
|
||||||
return qrCode.getText();
|
return qrCode.getText();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
return null;
|
return null;
|
||||||
|
@@ -85,6 +85,11 @@ public class QrCameraTest {
|
|||||||
public void setTransform(Matrix transform) {
|
public void setTransform(Matrix transform) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValid(String qrCode) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ScannerTestCallback mScannerCallback;
|
private ScannerTestCallback mScannerCallback;
|
||||||
|
@@ -80,4 +80,20 @@ public class WifiDppConfiguratorActivityTest {
|
|||||||
assertThat(activity instanceof WifiDppQrCodeGeneratorFragment
|
assertThat(activity instanceof WifiDppQrCodeGeneratorFragment
|
||||||
.OnQrCodeGeneratorFragmentAddButtonClickedListener).isEqualTo(true);
|
.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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user