Skip to content

Commit

Permalink
browser(firefox): fix flaky permissions in Firefox (#1249)
Browse files Browse the repository at this point in the history
Review URL: aslushnikov/juggler@9bd6e72

Wait for permissions to propagate to all context pages.

References #720
  • Loading branch information
aslushnikov authored Mar 5, 2020
1 parent cd8714d commit b0d037e
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 10 deletions.
2 changes: 1 addition & 1 deletion browser_patches/firefox/BUILD_NUMBER
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1036
1037
61 changes: 52 additions & 9 deletions browser_patches/firefox/patches/bootstrap.diff
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ index 6dca2b78830edc1ddbd66264bd332853729dac71..fbe89c9682834e11b9d9219d9eb056ed

diff --git a/testing/juggler/BrowserContextManager.js b/testing/juggler/BrowserContextManager.js
new file mode 100644
index 0000000000000000000000000000000000000000..483667dbec8e4c76533e4cf5e69ca9e322f2e708
index 0000000000000000000000000000000000000000..dfb1f50b3a6ad915b99481c987975cb99c268ed7
--- /dev/null
+++ b/testing/juggler/BrowserContextManager.js
@@ -0,0 +1,194 @@
Expand Down Expand Up @@ -593,7 +593,7 @@ index 0000000000000000000000000000000000000000..483667dbec8e4c76533e4cf5e69ca9e3
+ this._principals.push(principal);
+ for (const permission of ALL_PERMISSIONS) {
+ const action = permissions.includes(permission) ? Ci.nsIPermissionManager.ALLOW_ACTION : Ci.nsIPermissionManager.DENY_ACTION;
+ Services.perms.addFromPrincipal(principal, permission, action);
+ Services.perms.addFromPrincipal(principal, permission, action, Ci.nsIPermissionManager.EXPIRE_NEVER, 0 /* expireTime */);
+ }
+ }
+
Expand Down Expand Up @@ -1628,10 +1628,10 @@ index 0000000000000000000000000000000000000000..ba34976ad05e7f5f1a99777f76ac08b1
+this.SimpleChannel = SimpleChannel;
diff --git a/testing/juggler/TargetRegistry.js b/testing/juggler/TargetRegistry.js
new file mode 100644
index 0000000000000000000000000000000000000000..2cb5f24b079289f00d84d0d7b266443635edd2b2
index 0000000000000000000000000000000000000000..1bcbafed549090fe533fb1340b2598e5962b855d
--- /dev/null
+++ b/testing/juggler/TargetRegistry.js
@@ -0,0 +1,257 @@
@@ -0,0 +1,264 @@
+const {EventEmitter} = ChromeUtils.import('resource://gre/modules/EventEmitter.jsm');
+const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
+const {SimpleChannel} = ChromeUtils.import('chrome://juggler/content/SimpleChannel.js');
Expand Down Expand Up @@ -1689,6 +1689,13 @@ index 0000000000000000000000000000000000000000..2cb5f24b079289f00d84d0d7b2664436
+ Services.obs.addObserver(this, 'oop-frameloader-crashed');
+ }
+
+ async ensurePermissionsInContextPages(browserContextId, permissions) {
+ const browserContext = this._contextManager.browserContextForId(browserContextId);
+ const pageTargets = [...this._targets.values()].filter(target => target instanceof PageTarget);
+ const contextPages = pageTargets.filter(target => target._browserContext === browserContext);
+ await Promise.all(contextPages.map(page => page._channel.connect('').send('ensurePermissions', permissions).catch(e => void e)));
+ }
+
+ async newPage({browserContextId}) {
+ const browserContext = this._contextManager.browserContextForId(browserContextId);
+ const tab = this._mainWindow.gBrowser.addTab('about:blank', {
Expand Down Expand Up @@ -4166,10 +4173,11 @@ index 0000000000000000000000000000000000000000..3a386425d3796d0a6786dea193b3402d
+
diff --git a/testing/juggler/content/main.js b/testing/juggler/content/main.js
new file mode 100644
index 0000000000000000000000000000000000000000..887180f71ef78604d2756ffa6a026ac968bda276
index 0000000000000000000000000000000000000000..212f1c1a218efebe8685b019e79fb553db720453
--- /dev/null
+++ b/testing/juggler/content/main.js
@@ -0,0 +1,96 @@
@@ -0,0 +1,129 @@
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
+const {FrameTree} = ChromeUtils.import('chrome://juggler/content/content/FrameTree.js');
+const {NetworkMonitor} = ChromeUtils.import('chrome://juggler/content/content/NetworkMonitor.js');
Expand All @@ -4178,6 +4186,13 @@ index 0000000000000000000000000000000000000000..887180f71ef78604d2756ffa6a026ac9
+const {RuntimeAgent} = ChromeUtils.import('chrome://juggler/content/content/RuntimeAgent.js');
+const {PageAgent} = ChromeUtils.import('chrome://juggler/content/content/PageAgent.js');
+
+const ALL_PERMISSIONS = [
+ 'geo',
+ 'microphone',
+ 'camera',
+ 'desktop-notifications',
+];
+
+const scrollbarManager = new ScrollbarManager(docShell);
+let frameTree;
+let networkMonitor;
Expand Down Expand Up @@ -4246,6 +4261,31 @@ index 0000000000000000000000000000000000000000..887180f71ef78604d2756ffa6a026ac9
+ frameTree.addScriptToEvaluateOnNewDocument(script);
+ },
+
+ async ensurePermissions(permissions) {
+ const checkPermissions = () => {
+ for (const permission of ALL_PERMISSIONS) {
+ const actual = Services.perms.testExactPermissionFromPrincipal(this._docShell.domWindow.document.nodePrincipal, permission);
+ const expected = permissions.include(permission) ? Ci.nsIPermissionManager.ALLOW_ACTION : Ci.nsIPermissionManager.DENY_ACTION;
+ if (actual !== expected)
+ return false;
+ }
+ return true;
+ }
+
+ if (checkPermissions())
+ return;
+
+ // Track all 'perm-changed' events and wait until permissions are expected.
+ await new Promise(resolve => {
+ const listeners = [helper.addObserver(() => {
+ if (!checkPermission())
+ return;
+ helper.removeListeners(listeners);
+ resolve();
+ }, 'perm-changed')];
+ });
+ },
+
+ dispose() {
+ },
+ });
Expand Down Expand Up @@ -4348,17 +4388,18 @@ index 0000000000000000000000000000000000000000..2f2b7ca247f6b6dff396fb4b644654de
+this.AccessibilityHandler = AccessibilityHandler;
diff --git a/testing/juggler/protocol/BrowserHandler.js b/testing/juggler/protocol/BrowserHandler.js
new file mode 100644
index 0000000000000000000000000000000000000000..061bcb4ff8a34610a5ec433393bf7901c4cafe86
index 0000000000000000000000000000000000000000..c34d0852b2e5b550d063f93e29429c651ec2501e
--- /dev/null
+++ b/testing/juggler/protocol/BrowserHandler.js
@@ -0,0 +1,81 @@
@@ -0,0 +1,84 @@
+"use strict";
+
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { allowAllCerts } = ChromeUtils.import(
+ "chrome://marionette/content/cert.js"
+);
+const {BrowserContextManager} = ChromeUtils.import("chrome://juggler/content/BrowserContextManager.js");
+const {TargetRegistry} = ChromeUtils.import("chrome://juggler/content/TargetRegistry.js");
+
+class BrowserHandler {
+ /**
Expand All @@ -4367,6 +4408,7 @@ index 0000000000000000000000000000000000000000..061bcb4ff8a34610a5ec433393bf7901
+ constructor() {
+ this._sweepingOverride = null;
+ this._contextManager = BrowserContextManager.instance();
+ this._targetRegistry = TargetRegistry.instance();
+ }
+
+ async close() {
Expand All @@ -4389,8 +4431,9 @@ index 0000000000000000000000000000000000000000..061bcb4ff8a34610a5ec433393bf7901
+ }
+ }
+
+ grantPermissions({browserContextId, origin, permissions}) {
+ async grantPermissions({browserContextId, origin, permissions}) {
+ this._contextManager.browserContextForId(browserContextId).grantPermissions(origin, permissions);
+ await this._targetRegistry.ensurePermissionsInContextPages(browserContextId, permissions);
+ }
+
+ resetPermissions({browserContextId}) {
Expand Down

0 comments on commit b0d037e

Please sign in to comment.