Commit b01d2a75 authored by Agi Sferro's avatar Agi Sferro
Browse files

Bug 1750623 - Always set isTopLevel=true for ENV_EXTENSION senders. r=robwu,jonalmeida

isTopLevel is used for ENV_TYPE_CONTENT_SCRIPT to let embedders know if an
iframe is sending messages to the app. For extension environments we don't need
this extra check so we can always set the value to true.

Differential Revision: https://phabricator.services.mozilla.com/D137776
parent 0541c7f3
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
<html>
  <head>
    <meta charset="utf-8">
    <script src="test-popup-messaging.js"></script>
  </head>
  <body>
    <h1> HELLO </h1>
  </body>
</html>
+24 −0
Original line number Diff line number Diff line
browser.runtime.sendNativeMessage("badNativeApi", "errorerrorerror");

async function runTest() {
  const response = await browser.runtime.sendNativeMessage(
    "browser",
    "testPopupMessage"
  );

  browser.runtime.sendNativeMessage("browser", `response: ${response}`);

  const port = browser.runtime.connectNative("browser");
  port.onMessage.addListener(response => {
    if (response.action === "disconnect") {
      port.disconnect();
      return;
    }

    port.postMessage(`response: ${response.message}`);
  });

  port.postMessage("testPopupPortMessage");
}

runTest();
+85 −0
Original line number Diff line number Diff line
@@ -605,6 +605,91 @@ class ExtensionActionTest : BaseSessionTest() {
        sessionRule.waitForResult(onClicked)
    }

    @Test
    fun testPopupMessaging() {
        val popupSession = sessionRule.createOpenSession()

        val actionResult = GeckoResult<WebExtension.Action>()
        testActionApi("""{
           "action": "setPopup",
           "popup": "test-popup-messaging.html"
        }""") { action ->
            assertEquals(action.title, "Test action default")
            assertEquals(action.enabled, true)
            actionResult.complete(action)
        }

        val messages = mutableListOf<String>()
        val messageResult = GeckoResult<List<String>>()
        val portResult = GeckoResult<WebExtension.Port>()
        val messageDelegate = object : WebExtension.MessageDelegate {
            override fun onMessage(
                nativeApp: String,
                message: Any,
                sender: WebExtension.MessageSender
            ): GeckoResult<Any>? {
                assertEquals(extension!!.id, sender.webExtension.id)
                assertEquals(WebExtension.MessageSender.ENV_TYPE_EXTENSION,
                    sender.environmentType)
                assertEquals(sender.isTopLevel, true)
                assertEquals("${extension!!.metaData.baseUrl}test-popup-messaging.html",
                    sender.url)
                assertEquals(sender.session, popupSession)
                messages.add(message as String)
                if (messages.size == 2) {
                    messageResult.complete(messages)
                    return null
                } else {
                    return GeckoResult.fromValue("TEST_RESPONSE")
                }
            }

            override fun onConnect(port: WebExtension.Port) {
                assertEquals(extension!!.id, port.sender.webExtension.id)
                assertEquals(WebExtension.MessageSender.ENV_TYPE_EXTENSION,
                    port.sender.environmentType)
                assertEquals(true, port.sender.isTopLevel)
                assertEquals("${extension!!.metaData.baseUrl}test-popup-messaging.html",
                    port.sender.url)
                assertEquals(port.sender.session, popupSession)
                portResult.complete(port)
            }
        }

        popupSession.webExtensionController.setMessageDelegate(
            extension!!, messageDelegate, "browser")

        val action = sessionRule.waitForResult(actionResult)
        extension!!.setActionDelegate(object : WebExtension.ActionDelegate {
            override fun onTogglePopup(extension: WebExtension,
                                       popupAction: WebExtension.Action): GeckoResult<GeckoSession>? {
                assertEquals(extension, this@ExtensionActionTest.extension)
                assertEquals(popupAction, action)
                return GeckoResult.fromValue(popupSession)
            }
        })

        action.click()

        val message = sessionRule.waitForResult(messageResult)
        assertThat("Message should match", message, equalTo(listOf(
            "testPopupMessage", "response: TEST_RESPONSE")))

        val port = sessionRule.waitForResult(portResult)
        val portMessageResult = GeckoResult<String>()

        port.setDelegate(object : WebExtension.PortDelegate {
            override fun onPortMessage(message: Any, p: WebExtension.Port) {
                assertEquals(port, p)
                portMessageResult.complete(message as String)
            }
        })

        val portMessage = sessionRule.waitForResult(portMessageResult)
        assertThat("Message should match", portMessage,
            equalTo("testPopupPortMessage"))
    }

    @Test
    fun testPopupsCanCloseThemselves() {
        val onCloseRequestResult = GeckoResult<Void>()
+2 −2
Original line number Diff line number Diff line
@@ -1093,8 +1093,8 @@ public class WebExtensionController {

    final String url = sender.getString("url");
    final boolean isTopLevel;
    if (session == null) {
      // This message is coming from the background page
    if (session == null || environmentType == WebExtension.MessageSender.ENV_TYPE_EXTENSION) {
      // This message is coming from the background page, a popup, or an extension page
      isTopLevel = true;
    } else {
      // If session is present we are either receiving this message from a content script or