mirror of
https://github.com/fork-maintainers/iceraven-browser
synced 2024-11-15 18:12:54 +00:00
Bug 1810044 1810045 - Delay reading clipboard and allow to paste non url
This commit is contained in:
parent
5a06549a3b
commit
06fb70e5db
@ -39,10 +39,7 @@ class ClipboardHandler(val context: Context) {
|
||||
if (clipboard.isPrimaryClipEmpty()) {
|
||||
return null
|
||||
}
|
||||
if (clipboard.isPrimaryClipPlainText() ||
|
||||
clipboard.isPrimaryClipHtmlText() ||
|
||||
clipboard.isPrimaryClipUrlText()
|
||||
) {
|
||||
if (containsText()) {
|
||||
return firstSafePrimaryClipItemText
|
||||
}
|
||||
return null
|
||||
@ -101,6 +98,16 @@ class ClipboardHandler(val context: Context) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the clipboard data contains text.
|
||||
* We cannot rely on `isPrimaryClipEmpty()` since it triggers a clipboard access system notification.
|
||||
*/
|
||||
fun containsText(): Boolean {
|
||||
return clipboard.isPrimaryClipHtmlText() ||
|
||||
clipboard.isPrimaryClipPlainText() ||
|
||||
clipboard.isPrimaryClipUrlText()
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
internal fun containsURL(): Boolean {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
@ -127,6 +134,13 @@ class ClipboardHandler(val context: Context) {
|
||||
private fun ClipboardManager.isPrimaryClipUrlText() =
|
||||
primaryClipDescription?.hasMimeType(MIME_TYPE_TEXT_URL) ?: false
|
||||
|
||||
/**
|
||||
* Returns whether or not the clipboard has any clip data.
|
||||
* Reads the clip data, be aware this is a sensitive API as from Android 12 and above,
|
||||
* accessing it will trigger a notification letting the user know the app has accessed the clipboard,
|
||||
* make sure when you call this API that users are completely aware that we are accessing the clipboard.
|
||||
* See https://github.com/mozilla-mobile/fenix/issues/22271 for more details.
|
||||
*/
|
||||
private fun ClipboardManager.isPrimaryClipEmpty() = primaryClip?.itemCount == 0
|
||||
|
||||
/**
|
||||
|
@ -26,6 +26,10 @@ import org.mozilla.fenix.databinding.BrowserToolbarPopupWindowBinding
|
||||
import org.mozilla.fenix.ext.components
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
/**
|
||||
* Since Android 12 reading the clipboard triggers an OS notification.
|
||||
* As such it is important that we do not read it prematurely and only when the user trigger a paste action.
|
||||
*/
|
||||
object ToolbarPopupWindow {
|
||||
fun show(
|
||||
view: WeakReference<View>,
|
||||
@ -35,12 +39,13 @@ object ToolbarPopupWindow {
|
||||
copyVisible: Boolean = true,
|
||||
) {
|
||||
val context = view.get()?.context ?: return
|
||||
val clipboard = context.components.clipboardHandler
|
||||
val clipboardUrl = clipboard.getUrl()
|
||||
val clipboardText = clipboard.text
|
||||
if (!copyVisible && clipboardUrl == null) return
|
||||
|
||||
val isCustomTabSession = customTabId != null
|
||||
val clipboard = context.components.clipboardHandler
|
||||
|
||||
val containsText = clipboard.containsText()
|
||||
val containsUrl = clipboard.containsURL()
|
||||
val pasteDeactivated = isCustomTabSession || (!containsText && !containsUrl)
|
||||
if (!copyVisible && pasteDeactivated) return
|
||||
|
||||
val binding = BrowserToolbarPopupWindowBinding.inflate(LayoutInflater.from(context))
|
||||
val popupWindow = PopupWindow(
|
||||
@ -57,9 +62,8 @@ object ToolbarPopupWindow {
|
||||
popupWindow.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
|
||||
binding.copy.isVisible = copyVisible
|
||||
|
||||
binding.paste.isVisible = clipboardText != null && !isCustomTabSession
|
||||
binding.pasteAndGo.isVisible = clipboardUrl != null && !isCustomTabSession
|
||||
binding.paste.isVisible = containsText && !isCustomTabSession
|
||||
binding.pasteAndGo.isVisible = containsUrl && !isCustomTabSession
|
||||
|
||||
if (copyVisible) {
|
||||
binding.copy.setOnClickListener { copyView ->
|
||||
@ -82,17 +86,21 @@ object ToolbarPopupWindow {
|
||||
}
|
||||
}
|
||||
|
||||
clipboardText?.let { text ->
|
||||
if (binding.paste.isVisible) {
|
||||
binding.paste.setOnClickListener {
|
||||
popupWindow.dismiss()
|
||||
handlePaste(text)
|
||||
handlePaste(clipboard.text.orEmpty())
|
||||
}
|
||||
}
|
||||
|
||||
clipboardUrl?.let { url ->
|
||||
if (binding.pasteAndGo.isVisible) {
|
||||
binding.pasteAndGo.setOnClickListener {
|
||||
popupWindow.dismiss()
|
||||
handlePasteAndGo(url)
|
||||
clipboard.extractURL()?.also {
|
||||
handlePasteAndGo(it)
|
||||
} ?: run {
|
||||
Logger("ToolbarPopupWindow").error("Clipboard contains URL but unable to read text")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,12 +127,4 @@ object ToolbarPopupWindow {
|
||||
selectedTab?.readerState?.activeUrl ?: selectedTab?.content?.url
|
||||
}
|
||||
}
|
||||
|
||||
private fun ClipboardHandler.getUrl(): String? {
|
||||
if (containsURL()) {
|
||||
text?.let { return it }
|
||||
Logger("ToolbarPopupWindow").error("Clipboard contains URL but unable to read text")
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user