Check if enrolled Wi-Fi network is reachable in WifiManager#connect onSuccess callback

WifiManager#connect may callback onSuccess even if the Wi-Fi network is not reachable,
it confuses users.

In onSuccess callback, if the Wi-Fi network is unreachable, shows error message.

Bug: 127980127
Test: manual test
Change-Id: I503d6c77c1f1fcab3a1240d904f1c60aaef63aa1
This commit is contained in:
Arc Wang
2019-03-21 19:14:17 +08:00
parent 3196013b1a
commit 7599de43f7

View File

@@ -45,6 +45,7 @@ import android.view.accessibility.AccessibilityEvent;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.StringRes;
import androidx.lifecycle.ViewModelProviders; import androidx.lifecycle.ViewModelProviders;
import com.android.settings.R; import com.android.settings.R;
@@ -52,12 +53,17 @@ import com.android.settings.wifi.WifiDialogActivity;
import com.android.settings.wifi.qrcode.QrCamera; import com.android.settings.wifi.qrcode.QrCamera;
import com.android.settings.wifi.qrcode.QrDecorateView; 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; import java.util.List;
public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment implements public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment implements
SurfaceTextureListener, SurfaceTextureListener,
QrCamera.ScannerCallback, QrCamera.ScannerCallback,
WifiManager.ActionListener { WifiManager.ActionListener,
WifiTracker.WifiListener {
private static final String TAG = "WifiDppQrCodeScannerFragment"; private static final String TAG = "WifiDppQrCodeScannerFragment";
/** Message sent to hide error message */ /** Message sent to hide error message */
@@ -80,6 +86,8 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
private static final String KEY_LATEST_ERROR_CODE = "key_latest_error_code"; 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 String KEY_WIFI_CONFIGURATION = "key_wifi_configuration";
private static final int ARG_RESTART_CAMERA = 1;
private ProgressBar mProgressBar; private ProgressBar mProgressBar;
private QrCamera mCamera; private QrCamera mCamera;
private TextureView mTextureView; private TextureView mTextureView;
@@ -100,6 +108,68 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
private int mLatestStatusCode = WifiDppUtils.EASY_CONNECT_EVENT_FAILURE_NONE; 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 @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@@ -175,6 +245,9 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
public void onActivityCreated(Bundle savedInstanceState) { public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState); super.onActivityCreated(savedInstanceState);
mWifiTracker = WifiTrackerFactory.create(getActivity(), /* wifiListener */ this,
getSettingsLifecycle(), /* includeSaved */ false, /* includeScans */ true);
// setTitle for Talkback // setTitle for Talkback
if (mIsConfiguratorMode) { if (mIsConfiguratorMode) {
getActivity().setTitle(R.string.wifi_dpp_add_device_to_network); getActivity().setTitle(R.string.wifi_dpp_add_device_to_network);
@@ -291,7 +364,7 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
try { try {
mWifiQrCode = new WifiQrCode(qrCode); mWifiQrCode = new WifiQrCode(qrCode);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
mHandler.sendEmptyMessage(MESSAGE_SHOW_ERROR_MESSAGE); showErrorMessage(R.string.wifi_dpp_could_not_detect_valid_qr_code);
return false; return false;
} }
@@ -301,14 +374,14 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
if (!mIsConfiguratorMode && WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG.equals(scheme)) { if (!mIsConfiguratorMode && WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG.equals(scheme)) {
final String ssidQrCode = mWifiQrCode.getWifiNetworkConfig().getSsid(); final String ssidQrCode = mWifiQrCode.getWifiNetworkConfig().getSsid();
if (!TextUtils.isEmpty(mSsid) && !mSsid.equals(ssidQrCode)) { 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; return false;
} }
} }
// It's impossible to provision other device with ZXing Wi-Fi Network config format // It's impossible to provision other device with ZXing Wi-Fi Network config format
if (mIsConfiguratorMode && WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG.equals(scheme)) { 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; return false;
} }
@@ -385,59 +458,18 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
} }
} }
public void showErrorMessage(String message) { private void showErrorMessage(@StringRes int messageResId) {
mErrorMessage.setVisibility(View.VISIBLE); final Message message = mHandler.obtainMessage(MESSAGE_SHOW_ERROR_MESSAGE,
mErrorMessage.setText(message); getString(messageResId));
mErrorMessage.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); message.sendToTarget();
mHandler.removeMessages(MESSAGE_HIDE_ERROR_MESSAGE);
mHandler.sendEmptyMessageDelayed(MESSAGE_HIDE_ERROR_MESSAGE,
SHOW_ERROR_MESSAGE_INTERVAL);
} }
private final Handler mHandler = new Handler() { private void showErrorMessageAndRestartCamera(@StringRes int messageResId) {
@Override final Message message = mHandler.obtainMessage(MESSAGE_SHOW_ERROR_MESSAGE,
public void handleMessage(Message msg) { getString(messageResId));
switch (msg.what) { message.arg1 = ARG_RESTART_CAMERA;
case MESSAGE_HIDE_ERROR_MESSAGE: message.sendToTarget();
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;
}
}
};
@Override @Override
public void onSaveInstanceState(Bundle outState) { public void onSaveInstanceState(Bundle outState) {
@@ -468,9 +500,7 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
Log.e(TAG, "Invalid networkId " + newNetworkId); Log.e(TAG, "Invalid networkId " + newNetworkId);
mLatestStatusCode = EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_GENERIC; mLatestStatusCode = EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_GENERIC;
updateEnrolleeSummary(); updateEnrolleeSummary();
mProgressBar.setVisibility(View.INVISIBLE); showErrorMessageAndRestartCamera(R.string.wifi_dpp_check_connection_try_again);
showErrorMessage(getString(R.string.wifi_dpp_check_connection_try_again));
restartCamera();
} }
@Override @Override
@@ -482,23 +512,22 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
public void onFailure(int code) { public void onFailure(int code) {
Log.d(TAG, "EasyConnectEnrolleeStatusCallback.onFailure " + code); Log.d(TAG, "EasyConnectEnrolleeStatusCallback.onFailure " + code);
int errorMessageResId = 0;
switch (code) { switch (code) {
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_INVALID_URI: 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; break;
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_AUTHENTICATION: case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_AUTHENTICATION:
showErrorMessage( errorMessageResId = R.string.wifi_dpp_failure_authentication_or_configuration;
getString(R.string.wifi_dpp_failure_authentication_or_configuration));
break; break;
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_NOT_COMPATIBLE: 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; break;
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_CONFIGURATION: case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_CONFIGURATION:
showErrorMessage( errorMessageResId = R.string.wifi_dpp_failure_authentication_or_configuration;
getString(R.string.wifi_dpp_failure_authentication_or_configuration));
break; break;
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_BUSY: case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_BUSY:
@@ -515,11 +544,11 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
return; return;
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_TIMEOUT: case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_TIMEOUT:
showErrorMessage(getString(R.string.wifi_dpp_failure_timeout)); errorMessageResId = R.string.wifi_dpp_failure_timeout;
break; break;
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_GENERIC: case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_GENERIC:
showErrorMessage(getString(R.string.wifi_dpp_failure_generic)); errorMessageResId = R.string.wifi_dpp_failure_generic;
break; break;
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED: case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED:
@@ -536,8 +565,7 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
mLatestStatusCode = code; mLatestStatusCode = code;
updateEnrolleeSummary(); updateEnrolleeSummary();
mProgressBar.setVisibility(View.INVISIBLE); showErrorMessageAndRestartCamera(errorMessageResId);
restartCamera();
} }
@Override @Override
@@ -555,21 +583,39 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
@Override @Override
public void onSuccess() { public void onSuccess() {
final Intent resultIntent = new Intent(); if (isEnrollingWifiNetworkReachable()) {
resultIntent.putExtra(WifiDialogActivity.KEY_WIFI_CONFIGURATION, mWifiConfiguration); final Intent resultIntent = new Intent();
resultIntent.putExtra(WifiDialogActivity.KEY_WIFI_CONFIGURATION, mWifiConfiguration);
final Activity hostActivity = getActivity(); final Activity hostActivity = getActivity();
hostActivity.setResult(Activity.RESULT_OK, resultIntent); hostActivity.setResult(Activity.RESULT_OK, resultIntent);
hostActivity.finish(); 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 @Override
public void onFailure(int reason) { public void onFailure(int reason) {
Log.d(TAG, "Wi-Fi connect onFailure reason - " + reason); Log.d(TAG, "Wi-Fi connect onFailure reason - " + reason);
showErrorMessageAndRestartCamera(R.string.wifi_dpp_check_connection_try_again);
}
mProgressBar.setVisibility(View.INVISIBLE); private boolean isEnrollingWifiNetworkReachable() {
showErrorMessage(getString(R.string.wifi_dpp_check_connection_try_again)); if (mWifiConfiguration == null) {
restartCamera(); 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 // Check is Easy Connect handshaking or not
@@ -610,4 +656,25 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
mSummary.setText(description); 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.
}
} }