Commit c80f2cc1 authored by Valere's avatar Valere

Permission UX for webviews

parent 6155f941
......@@ -31,6 +31,7 @@ import im.vector.Matrix
import im.vector.R
import im.vector.activity.util.INTEGRATION_MANAGER_ACTIVITY_REQUEST_CODE
import im.vector.activity.util.TERMS_REQUEST_CODE
import im.vector.fragments.roomwidgets.WebviewPermissionUtils
import im.vector.types.JsonDict
import im.vector.types.WidgetEventData
import im.vector.util.AssetReader
......@@ -194,7 +195,7 @@ abstract class AbstractWidgetActivity : VectorAppCompatActivity() {
// Permission requests
it.webChromeClient = object : WebChromeClient() {
override fun onPermissionRequest(request: PermissionRequest) {
runOnUiThread { request.grant(request.resources) }
WebviewPermissionUtils.promptForPermissions(R.string.room_widget_resource_permission_title, request, this@AbstractWidgetActivity)
}
override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean {
......
......@@ -21,8 +21,6 @@ import android.content.Intent
import android.graphics.Bitmap
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.Menu
import android.view.MenuItem
import android.view.View
......@@ -250,9 +248,7 @@ class RoomWidgetFragment : VectorBaseMvRxFragment(), HandleBackParticipant {
}
override fun onPrepareOptionsMenu(menu: Menu?) = withState(viewModel) { state ->
menu?.findItem(R.id.action_close)?.let {
it.isVisible = state.canManageWidgets
}
menu?.findItem(R.id.action_close)?.isVisible = state.canManageWidgets
super.onPrepareOptionsMenu(menu)
}
......@@ -283,16 +279,16 @@ class RoomWidgetFragment : VectorBaseMvRxFragment(), HandleBackParticipant {
*/
@SuppressLint("NewApi")
private fun configureWebView() {
mWidgetWebView?.let {
mWidgetWebView?.let { webview ->
// xml value seems ignored
it.setBackgroundColor(ThemeUtils.getColor(requireContext(), R.attr.vctr_bottom_nav_background_color))
webview.setBackgroundColor(ThemeUtils.getColor(requireContext(), R.attr.vctr_bottom_nav_background_color))
// clear caches
it.clearHistory()
it.clearFormData()
it.clearCache(true)
webview.clearHistory()
webview.clearFormData()
webview.clearCache(true)
it.settings.let { settings ->
webview.settings.let { settings ->
// does not cache the data
settings.cacheMode = WebSettings.LOAD_NO_CACHE
......@@ -316,17 +312,19 @@ class RoomWidgetFragment : VectorBaseMvRxFragment(), HandleBackParticipant {
}
// Permission requests
it.webChromeClient = object : WebChromeClient() {
webview.webChromeClient = object : WebChromeClient() {
override fun onPermissionRequest(request: PermissionRequest) {
Handler(Looper.getMainLooper()).post { request.grant(request.resources) }
activity?.let {
WebviewPermissionUtils.promptForPermissions(R.string.room_widget_resource_permission_title, request, it)
}
}
}
it.webViewClient = webViewClient
webview.webViewClient = webViewClient
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val cookieManager = CookieManager.getInstance()
cookieManager.setAcceptThirdPartyCookies(mWidgetWebView, true)
cookieManager.setAcceptThirdPartyCookies(mWidgetWebView, false)
}
}
}
......@@ -346,5 +344,4 @@ class RoomWidgetFragment : VectorBaseMvRxFragment(), HandleBackParticipant {
it.onPause()
}
}
}
\ No newline at end of file
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.fragments.roomwidgets
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.webkit.PermissionRequest
import androidx.annotation.StringRes
import androidx.appcompat.app.AlertDialog
import im.vector.R
object WebviewPermissionUtils {
@SuppressLint("NewApi")
fun promptForPermissions(@StringRes title: Int, request: PermissionRequest, activity: Activity) {
if (activity.isFinishing || activity.isDestroyed) return
val allowedPermissions = request.resources.map {
it to false
}.toMutableList()
AlertDialog.Builder(activity)
.setTitle(title)
.setMultiChoiceItems(
request.resources.map { webPermissionToHumanReadable(it, activity) }.toTypedArray()
, null
) { dialog, which, isChecked ->
allowedPermissions[which] = allowedPermissions[which].first to isChecked
}
.setPositiveButton(R.string.room_widget_resource_grant_permission) { dialog, wich ->
activity.runOnUiThread {
request.grant(allowedPermissions.mapNotNull { perm ->
perm.first.takeIf { perm.second }
}.toTypedArray())
}
}
.setNegativeButton(R.string.room_widget_resource_decline_permission) { dialog, wich ->
activity.runOnUiThread { request.deny() }
}
.show()
}
private fun webPermissionToHumanReadable(permission: String, context: Context): String {
return when (permission) {
PermissionRequest.RESOURCE_AUDIO_CAPTURE -> context.getString(R.string.room_widget_webview_access_microphone)
PermissionRequest.RESOURCE_VIDEO_CAPTURE -> context.getString(R.string.room_widget_webview_access_camera)
PermissionRequest.RESOURCE_PROTECTED_MEDIA_ID -> context.getString(R.string.room_widget_webview_read_protected_media)
else -> permission
}
}
}
\ No newline at end of file
......@@ -1132,6 +1132,12 @@
<string name="error_jitsi_not_supported_on_old_device">Sorry, conference calls with Jitsi are not supported on old devices (devices with Android OS below 5.0)</string>
<string name="room_widget_resource_permission_title">This widget wants to use the following resources:</string>
<string name="room_widget_resource_grant_permission">Allow</string>
<string name="room_widget_resource_decline_permission">Block All</string>
<string name="room_widget_webview_access_camera">Use the camera</string>
<string name="room_widget_webview_access_microphone">Use the microphone</string>
<string name="room_widget_webview_read_protected_media">Read DRM protected Media</string>
<!-- Widget Integration Manager -->
<string name="widget_integration_unable_to_create">Unable to create widget.</string>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment