From 9cb3022713feeb48d5e2cd6f302729489f17346a Mon Sep 17 00:00:00 2001 From: Akshay Nandwana Date: Fri, 6 Dec 2024 13:47:07 +0530 Subject: [PATCH 01/10] play service error handle --- .../android/ground/system/GoogleApiManager.kt | 27 +++++++++++-------- .../ground/ui/startup/StartupFragment.kt | 21 ++++++++------- .../ground/ui/startup/StartupViewModel.kt | 8 ++++-- 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt b/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt index 685d871705..c66ef98878 100644 --- a/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt +++ b/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt @@ -37,20 +37,27 @@ constructor( * Displays a dialog to install Google Play Services, if missing. Throws an error if install not * possible or cancelled. */ - suspend fun installGooglePlayServices() { + suspend fun installGooglePlayServices(): Boolean { val status = googleApiAvailability.isGooglePlayServicesAvailable(context) - if (status == ConnectionResult.SUCCESS) return + if (status == ConnectionResult.SUCCESS) return true val requestCode = INSTALL_API_REQUEST_CODE - startResolution(status, requestCode, GooglePlayServicesMissingException()) - getNextResult(requestCode) + return startResolution(status, requestCode) } - private fun startResolution(status: Int, requestCode: Int, throwable: Throwable) { - if (!googleApiAvailability.isUserResolvableError(status)) throw throwable - - activityStreams.withActivity { - googleApiAvailability.showErrorDialogFragment(it, status, requestCode) { throw throwable } + private suspend fun startResolution(status: Int, requestCode: Int): Boolean { + return if (googleApiAvailability.isUserResolvableError(status)) { + try { + activityStreams.withActivity { + googleApiAvailability.showErrorDialogFragment(it, status, requestCode, null) + } + getNextResult(requestCode) + true + } catch (e: Exception) { + false + } + } else { + false } } @@ -60,6 +67,4 @@ constructor( error("Activity result failed: requestCode = $requestCode, result = $result") } } - - class GooglePlayServicesMissingException : Error("Google play services not available") } diff --git a/ground/src/main/java/com/google/android/ground/ui/startup/StartupFragment.kt b/ground/src/main/java/com/google/android/ground/ui/startup/StartupFragment.kt index 648118f537..939b3241dc 100644 --- a/ground/src/main/java/com/google/android/ground/ui/startup/StartupFragment.kt +++ b/ground/src/main/java/com/google/android/ground/ui/startup/StartupFragment.kt @@ -21,7 +21,6 @@ import android.view.View import android.view.ViewGroup import androidx.lifecycle.lifecycleScope import com.google.android.ground.R -import com.google.android.ground.system.GoogleApiManager import com.google.android.ground.ui.common.AbstractFragment import com.google.android.ground.ui.common.EphemeralPopups import dagger.hilt.android.AndroidEntryPoint @@ -51,11 +50,14 @@ class StartupFragment : AbstractFragment() { super.onResume() showProgressDialog(R.string.initializing) viewLifecycleOwner.lifecycleScope.launch { - try { - viewModel.initializeLogin() - } catch (t: Throwable) { - onInitFailed(t) - } + val success = + try { + viewModel.initializeLogin() + } catch (t: Throwable) { + Timber.e(t, "Failed to initialize login") + false + } + handleLoginResult(success) } } @@ -64,11 +66,10 @@ class StartupFragment : AbstractFragment() { super.onPause() } - private fun onInitFailed(t: Throwable) { - Timber.e(t, "Failed to launch app") - if (t is GoogleApiManager.GooglePlayServicesMissingException) { + private fun handleLoginResult(success: Boolean) { + if (!success) { popups.ErrorPopup().show(R.string.google_api_install_failed) + requireActivity().finish() } - requireActivity().finish() } } diff --git a/ground/src/main/java/com/google/android/ground/ui/startup/StartupViewModel.kt b/ground/src/main/java/com/google/android/ground/ui/startup/StartupViewModel.kt index cff41bdee6..95187bffcb 100644 --- a/ground/src/main/java/com/google/android/ground/ui/startup/StartupViewModel.kt +++ b/ground/src/main/java/com/google/android/ground/ui/startup/StartupViewModel.kt @@ -28,8 +28,12 @@ internal constructor( ) : AbstractViewModel() { /** Checks & installs Google Play Services and initializes the login flow. */ - suspend fun initializeLogin() { - googleApiManager.installGooglePlayServices() + suspend fun initializeLogin(): Boolean { + val isGooglePlayServicesAvailable = googleApiManager.installGooglePlayServices() + if (!isGooglePlayServicesAvailable) { + return false + } userRepository.init() + return true } } From ab57bdc1085f001acbac168bd4c184317749c6a9 Mon Sep 17 00:00:00 2001 From: Akshay Nandwana Date: Fri, 6 Dec 2024 14:12:03 +0530 Subject: [PATCH 02/10] check fix --- .../android/ground/system/GoogleApiManager.kt | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt b/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt index c66ef98878..d66c24ea03 100644 --- a/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt +++ b/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt @@ -21,6 +21,7 @@ import com.google.android.gms.common.GoogleApiAvailability import dagger.hilt.android.qualifiers.ApplicationContext import javax.inject.Inject import javax.inject.Singleton +import timber.log.Timber private val INSTALL_API_REQUEST_CODE = GoogleApiAvailability::class.java.hashCode() and 0xffff @@ -46,25 +47,34 @@ constructor( } private suspend fun startResolution(status: Int, requestCode: Int): Boolean { - return if (googleApiAvailability.isUserResolvableError(status)) { - try { - activityStreams.withActivity { - googleApiAvailability.showErrorDialogFragment(it, status, requestCode, null) - } - getNextResult(requestCode) + if (!googleApiAvailability.isUserResolvableError(status)) return false + + return try { + activityStreams.withActivity { activity -> + googleApiAvailability.showErrorDialogFragment(activity, status, requestCode, null) + } + if (getNextResult(requestCode)) { true - } catch (e: Exception) { + } else { + Timber.e("Activity result was not successful for requestCode: $requestCode") false } - } else { + } catch (e: Exception) { + Timber.e( + e, + "Failed to launch app resolution for status: $status and requestCode: $requestCode", + ) false } } - private suspend fun getNextResult(requestCode: Int) { + private suspend fun getNextResult(requestCode: Int): Boolean { val result = activityStreams.getNextActivityResult(requestCode) - if (!result.isOk()) { - error("Activity result failed: requestCode = $requestCode, result = $result") + return if (result.isOk()) { + true + } else { + Timber.e("Activity result failed: requestCode = $requestCode, result = $result") + false } } } From 08035c315a646818f88a633c248a3b1baac4899e Mon Sep 17 00:00:00 2001 From: Akshay Nandwana Date: Fri, 6 Dec 2024 20:17:45 +0530 Subject: [PATCH 03/10] remove timber --- .../android/ground/system/GoogleApiManager.kt | 20 +++---------------- .../ground/ui/startup/StartupFragment.kt | 3 +-- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt b/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt index d66c24ea03..208b66ea72 100644 --- a/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt +++ b/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt @@ -21,7 +21,6 @@ import com.google.android.gms.common.GoogleApiAvailability import dagger.hilt.android.qualifiers.ApplicationContext import javax.inject.Inject import javax.inject.Singleton -import timber.log.Timber private val INSTALL_API_REQUEST_CODE = GoogleApiAvailability::class.java.hashCode() and 0xffff @@ -46,6 +45,7 @@ constructor( return startResolution(status, requestCode) } + @Suppress("SwallowedException") private suspend fun startResolution(status: Int, requestCode: Int): Boolean { if (!googleApiAvailability.isUserResolvableError(status)) return false @@ -53,28 +53,14 @@ constructor( activityStreams.withActivity { activity -> googleApiAvailability.showErrorDialogFragment(activity, status, requestCode, null) } - if (getNextResult(requestCode)) { - true - } else { - Timber.e("Activity result was not successful for requestCode: $requestCode") - false - } + getNextResult(requestCode) } catch (e: Exception) { - Timber.e( - e, - "Failed to launch app resolution for status: $status and requestCode: $requestCode", - ) false } } private suspend fun getNextResult(requestCode: Int): Boolean { val result = activityStreams.getNextActivityResult(requestCode) - return if (result.isOk()) { - true - } else { - Timber.e("Activity result failed: requestCode = $requestCode, result = $result") - false - } + return result.isOk() } } diff --git a/ground/src/main/java/com/google/android/ground/ui/startup/StartupFragment.kt b/ground/src/main/java/com/google/android/ground/ui/startup/StartupFragment.kt index 939b3241dc..b4d3a55d07 100644 --- a/ground/src/main/java/com/google/android/ground/ui/startup/StartupFragment.kt +++ b/ground/src/main/java/com/google/android/ground/ui/startup/StartupFragment.kt @@ -26,7 +26,6 @@ import com.google.android.ground.ui.common.EphemeralPopups import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlinx.coroutines.launch -import timber.log.Timber @AndroidEntryPoint class StartupFragment : AbstractFragment() { @@ -46,6 +45,7 @@ class StartupFragment : AbstractFragment() { savedInstanceState: Bundle?, ): View? = inflater.inflate(R.layout.startup_frag, container, false) + @Suppress("SwallowedException") override fun onResume() { super.onResume() showProgressDialog(R.string.initializing) @@ -54,7 +54,6 @@ class StartupFragment : AbstractFragment() { try { viewModel.initializeLogin() } catch (t: Throwable) { - Timber.e(t, "Failed to initialize login") false } handleLoginResult(success) From 969589d348d53ab751933bf9ca5670834480a674 Mon Sep 17 00:00:00 2001 From: Akshay Nandwana Date: Fri, 6 Dec 2024 20:19:36 +0530 Subject: [PATCH 04/10] added log --- .../java/com/google/android/ground/system/GoogleApiManager.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt b/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt index 208b66ea72..5045725ccf 100644 --- a/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt +++ b/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt @@ -19,6 +19,7 @@ import android.content.Context import com.google.android.gms.common.ConnectionResult import com.google.android.gms.common.GoogleApiAvailability import dagger.hilt.android.qualifiers.ApplicationContext +import timber.log.Timber import javax.inject.Inject import javax.inject.Singleton @@ -55,6 +56,7 @@ constructor( } getNextResult(requestCode) } catch (e: Exception) { + Timber.e("Activity result was not successful for requestCode: $requestCode") false } } From 3aed8f387c4b8adefae1f17d6c62d0b944ceb96d Mon Sep 17 00:00:00 2001 From: Akshay Nandwana Date: Fri, 6 Dec 2024 20:21:32 +0530 Subject: [PATCH 05/10] nit fix --- .../java/com/google/android/ground/system/GoogleApiManager.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt b/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt index 5045725ccf..94e80ee693 100644 --- a/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt +++ b/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt @@ -19,9 +19,9 @@ import android.content.Context import com.google.android.gms.common.ConnectionResult import com.google.android.gms.common.GoogleApiAvailability import dagger.hilt.android.qualifiers.ApplicationContext -import timber.log.Timber import javax.inject.Inject import javax.inject.Singleton +import timber.log.Timber private val INSTALL_API_REQUEST_CODE = GoogleApiAvailability::class.java.hashCode() and 0xffff @@ -46,7 +46,6 @@ constructor( return startResolution(status, requestCode) } - @Suppress("SwallowedException") private suspend fun startResolution(status: Int, requestCode: Int): Boolean { if (!googleApiAvailability.isUserResolvableError(status)) return false From 31a2a4ecc2250da64930e27be15d8fcd5517e400 Mon Sep 17 00:00:00 2001 From: Akshay Nandwana Date: Sun, 8 Dec 2024 08:06:40 +0530 Subject: [PATCH 06/10] suggested fix --- .../android/ground/system/GoogleApiManager.kt | 4 ++-- .../ground/ui/startup/StartupFragment.kt | 23 +++++++------------ .../ground/ui/startup/StartupViewModel.kt | 2 +- 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt b/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt index 94e80ee693..d014ad8f3a 100644 --- a/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt +++ b/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt @@ -54,8 +54,8 @@ constructor( googleApiAvailability.showErrorDialogFragment(activity, status, requestCode, null) } getNextResult(requestCode) - } catch (e: Exception) { - Timber.e("Activity result was not successful for requestCode: $requestCode") + } catch (t: Throwable) { + Timber.e("Activity result was not successful for requestCode: $requestCode and throws $t") false } } diff --git a/ground/src/main/java/com/google/android/ground/ui/startup/StartupFragment.kt b/ground/src/main/java/com/google/android/ground/ui/startup/StartupFragment.kt index b4d3a55d07..e4a01427d9 100644 --- a/ground/src/main/java/com/google/android/ground/ui/startup/StartupFragment.kt +++ b/ground/src/main/java/com/google/android/ground/ui/startup/StartupFragment.kt @@ -26,6 +26,7 @@ import com.google.android.ground.ui.common.EphemeralPopups import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlinx.coroutines.launch +import timber.log.Timber @AndroidEntryPoint class StartupFragment : AbstractFragment() { @@ -45,18 +46,17 @@ class StartupFragment : AbstractFragment() { savedInstanceState: Bundle?, ): View? = inflater.inflate(R.layout.startup_frag, container, false) - @Suppress("SwallowedException") override fun onResume() { super.onResume() showProgressDialog(R.string.initializing) viewLifecycleOwner.lifecycleScope.launch { - val success = - try { - viewModel.initializeLogin() - } catch (t: Throwable) { - false - } - handleLoginResult(success) + try { + viewModel.initializeLogin() + } catch (t: Throwable) { + Timber.e(t, "Failed to launch app") + popups.ErrorPopup().show(R.string.google_api_install_failed) + requireActivity().finish() + } } } @@ -64,11 +64,4 @@ class StartupFragment : AbstractFragment() { dismissProgressDialog() super.onPause() } - - private fun handleLoginResult(success: Boolean) { - if (!success) { - popups.ErrorPopup().show(R.string.google_api_install_failed) - requireActivity().finish() - } - } } diff --git a/ground/src/main/java/com/google/android/ground/ui/startup/StartupViewModel.kt b/ground/src/main/java/com/google/android/ground/ui/startup/StartupViewModel.kt index 95187bffcb..92700dd570 100644 --- a/ground/src/main/java/com/google/android/ground/ui/startup/StartupViewModel.kt +++ b/ground/src/main/java/com/google/android/ground/ui/startup/StartupViewModel.kt @@ -31,7 +31,7 @@ internal constructor( suspend fun initializeLogin(): Boolean { val isGooglePlayServicesAvailable = googleApiManager.installGooglePlayServices() if (!isGooglePlayServicesAvailable) { - return false + error("Google Play Services installation failed") } userRepository.init() return true From 0acdcc41adf6fd2ed97c456486b628da2e3cf07d Mon Sep 17 00:00:00 2001 From: Gino Miceli <228050+gino-m@users.noreply.github.com> Date: Mon, 9 Dec 2024 11:14:33 -0500 Subject: [PATCH 07/10] Update GoogleApiManager.kt --- .../java/com/google/android/ground/system/GoogleApiManager.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt b/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt index d014ad8f3a..3bb6afef0f 100644 --- a/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt +++ b/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt @@ -54,8 +54,8 @@ constructor( googleApiAvailability.showErrorDialogFragment(activity, status, requestCode, null) } getNextResult(requestCode) - } catch (t: Throwable) { - Timber.e("Activity result was not successful for requestCode: $requestCode and throws $t") + } catch (e: Exception) { + Timber.e(e, "Activity result was not successful for requestCode: $requestCode") false } } From 416cbcdfab56134ba3ec00e4d37871d3d4391e46 Mon Sep 17 00:00:00 2001 From: Akshay Nandwana Date: Tue, 10 Dec 2024 12:35:40 +0530 Subject: [PATCH 08/10] suggested fix --- .../com/google/android/ground/system/GoogleApiManager.kt | 6 ++---- .../google/android/ground/ui/startup/StartupViewModel.kt | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt b/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt index 3bb6afef0f..096c04153a 100644 --- a/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt +++ b/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt @@ -60,8 +60,6 @@ constructor( } } - private suspend fun getNextResult(requestCode: Int): Boolean { - val result = activityStreams.getNextActivityResult(requestCode) - return result.isOk() - } + private suspend fun getNextResult(requestCode: Int) = + activityStreams.getNextActivityResult(requestCode).isOk() } diff --git a/ground/src/main/java/com/google/android/ground/ui/startup/StartupViewModel.kt b/ground/src/main/java/com/google/android/ground/ui/startup/StartupViewModel.kt index 92700dd570..ed47da7e44 100644 --- a/ground/src/main/java/com/google/android/ground/ui/startup/StartupViewModel.kt +++ b/ground/src/main/java/com/google/android/ground/ui/startup/StartupViewModel.kt @@ -28,12 +28,11 @@ internal constructor( ) : AbstractViewModel() { /** Checks & installs Google Play Services and initializes the login flow. */ - suspend fun initializeLogin(): Boolean { + suspend fun initializeLogin() { val isGooglePlayServicesAvailable = googleApiManager.installGooglePlayServices() if (!isGooglePlayServicesAvailable) { error("Google Play Services installation failed") } userRepository.init() - return true } } From 4e9b53ae0160e085213803fa3b14a1508f03c405 Mon Sep 17 00:00:00 2001 From: Akshay Nandwana Date: Tue, 10 Dec 2024 12:41:18 +0530 Subject: [PATCH 09/10] more helpful log message --- .../com/google/android/ground/system/GoogleApiManager.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt b/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt index 096c04153a..6c6f2adf9c 100644 --- a/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt +++ b/ground/src/main/java/com/google/android/ground/system/GoogleApiManager.kt @@ -55,7 +55,10 @@ constructor( } getNextResult(requestCode) } catch (e: Exception) { - Timber.e(e, "Activity result was not successful for requestCode: $requestCode") + Timber.e( + e, + "Failed to handle activity result for requestCode: $requestCode. Exception details: ${e.message}", + ) false } } From 685d5e6dba982e1685b91d5b1897d6e64c8cfd11 Mon Sep 17 00:00:00 2001 From: Akshay Nandwana Date: Thu, 12 Dec 2024 14:57:11 +0530 Subject: [PATCH 10/10] revert --- .../com/google/android/ground/ui/startup/StartupViewModel.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ground/src/main/java/com/google/android/ground/ui/startup/StartupViewModel.kt b/ground/src/main/java/com/google/android/ground/ui/startup/StartupViewModel.kt index 10faec1a8b..73ec0cef28 100644 --- a/ground/src/main/java/com/google/android/ground/ui/startup/StartupViewModel.kt +++ b/ground/src/main/java/com/google/android/ground/ui/startup/StartupViewModel.kt @@ -29,10 +29,7 @@ internal constructor( /** Initializes the login flow, installing Google Play Services if necessary. */ suspend fun initializeLogin() { - val isGooglePlayServicesAvailable = googleApiManager.installGooglePlayServices() - if (!isGooglePlayServicesAvailable) { - error("Google Play Services installation failed") - } + googleApiManager.installGooglePlayServices() userRepository.init() } }