Skip to content

Commit c2a80fd

Browse files
committed
Bug 1869582 - Dismiss clipboard permission UI when user tap on the browser; r=geckoview-reviewers,calu
Differential Revision: https://phabricator.services.mozilla.com/D196893
1 parent 64d00dd commit c2a80fd

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/SelectionActionDelegateTest.kt

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,52 @@ class SelectionActionDelegateTest : BaseSessionTest() {
514514
sessionRule.waitForPageStop()
515515
}
516516
517+
@WithDisplay(width = 100, height = 100)
518+
@Test
519+
fun clipboardReadDismiss() {
520+
assumeThat("Unnecessary to run multiple times", id, equalTo("#text"))
521+
522+
sessionRule.setPrefsUntilTestEnd(mapOf("dom.events.asyncClipboard.readText" to true))
523+
524+
withClipboard("clipboardReadDismiss") {} // Reset clipboard data
525+
526+
val url = createTestUrl(CLIPBOARD_READ_HTML_PATH)
527+
mainSession.loadUri(url)
528+
mainSession.waitForPageStop()
529+
530+
val result = GeckoResult<Void>()
531+
val permissionResult = GeckoResult<AllowOrDeny>()
532+
mainSession.delegateDuringNextWait(object : SelectionActionDelegate {
533+
@AssertCalled(count = 1)
534+
override fun onShowClipboardPermissionRequest(
535+
session: GeckoSession,
536+
perm: ClipboardPermission,
537+
):
538+
GeckoResult<AllowOrDeny>? {
539+
assertThat(
540+
"Type should match",
541+
perm.type,
542+
equalTo(SelectionActionDelegate.PERMISSION_CLIPBOARD_READ),
543+
)
544+
result.complete(null)
545+
return permissionResult
546+
}
547+
})
548+
549+
mainSession.synthesizeTap(50, 50) // Provides user activation.
550+
sessionRule.waitForResult(result)
551+
552+
mainSession.delegateDuringNextWait(object : SelectionActionDelegate {
553+
@AssertCalled
554+
override fun onDismissClipboardPermissionRequest(session: GeckoSession) {
555+
permissionResult.complete(AllowOrDeny.DENY)
556+
}
557+
})
558+
559+
mainSession.synthesizeTap(10, 10) // click to dismiss.
560+
sessionRule.waitForResult(permissionResult)
561+
}
562+
517563
/** Interface that defines behavior for a particular type of content */
518564
private interface SelectedContent {
519565
fun focus() {}

mobile/android/modules/geckoview/GeckoViewClipboardPermission.sys.mjs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export var GeckoViewClipboardPermission = {
6060

6161
debug`confirmUserPaste (${screenRect.x}, ${screenRect.y})`;
6262

63+
document.addEventListener("pointerdown", this);
6364
document.ownerGlobal.WindowEventDispatcher.sendRequestForResult({
6465
type: "GeckoView:ClipboardPermissionRequest",
6566
screenPoint: {
@@ -71,13 +72,28 @@ export var GeckoViewClipboardPermission = {
7172
const propBag = lazy.PromptUtils.objectToPropBag({ ok: allowOrDeny });
7273
this._pendingRequest.resolve(propBag);
7374
this._pendingRequest = null;
75+
document.removeEventListener("pointerdown", this);
7476
},
7577
error => {
7678
debug`Permission error: ${error}`;
7779
this._pendingRequest.reject();
7880
this._pendingRequest = null;
81+
document.removeEventListener("pointerdown", this);
7982
}
8083
);
8184
});
8285
},
86+
87+
// EventListener interface.
88+
handleEvent(aEvent) {
89+
debug`handleEvent: ${aEvent.type}`;
90+
switch (aEvent.type) {
91+
case "pointerdown": {
92+
aEvent.target.ownerGlobal.WindowEventDispatcher.sendRequestForResult({
93+
type: "GeckoView:DismissClipboardPermissionRequest",
94+
});
95+
break;
96+
}
97+
}
98+
},
8399
};

0 commit comments

Comments
 (0)