From 484a84bf082f09eec3624791573d9f6613fa4459 Mon Sep 17 00:00:00 2001 From: Simon Duchastel Date: Tue, 19 Nov 2024 13:55:18 -0500 Subject: [PATCH] Fix leftover merge conflicts --- .../webview/StripeConnectWebChromeClient.kt | 62 ------------------ .../webview/StripeConnectWebViewClient.kt | 0 .../webview/StripeConnectWebViewContainer.kt | 63 +++++++++++++++++++ 3 files changed, 63 insertions(+), 62 deletions(-) delete mode 100644 connect/src/main/java/com/stripe/android/connect/webview/StripeConnectWebChromeClient.kt delete mode 100644 connect/src/main/java/com/stripe/android/connect/webview/StripeConnectWebViewClient.kt diff --git a/connect/src/main/java/com/stripe/android/connect/webview/StripeConnectWebChromeClient.kt b/connect/src/main/java/com/stripe/android/connect/webview/StripeConnectWebChromeClient.kt deleted file mode 100644 index 41035564efd..00000000000 --- a/connect/src/main/java/com/stripe/android/connect/webview/StripeConnectWebChromeClient.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.stripe.android.connect.webview - -import android.Manifest -import android.content.Context -import android.content.pm.PackageManager -import android.webkit.PermissionRequest -import android.webkit.WebChromeClient -import androidx.core.content.ContextCompat.checkSelfPermission -import androidx.lifecycle.LifecycleCoroutineScope -import com.stripe.android.connect.EmbeddedComponentManager -import com.stripe.android.connect.PrivateBetaConnectSDK -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext - -/** - * A [WebChromeClient] that handles permission requests for the Stripe Connect WebView. - * This should be used in conjunction with [StripeConnectWebViewClient]. - */ -@OptIn(PrivateBetaConnectSDK::class) -internal class StripeConnectWebChromeClient( - private val context: Context, - private val embeddedComponentManager: EmbeddedComponentManager, - private val viewScope: () -> LifecycleCoroutineScope, -) : WebChromeClient() { - - private val inProgressRequests: MutableMap = mutableMapOf() - - override fun onPermissionRequest(request: PermissionRequest) { - // we only care about camera permissions at this time (video/audio) - val permissionsRequested = request.resources.filter { - it in listOf(PermissionRequest.RESOURCE_VIDEO_CAPTURE, PermissionRequest.RESOURCE_AUDIO_CAPTURE) - }.toTypedArray() - if (permissionsRequested.isEmpty()) { - request.deny() // no supported permissions were requested, so reject the request - return - } - - if (checkSelfPermission(context, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) { - request.grant(permissionsRequested) - } else { - val job = viewScope().launch { - val isGranted = embeddedComponentManager.requestCameraPermission() - withContext(Dispatchers.Main) { - if (isGranted) { - request.grant(permissionsRequested) - } else { - request.deny() - } - } - inProgressRequests.remove(request) - } - inProgressRequests[request] = job - } - } - - override fun onPermissionRequestCanceled(request: PermissionRequest?) { - if (request == null) return - inProgressRequests.remove(request)?.also { it.cancel() } - } -} diff --git a/connect/src/main/java/com/stripe/android/connect/webview/StripeConnectWebViewClient.kt b/connect/src/main/java/com/stripe/android/connect/webview/StripeConnectWebViewClient.kt deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/connect/src/main/java/com/stripe/android/connect/webview/StripeConnectWebViewContainer.kt b/connect/src/main/java/com/stripe/android/connect/webview/StripeConnectWebViewContainer.kt index c33cde7d807..ccfd040c157 100644 --- a/connect/src/main/java/com/stripe/android/connect/webview/StripeConnectWebViewContainer.kt +++ b/connect/src/main/java/com/stripe/android/connect/webview/StripeConnectWebViewContainer.kt @@ -1,17 +1,24 @@ package com.stripe.android.connect.webview +import android.Manifest import android.annotation.SuppressLint +import android.content.Context +import android.content.pm.PackageManager import android.graphics.Bitmap import android.view.LayoutInflater import android.webkit.JavascriptInterface +import android.webkit.PermissionRequest +import android.webkit.WebChromeClient import android.webkit.WebView import android.webkit.WebViewClient import android.widget.FrameLayout import androidx.annotation.RestrictTo import androidx.annotation.VisibleForTesting +import androidx.core.content.ContextCompat.checkSelfPermission import androidx.core.view.doOnAttach import androidx.core.view.doOnDetach import androidx.core.view.isVisible +import androidx.lifecycle.LifecycleCoroutineScope import androidx.lifecycle.findViewTreeLifecycleOwner import androidx.lifecycle.lifecycleScope import com.stripe.android.connect.BuildConfig @@ -28,9 +35,12 @@ import com.stripe.android.connect.webview.serialization.SetterMessage import com.stripe.android.connect.webview.serialization.toJs import com.stripe.android.core.Logger import com.stripe.android.core.version.StripeSdkVersion +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withContext import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.encodeToJsonElement @@ -79,6 +89,16 @@ internal class StripeConnectWebViewContainerImpl( @VisibleForTesting internal val stripeWebViewClient = StripeConnectWebViewClient() + @VisibleForTesting + internal val stripeWebChromeContainer = StripeConnectWebChromeClient( + context = webView?.context ?: throw IllegalStateException("WebView is not initialized"), + embeddedComponentManager = embeddedComponentManager + ?: throw IllegalStateException("EmbeddedComponentManager is not initialized"), + viewScope = { + webView?.findViewTreeLifecycleOwner()?.lifecycleScope ?: throw IllegalStateException("View is not attached") + } + ) + private var controller: StripeConnectWebViewContainerController? = null init { @@ -105,6 +125,7 @@ internal class StripeConnectWebViewContainerImpl( internal fun initializeWebView(webView: WebView) { with(webView) { webViewClient = stripeWebViewClient + webChromeClient = stripeWebChromeContainer settings.apply { @SuppressLint("SetJavaScriptEnabled") javaScriptEnabled = true @@ -210,6 +231,48 @@ internal class StripeConnectWebViewContainerImpl( } } + internal class StripeConnectWebChromeClient( + private val context: Context, + private val embeddedComponentManager: EmbeddedComponentManager, + private val viewScope: () -> LifecycleCoroutineScope, + ) : WebChromeClient() { + + private val inProgressRequests: MutableMap = mutableMapOf() + + override fun onPermissionRequest(request: PermissionRequest) { + // we only care about camera permissions at this time (video/audio) + val permissionsRequested = request.resources.filter { + it in listOf(PermissionRequest.RESOURCE_VIDEO_CAPTURE, PermissionRequest.RESOURCE_AUDIO_CAPTURE) + }.toTypedArray() + if (permissionsRequested.isEmpty()) { + request.deny() // no supported permissions were requested, so reject the request + return + } + + if (checkSelfPermission(context, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) { + request.grant(permissionsRequested) + } else { + val job = viewScope().launch { + val isGranted = embeddedComponentManager.requestCameraPermission() + withContext(Dispatchers.Main) { + if (isGranted) { + request.grant(permissionsRequested) + } else { + request.deny() + } + } + inProgressRequests.remove(request) + } + inProgressRequests[request] = job + } + } + + override fun onPermissionRequestCanceled(request: PermissionRequest?) { + if (request == null) return + inProgressRequests.remove(request)?.also { it.cancel() } + } + } + private inner class StripeJsInterface { @JavascriptInterface fun debug(message: String) {