Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
simond-stripe committed Nov 19, 2024
1 parent 484a84b commit 9e85b34
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,7 @@ internal class StripeConnectWebViewContainerImpl(
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")
}
)
internal val stripeWebChromeContainer = StripeConnectWebChromeClient()

private var controller: StripeConnectWebViewContainerController? = null

Expand Down Expand Up @@ -231,45 +224,14 @@ internal class StripeConnectWebViewContainerImpl(
}
}

internal class StripeConnectWebChromeClient(
private val context: Context,
private val embeddedComponentManager: EmbeddedComponentManager,
private val viewScope: () -> LifecycleCoroutineScope,
) : WebChromeClient() {

private val inProgressRequests: MutableMap<PermissionRequest, Job> = mutableMapOf()

internal inner class StripeConnectWebChromeClient : WebChromeClient() {
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
}
controller?.onPermissionRequest(request)
}

override fun onPermissionRequestCanceled(request: PermissionRequest?) {
if (request == null) return
inProgressRequests.remove(request)?.also { it.cancel() }
controller?.onPermissionRequestCanceled(request)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package com.stripe.android.connect.webview

import android.Manifest
import android.content.pm.PackageManager
import android.webkit.PermissionRequest
import androidx.annotation.RestrictTo
import androidx.core.content.ContextCompat.checkSelfPermission
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
Expand All @@ -9,11 +13,14 @@ import androidx.lifecycle.repeatOnLifecycle
import com.stripe.android.connect.EmbeddedComponentManager
import com.stripe.android.connect.PrivateBetaConnectSDK
import com.stripe.android.connect.StripeEmbeddedComponent
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

@OptIn(PrivateBetaConnectSDK::class)
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
Expand All @@ -31,6 +38,8 @@ internal class StripeConnectWebViewContainerController(
val stateFlow: StateFlow<StripeConnectWebViewContainerState>
get() = _stateFlow.asStateFlow()

private val inProgressRequests: MutableMap<PermissionRequest, Job> = mutableMapOf()

/**
* Callback to invoke when the view is attached.
*/
Expand Down Expand Up @@ -68,6 +77,44 @@ internal class StripeConnectWebViewContainerController(
return embeddedComponentManager.fetchClientSecret()
}

/**
*
*/
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
}
}

/**
*
*/
fun onPermissionRequestCanceled(request: PermissionRequest) {
inProgressRequests.remove(request)?.also { it.cancel() }
}

/**
* Callback to invoke upon receiving 'pageDidLoad' message.
*/
Expand Down

0 comments on commit 9e85b34

Please sign in to comment.