|
|
|
@ -4,8 +4,9 @@
|
|
|
|
|
|
|
|
|
|
package org.mozilla.fenix.settings.quicksettings
|
|
|
|
|
|
|
|
|
|
import android.util.TypedValue
|
|
|
|
|
import android.view.View
|
|
|
|
|
import android.view.View.GONE
|
|
|
|
|
import android.view.View.VISIBLE
|
|
|
|
|
import android.view.ViewGroup
|
|
|
|
|
import android.widget.TextView
|
|
|
|
|
import androidx.appcompat.content.res.AppCompatResources
|
|
|
|
@ -14,9 +15,10 @@ import androidx.core.content.ContextCompat
|
|
|
|
|
import io.reactivex.Observable
|
|
|
|
|
import io.reactivex.Observer
|
|
|
|
|
import io.reactivex.functions.Consumer
|
|
|
|
|
import mozilla.components.feature.sitepermissions.SitePermissions
|
|
|
|
|
import mozilla.components.feature.sitepermissions.SitePermissions.Status.NO_DECISION
|
|
|
|
|
import mozilla.components.support.ktx.android.net.hostWithoutCommonPrefixes
|
|
|
|
|
import mozilla.components.support.ktx.kotlin.toUri
|
|
|
|
|
import org.jetbrains.anko.textColorResource
|
|
|
|
|
import org.mozilla.fenix.R
|
|
|
|
|
import org.mozilla.fenix.mvi.UIView
|
|
|
|
|
import org.mozilla.fenix.settings.PhoneFeature
|
|
|
|
@ -24,7 +26,6 @@ import org.mozilla.fenix.settings.PhoneFeature.CAMERA
|
|
|
|
|
import org.mozilla.fenix.settings.PhoneFeature.LOCATION
|
|
|
|
|
import org.mozilla.fenix.settings.PhoneFeature.MICROPHONE
|
|
|
|
|
import org.mozilla.fenix.settings.PhoneFeature.NOTIFICATION
|
|
|
|
|
import org.mozilla.fenix.utils.ItsNotBrokenSnack
|
|
|
|
|
import org.mozilla.fenix.utils.Settings
|
|
|
|
|
|
|
|
|
|
class QuickSettingsUIView(
|
|
|
|
@ -38,26 +39,28 @@ class QuickSettingsUIView(
|
|
|
|
|
private val securityInfoLabel: TextView
|
|
|
|
|
private val urlLabel: TextView
|
|
|
|
|
private val cameraActionLabel: TextView
|
|
|
|
|
private val cameraLabel: TextView
|
|
|
|
|
private val microphoneActionLabel: TextView
|
|
|
|
|
private val microphoneLabel: TextView
|
|
|
|
|
private val locationActionLabel: TextView
|
|
|
|
|
private val locationLabel: TextView
|
|
|
|
|
private val notificationActionLabel: TextView
|
|
|
|
|
private val notificationLabel: TextView
|
|
|
|
|
private val blockedByAndroidPhoneFeatures = mutableListOf<PhoneFeature>()
|
|
|
|
|
private val context get() = view.context
|
|
|
|
|
private val settings: Settings = Settings.getInstance(context)
|
|
|
|
|
|
|
|
|
|
private val toolbarTextColorId by lazy {
|
|
|
|
|
val typedValue = TypedValue()
|
|
|
|
|
context.theme.resolveAttribute(R.attr.toolbarTextColor, typedValue, true)
|
|
|
|
|
typedValue.resourceId
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
init {
|
|
|
|
|
urlLabel = view.findViewById<AppCompatTextView>(R.id.url)
|
|
|
|
|
securityInfoLabel = view.findViewById<AppCompatTextView>(R.id.security_info)
|
|
|
|
|
cameraActionLabel = view.findViewById<AppCompatTextView>(R.id.camera_action_label)
|
|
|
|
|
cameraLabel = view.findViewById<AppCompatTextView>(R.id.camera_icon)
|
|
|
|
|
microphoneActionLabel = view.findViewById<AppCompatTextView>(R.id.microphone_action_label)
|
|
|
|
|
microphoneLabel = view.findViewById<AppCompatTextView>(R.id.microphone_icon)
|
|
|
|
|
locationLabel = view.findViewById<AppCompatTextView>(R.id.location_icon)
|
|
|
|
|
locationActionLabel = view.findViewById<AppCompatTextView>(R.id.location_action_label)
|
|
|
|
|
notificationActionLabel = view.findViewById<AppCompatTextView>(R.id.notification_action_label)
|
|
|
|
|
notificationLabel = view.findViewById<AppCompatTextView>(R.id.notification_icon)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override fun updateView() = Consumer<QuickSettingsState> { state ->
|
|
|
|
@ -65,20 +68,20 @@ class QuickSettingsUIView(
|
|
|
|
|
is QuickSettingsState.Mode.Normal -> {
|
|
|
|
|
bindUrl(state.mode.url)
|
|
|
|
|
bindSecurityInfo(state.mode.isSecured)
|
|
|
|
|
bindPhoneFeatureItem(cameraActionLabel, CAMERA)
|
|
|
|
|
bindPhoneFeatureItem(microphoneActionLabel, MICROPHONE)
|
|
|
|
|
bindPhoneFeatureItem(notificationActionLabel, NOTIFICATION)
|
|
|
|
|
bindPhoneFeatureItem(locationActionLabel, LOCATION)
|
|
|
|
|
bindManagePermissionsButton()
|
|
|
|
|
bindPhoneFeatureItem(cameraActionLabel, CAMERA, state.mode.sitePermissions)
|
|
|
|
|
bindPhoneFeatureItem(microphoneActionLabel, MICROPHONE, state.mode.sitePermissions)
|
|
|
|
|
bindPhoneFeatureItem(notificationActionLabel, NOTIFICATION, state.mode.sitePermissions)
|
|
|
|
|
bindPhoneFeatureItem(locationActionLabel, LOCATION, state.mode.sitePermissions)
|
|
|
|
|
}
|
|
|
|
|
is QuickSettingsState.Mode.ActionLabelUpdated -> {
|
|
|
|
|
bindPhoneFeatureItem(
|
|
|
|
|
state.mode.phoneFeature.actionLabel,
|
|
|
|
|
state.mode.phoneFeature
|
|
|
|
|
state.mode.phoneFeature.labelAndAction.second,
|
|
|
|
|
state.mode.phoneFeature,
|
|
|
|
|
state.mode.sitePermissions
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
is QuickSettingsState.Mode.CheckPendingFeatureBlockedByAndroid -> {
|
|
|
|
|
checkFeaturesBlockedByAndroid()
|
|
|
|
|
checkFeaturesBlockedByAndroid(state.mode.sitePermissions)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -108,17 +111,41 @@ class QuickSettingsUIView(
|
|
|
|
|
securityInfoLabel.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun bindPhoneFeatureItem(actionLabel: TextView, phoneFeature: PhoneFeature) {
|
|
|
|
|
private fun bindPhoneFeatureItem(
|
|
|
|
|
actionLabel: TextView,
|
|
|
|
|
phoneFeature: PhoneFeature,
|
|
|
|
|
sitePermissions: SitePermissions? = null
|
|
|
|
|
) {
|
|
|
|
|
if (phoneFeature.shouldBeHidden(sitePermissions)) {
|
|
|
|
|
hide(phoneFeature)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
show(phoneFeature)
|
|
|
|
|
if (!phoneFeature.isAndroidPermissionGranted(context)) {
|
|
|
|
|
handleBlockedByAndroidAction(actionLabel, phoneFeature)
|
|
|
|
|
} else {
|
|
|
|
|
bindPhoneAction(actionLabel, phoneFeature)
|
|
|
|
|
bindPhoneAction(actionLabel, phoneFeature, sitePermissions)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun show(phoneFeature: PhoneFeature) {
|
|
|
|
|
val (label, action) = phoneFeature.labelAndAction
|
|
|
|
|
label.visibility = VISIBLE
|
|
|
|
|
action.visibility = VISIBLE
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun hide(phoneFeature: PhoneFeature) {
|
|
|
|
|
val (label, action) = phoneFeature.labelAndAction
|
|
|
|
|
label.visibility = GONE
|
|
|
|
|
action.visibility = GONE
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun PhoneFeature.shouldBeHidden(sitePermissions: SitePermissions?): Boolean {
|
|
|
|
|
return getStatus(sitePermissions, settings) == NO_DECISION
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun handleBlockedByAndroidAction(actionLabel: TextView, phoneFeature: PhoneFeature) {
|
|
|
|
|
actionLabel.setText(R.string.phone_feature_blocked_by_android)
|
|
|
|
|
actionLabel.setTextColor(ContextCompat.getColor(context, R.color.photonBlue50))
|
|
|
|
|
actionLabel.tag = phoneFeature
|
|
|
|
|
actionLabel.setOnClickListener {
|
|
|
|
|
val feature = it.tag as PhoneFeature
|
|
|
|
@ -131,38 +158,44 @@ class QuickSettingsUIView(
|
|
|
|
|
blockedByAndroidPhoneFeatures.add(phoneFeature)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun bindPhoneAction(actionLabel: TextView, phoneFeature: PhoneFeature) {
|
|
|
|
|
actionLabel.text = phoneFeature.getActionLabel(context = context, settings = settings)
|
|
|
|
|
actionLabel.textColorResource = toolbarTextColorId
|
|
|
|
|
actionLabel.isEnabled = false
|
|
|
|
|
blockedByAndroidPhoneFeatures.remove(phoneFeature)
|
|
|
|
|
}
|
|
|
|
|
private fun bindPhoneAction(
|
|
|
|
|
actionLabel: TextView,
|
|
|
|
|
phoneFeature: PhoneFeature,
|
|
|
|
|
sitePermissions: SitePermissions? = null
|
|
|
|
|
) {
|
|
|
|
|
actionLabel.text = phoneFeature.getActionLabel(
|
|
|
|
|
context = context,
|
|
|
|
|
sitePermissions = sitePermissions,
|
|
|
|
|
settings = settings
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
private fun bindManagePermissionsButton() {
|
|
|
|
|
val urlLabel = view.findViewById<TextView>(R.id.manage_site_permissions)
|
|
|
|
|
urlLabel.setOnClickListener {
|
|
|
|
|
actionEmitter.onNext(QuickSettingsAction.DismissDialog)
|
|
|
|
|
ItsNotBrokenSnack(context).showSnackbar(issueNumber = "1170")
|
|
|
|
|
actionLabel.tag = phoneFeature
|
|
|
|
|
actionLabel.setOnClickListener {
|
|
|
|
|
val feature = it.tag as PhoneFeature
|
|
|
|
|
actionEmitter.onNext(
|
|
|
|
|
QuickSettingsAction.TogglePermission(feature)
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
blockedByAndroidPhoneFeatures.remove(phoneFeature)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun checkFeaturesBlockedByAndroid() {
|
|
|
|
|
private fun checkFeaturesBlockedByAndroid(sitePermissions: SitePermissions?) {
|
|
|
|
|
val clonedList = blockedByAndroidPhoneFeatures.toTypedArray()
|
|
|
|
|
clonedList.forEach { phoneFeature ->
|
|
|
|
|
if (phoneFeature.isAndroidPermissionGranted(context)) {
|
|
|
|
|
val actionLabel = phoneFeature.actionLabel
|
|
|
|
|
bindPhoneAction(actionLabel, phoneFeature)
|
|
|
|
|
val actionLabel = phoneFeature.labelAndAction.second
|
|
|
|
|
bindPhoneAction(actionLabel, phoneFeature, sitePermissions)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private val PhoneFeature.actionLabel
|
|
|
|
|
get(): TextView {
|
|
|
|
|
private val PhoneFeature.labelAndAction
|
|
|
|
|
get(): Pair<TextView, TextView> {
|
|
|
|
|
return when (this) {
|
|
|
|
|
CAMERA -> cameraActionLabel
|
|
|
|
|
LOCATION -> locationActionLabel
|
|
|
|
|
MICROPHONE -> microphoneActionLabel
|
|
|
|
|
NOTIFICATION -> notificationActionLabel
|
|
|
|
|
CAMERA -> cameraLabel to cameraActionLabel
|
|
|
|
|
LOCATION -> locationLabel to locationActionLabel
|
|
|
|
|
MICROPHONE -> microphoneLabel to microphoneActionLabel
|
|
|
|
|
NOTIFICATION -> notificationLabel to notificationActionLabel
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|