Skip to content

Commit

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

Wait for permissions to propagate to all context pages.

Fixes microsoft#720
  • Loading branch information
aslushnikov committed Mar 5, 2020
1 parent cd8714d commit c53fcf4
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 12 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
65 changes: 54 additions & 11 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 @@ -2481,10 +2488,10 @@ index 0000000000000000000000000000000000000000..be70ea364f9534bb3b344f64970366c3
+
diff --git a/testing/juggler/content/PageAgent.js b/testing/juggler/content/PageAgent.js
new file mode 100644
index 0000000000000000000000000000000000000000..27a99df370a12f3c98f68017106050f4ee4c5675
index 0000000000000000000000000000000000000000..d71aad541437eab626cdf2a45091120368cf5d67
--- /dev/null
+++ b/testing/juggler/content/PageAgent.js
@@ -0,0 +1,919 @@
@@ -0,0 +1,926 @@
+"use strict";
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const Ci = Components.interfaces;
Expand All @@ -2496,6 +2503,13 @@ index 0000000000000000000000000000000000000000..27a99df370a12f3c98f68017106050f4
+
+const helper = new Helper();
+
+const ALL_PERMISSIONS = [
+ 'geo',
+ 'microphone',
+ 'camera',
+ 'desktop-notifications',
+];
+
+class WorkerData {
+ constructor(pageAgent, browserChannel, sessionId, worker) {
+ this._workerRuntime = worker.channel().connect(sessionId + 'runtime');
Expand Down Expand Up @@ -4166,10 +4180,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..ba4c5de242f1e6a0ea22f151b0c93293a0fa13dc
--- /dev/null
+++ b/testing/juggler/content/main.js
@@ -0,0 +1,96 @@
@@ -0,0 +1,122 @@
+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 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 c53fcf4

Please sign in to comment.