From 7b401abddc6754f399f9be09795476c1d78af831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joris=20Pelgr=C3=B6m?= Date: Fri, 1 Jul 2022 03:58:24 +0200 Subject: [PATCH] Don't complete onboarding on registration error (#2646) - Add specific error if the app encounters a HTTP 404 response during onboarding registration, because that means the mobile_app integration is missing - After an error, clean up the session data to make sure a new registration attempt is made --- .../android/launch/LaunchActivity.kt | 20 ++++++++--- .../impl/IntegrationRepositoryImpl.kt | 14 ++++---- common/src/main/res/values/strings.xml | 2 +- .../android/phone/PhoneSettingsListener.kt | 34 +++++++++++-------- 4 files changed, 42 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/io/homeassistant/companion/android/launch/LaunchActivity.kt b/app/src/main/java/io/homeassistant/companion/android/launch/LaunchActivity.kt index 01c5e37ad..cee05ffb0 100644 --- a/app/src/main/java/io/homeassistant/companion/android/launch/LaunchActivity.kt +++ b/app/src/main/java/io/homeassistant/companion/android/launch/LaunchActivity.kt @@ -26,6 +26,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.launch +import retrofit2.HttpException import javax.inject.Inject import javax.net.ssl.SSLException import javax.net.ssl.SSLHandshakeException @@ -145,15 +146,24 @@ class LaunchActivity : AppCompatActivity(), LaunchView { ) } catch (e: Exception) { // Fatal errors: if one of these calls fail, the app cannot proceed. - // Because this runs after the webview, the only expected errors are system - // version related in OkHttp (cryptography), or general connection issues (offline/unknown). + // Show an error, clean up the session and require new registration. + // Because this runs after the webview, the only expected errors are: + // - missing mobile_app integration + // - system version related in OkHttp (cryptography) + // - general connection issues (offline/unknown) Log.e(TAG, "Exception while registering", e) + try { + authenticationRepository.revokeSession() + } catch (e: Exception) { + Log.e(TAG, "Can't revoke session", e) + } AlertDialog.Builder(this@LaunchActivity) .setTitle(commonR.string.error_connection_failed) .setMessage( - when (e) { - is SSLHandshakeException -> commonR.string.webview_error_FAILED_SSL_HANDSHAKE - is SSLException -> commonR.string.webview_error_SSL_INVALID + when { + e is HttpException && e.code() == 404 -> commonR.string.error_with_registration + e is SSLHandshakeException -> commonR.string.webview_error_FAILED_SSL_HANDSHAKE + e is SSLException -> commonR.string.webview_error_SSL_INVALID else -> commonR.string.webview_error } ) diff --git a/common/src/main/java/io/homeassistant/companion/android/common/data/integration/impl/IntegrationRepositoryImpl.kt b/common/src/main/java/io/homeassistant/companion/android/common/data/integration/impl/IntegrationRepositoryImpl.kt index ca45a9f6f..84dbe7d42 100644 --- a/common/src/main/java/io/homeassistant/companion/android/common/data/integration/impl/IntegrationRepositoryImpl.kt +++ b/common/src/main/java/io/homeassistant/companion/android/common/data/integration/impl/IntegrationRepositoryImpl.kt @@ -94,13 +94,13 @@ class IntegrationRepositoryImpl @Inject constructor( Log.e(TAG, "Unable to register device due to missing URL") return } + val response = + integrationService.registerDevice( + url.newBuilder().addPathSegments("api/mobile_app/registrations").build(), + authenticationRepository.buildBearerToken(), + request + ) try { - val response = - integrationService.registerDevice( - url.newBuilder().addPathSegments("api/mobile_app/registrations").build(), - authenticationRepository.buildBearerToken(), - request - ) persistDeviceRegistration(deviceRegistration) urlRepository.saveRegistrationUrls( response.cloudhookUrl, @@ -109,7 +109,7 @@ class IntegrationRepositoryImpl @Inject constructor( ) localStorage.putString(PREF_SECRET, response.secret) } catch (e: Exception) { - Log.e(TAG, "Unable to register device", e) + Log.e(TAG, "Unable to save device registration", e) } } diff --git a/common/src/main/res/values/strings.xml b/common/src/main/res/values/strings.xml index 308043e75..36597ed8c 100644 --- a/common/src/main/res/values/strings.xml +++ b/common/src/main/res/values/strings.xml @@ -193,7 +193,7 @@ Error loading entities Unable to connect to Home Assistant. Unable to communicate with Home Assistant because of a SSL error. Please ensure your certificate is valid. - Please check to ensure you have the mobile_app\nintegration enabled on your home assistant instance. + The \'Mobile App\' integration is required to use the app, but it is not available on your Home Assistant server. Please check your server configuration and try again. Errors Failed to notify HA of picked option. Exit diff --git a/wear/src/main/java/io/homeassistant/companion/android/phone/PhoneSettingsListener.kt b/wear/src/main/java/io/homeassistant/companion/android/phone/PhoneSettingsListener.kt index ce7c6e7bb..23df9f339 100755 --- a/wear/src/main/java/io/homeassistant/companion/android/phone/PhoneSettingsListener.kt +++ b/wear/src/main/java/io/homeassistant/companion/android/phone/PhoneSettingsListener.kt @@ -109,25 +109,29 @@ class PhoneSettingsListener : WearableListenerService(), DataClient.OnDataChange } private fun login(dataMap: DataMap) = mainScope.launch { - val url = dataMap.getString("URL") - val authCode = dataMap.getString("AuthCode") - val deviceName = dataMap.getString("DeviceName") - val deviceTrackingEnabled = dataMap.getString("LocationTracking") + try { + val url = dataMap.getString("URL") + val authCode = dataMap.getString("AuthCode") + val deviceName = dataMap.getString("DeviceName") + val deviceTrackingEnabled = dataMap.getString("LocationTracking") - urlRepository.saveUrl(url) - authenticationRepository.registerAuthorizationCode(authCode) - integrationUseCase.registerDevice( - DeviceRegistration( - "${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})", - deviceName + urlRepository.saveUrl(url) + authenticationRepository.registerAuthorizationCode(authCode) + integrationUseCase.registerDevice( + DeviceRegistration( + "${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})", + deviceName + ) ) - ) + + val intent = HomeActivity.newInstance(applicationContext) + intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK + startActivity(intent) + } catch (e: Exception) { + Log.e(TAG, "Unable to login to Home Assistant", e) + } sendPhoneData() - - val intent = HomeActivity.newInstance(applicationContext) - intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK - startActivity(intent) } private fun saveFavorites(dataMap: DataMap) {