Commit 771aa8a2 authored by Istiaque Ahmed's avatar Istiaque Ahmed Committed by Commit Bot

Extension SW: Exercise early extension event dispatch right after registration.

This CL adds a test that sends an extension event early in the
extension lifetime, specifically after EventRouter sees a listener
registration, shortly after Service Worker is being registered.
This demonstrates that event dispatch works correctly before SW
registration contains an active worker. The registration would contain
installing_worker() in scenario.

This is a regression test for change
0c08a348

Bug: 850792
Change-Id: Ifab379cf60a105c806280fc5c27972f919632eac
Reviewed-on: https://chromium-review.googlesource.com/1091705
Commit-Queue: Istiaque Ahmed <lazyboy@chromium.org>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#569087}
parent 41d9e2a5
......@@ -42,10 +42,12 @@
#include "content/public/test/background_sync_test_util.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/service_worker_test_helpers.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/process_manager.h"
#include "extensions/common/extension_features.h"
#include "extensions/common/value_builder.h"
#include "extensions/test/background_page_watcher.h"
#include "extensions/test/extension_test_message_listener.h"
#include "extensions/test/result_catcher.h"
......@@ -298,6 +300,83 @@ IN_PROC_BROWSER_TEST_P(ServiceWorkerBasedBackgroundTest, Basic) {
EXPECT_TRUE(newtab_listener.WaitUntilSatisfied());
}
// Class that dispatches "test.onMessage" event to |extension_id| right after a
// listener to the event is added from the extension's Service Worker.
class EarlyWorkerMessageSender : public EventRouter::Observer {
public:
EarlyWorkerMessageSender(content::BrowserContext* browser_context,
const ExtensionId& extension_id)
: browser_context_(browser_context),
event_router_(EventRouter::EventRouter::Get(browser_context_)),
extension_id_(extension_id),
listener_("PASS", false) {
DCHECK(browser_context_);
listener_.set_failure_message("FAIL");
event_router_->RegisterObserver(this, kTestOnMessageEventName);
}
~EarlyWorkerMessageSender() override {
event_router_->UnregisterObserver(this);
}
// EventRouter::Observer:
void OnListenerAdded(const EventListenerInfo& details) override {
if (did_dispatch_event_ || extension_id_ != details.extension_id)
return;
const bool is_lazy_listener = details.browser_context == nullptr;
if (is_lazy_listener) {
// Wait for the non-lazy listener as we want to exercise the code to
// dispatch the event right after the Service Worker registration is
// completing.
return;
}
DispatchEvent();
did_dispatch_event_ = true;
}
bool SendAndWait() { return listener_.WaitUntilSatisfied(); }
private:
static constexpr const char* const kTestOnMessageEventName = "test.onMessage";
void DispatchEvent() {
std::unique_ptr<base::ListValue> event_args =
ListBuilder()
.Append(DictionaryBuilder()
.Set("data", "hello")
.Set("lastMessage", true)
.Build())
.Build();
auto event = std::make_unique<Event>(
events::TEST_ON_MESSAGE, std::string(kTestOnMessageEventName),
std::move(event_args), browser_context_);
EventRouter::Get(browser_context_)
->DispatchEventToExtension(extension_id_, std::move(event));
}
content::BrowserContext* const browser_context_ = nullptr;
EventRouter* const event_router_ = nullptr;
const ExtensionId extension_id_;
ExtensionTestMessageListener listener_;
bool did_dispatch_event_ = false;
DISALLOW_COPY_AND_ASSIGN(EarlyWorkerMessageSender);
};
// Tests that extension event dispatch works correctly right after extension
// installation registers its Service Worker.
// Regression test for: https://crbug.com/850792.
IN_PROC_BROWSER_TEST_P(ServiceWorkerBasedBackgroundTest, EarlyEventDispatch) {
const ExtensionId kId("pkplfbidichfdicaijlchgnapepdginl");
EarlyWorkerMessageSender sender(profile(), kId);
// pkplfbidichfdicaijlchgnapepdginl
const Extension* extension = LoadExtension(test_data_dir_.AppendASCII(
"service_worker/worker_based_background/early_event_dispatch"));
CHECK(extension);
EXPECT_EQ(kId, extension->id());
EXPECT_TRUE(sender.SendAndWait());
}
class ServiceWorkerBackgroundSyncTest : public ServiceWorkerTest {
public:
ServiceWorkerBackgroundSyncTest() {}
......
{
// chrome-extension://pkplfbidichfdicaijlchgnapepdginl
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtDfX9dHNh948bt00YhZBm3P6E5QLaOt+v8kXVtibQfiPtOD2FTScB/f0wX/EQWVO7BkaSOsRkTPcPIgocyMPYr2FLgqGLFlYT9nQpKJZUFNF5oJ5rG6Nv7ppf4zEB3j6da1IBRTz2yOZ+6O1TMZxol/V62/QcqrJeggsHTEPGLdr9Ua4b1Ka0xKJnJngZljsbw93FI1o+P9dAh5BS6wTPiZI/vmJVjvMTkSTnaZ3n9Go2t7A0XLcSxLcVyuLAd2mAvSN0mIviOukdM66wr7llif71nKuUt+4qvlr/r9HfwzN6pA4jkwhtS1UD+3CmB+wsHwsnohNcuu4FIQ6rgq/7QIDAQAB",
"name": "Worker based background script",
"version": "0.1",
"manifest_version": 2,
"description": "Test for dispatching extension event shortly after Service Worker registration occurs.",
"permissions": ["tabs"],
"background": {"service_worker_script": "service_worker_background.js"}
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var isInstanceOfServiceWorkerGlobalScope =
('ServiceWorkerGlobalScope' in self) &&
(self instanceof ServiceWorkerGlobalScope);
if (!isInstanceOfServiceWorkerGlobalScope) {
chrome.test.sendMessage('FAIL');
} else {
chrome.test.onMessage.addListener(args =>
chrome.test.sendMessage(args.data == 'hello' ? 'PASS': 'FAIL'));
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment