From bd61abc7ec3e275e6097363f0d19e08bb97bc10b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joris=20Pelgr=C3=B6m?= Date: Sat, 4 Jan 2025 22:24:18 +0100 Subject: [PATCH] Always request Bluetooth permission for Improv if 1/2 is granted (#4952) --- .../android/webview/WebViewActivity.kt | 13 +++++++++++- .../android/webview/WebViewPresenter.kt | 7 +++++++ .../android/webview/WebViewPresenterImpl.kt | 20 +++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/io/homeassistant/companion/android/webview/WebViewActivity.kt b/app/src/main/java/io/homeassistant/companion/android/webview/WebViewActivity.kt index 23e50d9cef3..a8502114490 100644 --- a/app/src/main/java/io/homeassistant/companion/android/webview/WebViewActivity.kt +++ b/app/src/main/java/io/homeassistant/companion/android/webview/WebViewActivity.kt @@ -157,6 +157,12 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi downloadFile(downloadFileUrl, downloadFileContentDisposition, downloadFileMimetype) } } + private val requestImprovPermission = + registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted -> + if (isGranted) { + presenter.startScanningForImprov() + } + } private val writeNfcTag = registerForActivityResult(WriteNfcTag()) { messageId -> sendExternalBusMessage( ExternalBusMessage( @@ -1696,7 +1702,12 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi val dialog = ImprovPermissionDialog() dialog.show(supportFragmentManager, ImprovPermissionDialog.TAG) } else { - presenter.startScanningForImprov() + val safePermissionToRequest = presenter.shouldRequestImprovPermission() + if (safePermissionToRequest != null) { + requestImprovPermission.launch(safePermissionToRequest) + } else { + presenter.startScanningForImprov() + } } } } diff --git a/app/src/main/java/io/homeassistant/companion/android/webview/WebViewPresenter.kt b/app/src/main/java/io/homeassistant/companion/android/webview/WebViewPresenter.kt index 3d39621632b..064744827b9 100644 --- a/app/src/main/java/io/homeassistant/companion/android/webview/WebViewPresenter.kt +++ b/app/src/main/java/io/homeassistant/companion/android/webview/WebViewPresenter.kt @@ -69,6 +69,13 @@ interface WebViewPresenter { /** @return `true` if the app should prompt the user for Improv permissions before scanning */ suspend fun shouldShowImprovPermissions(): Boolean + /** + * @return Improv permission the app should request directly, without showing a prompt. + * This may occur when one of two Bluetooth related permissions is granted and the other one + * is not. The system should automatically grant this when requested. + * */ + fun shouldRequestImprovPermission(): String? + /** @return `true` if the app tried starting scanning or `false` if it was missing permissions */ fun startScanningForImprov(): Boolean fun stopScanningForImprov(force: Boolean) diff --git a/app/src/main/java/io/homeassistant/companion/android/webview/WebViewPresenterImpl.kt b/app/src/main/java/io/homeassistant/companion/android/webview/WebViewPresenterImpl.kt index d74552fecaa..7c9c24bf1d7 100644 --- a/app/src/main/java/io/homeassistant/companion/android/webview/WebViewPresenterImpl.kt +++ b/app/src/main/java/io/homeassistant/companion/android/webview/WebViewPresenterImpl.kt @@ -1,12 +1,15 @@ package io.homeassistant.companion.android.webview +import android.Manifest import android.app.Activity import android.content.Context import android.content.IntentSender +import android.content.pm.PackageManager import android.graphics.Color import android.net.Uri import android.util.Log import androidx.activity.result.ActivityResult +import androidx.core.content.ContextCompat import dagger.hilt.android.qualifiers.ActivityContext import io.homeassistant.companion.android.common.R as commonR import io.homeassistant.companion.android.common.data.authentication.SessionState @@ -489,6 +492,23 @@ class WebViewPresenterImpl @Inject constructor( } } + override fun shouldRequestImprovPermission(): String? { + var returnPermissions = try { + improvRepository.getRequiredPermissions().filter { + ContextCompat.checkSelfPermission(view as Context, it) != PackageManager.PERMISSION_GRANTED + } + } catch (_: Exception) { + // Unable to check, ignore + emptyList() + } + return if (returnPermissions.size == 1 && returnPermissions[0] != Manifest.permission.ACCESS_FINE_LOCATION) { + Log.d(TAG, "Should request Improv permission: $returnPermissions") + returnPermissions[0] + } else { + null + } + } + override fun startScanningForImprov(): Boolean { if (!improvRepository.hasPermission(view as Context)) { Log.d(TAG, "Improv scan request ignored because app doesn't have permission")