summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhoro@chromium.org <horo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-26 23:13:50 +0000
committerhoro@chromium.org <horo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-26 23:13:50 +0000
commitdafa65d5207ea667a7fdbe5525230fe887298261 (patch)
tree22ba5e06a1f81a6a35945883f67edf2896391c5b
parent2e6504478c3cd823dc626729110f27a53ee864b8 (diff)
downloadchromium_src-dafa65d5207ea667a7fdbe5525230fe887298261.zip
chromium_src-dafa65d5207ea667a7fdbe5525230fe887298261.tar.gz
chromium_src-dafa65d5207ea667a7fdbe5525230fe887298261.tar.bz2
Implement SharedWorkerServiceImpl::CreateWorker and SharedWorkerInstance and SharedWorkerHost.
SharedWorkerInstance is almost same as WorkerProcessHost::WorkerInstance in content/browser/worker_host/worker_process_host.h. In the next CL, I will implement SharedWorkerHost::Init() which sends CreateWorker message to the renderer. BUG=327256 Review URL: https://codereview.chromium.org/177043003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@253620 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/browser/shared_worker/shared_worker_host.cc30
-rw-r--r--content/browser/shared_worker/shared_worker_host.h38
-rw-r--r--content/browser/shared_worker/shared_worker_instance.cc101
-rw-r--r--content/browser/shared_worker/shared_worker_instance.h109
-rw-r--r--content/browser/shared_worker/shared_worker_instance_unittest.cc76
-rw-r--r--content/browser/shared_worker/shared_worker_service_impl.cc68
-rw-r--r--content/browser/shared_worker/shared_worker_service_impl.h10
-rw-r--r--content/browser/worker_host/worker_storage_partition.h3
-rw-r--r--content/content_browser.gypi4
-rw-r--r--content/content_tests.gypi1
10 files changed, 437 insertions, 3 deletions
diff --git a/content/browser/shared_worker/shared_worker_host.cc b/content/browser/shared_worker/shared_worker_host.cc
new file mode 100644
index 0000000..79944ec
--- /dev/null
+++ b/content/browser/shared_worker/shared_worker_host.cc
@@ -0,0 +1,30 @@
+// Copyright 2014 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.
+
+#include "content/browser/shared_worker/shared_worker_host.h"
+
+#include "content/browser/shared_worker/shared_worker_instance.h"
+#include "content/browser/shared_worker/shared_worker_message_filter.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace content {
+
+SharedWorkerHost::SharedWorkerHost(SharedWorkerInstance* instance)
+ : instance_(instance),
+ worker_route_id_(MSG_ROUTING_NONE) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+}
+
+SharedWorkerHost::~SharedWorkerHost() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+}
+
+void SharedWorkerHost::Init(SharedWorkerMessageFilter* filter) {
+ DCHECK(worker_route_id_ == MSG_ROUTING_NONE);
+ worker_route_id_ = filter->GetNextRoutingID();
+ // TODO(horo): implement this.
+ NOTIMPLEMENTED();
+}
+
+} // namespace content
diff --git a/content/browser/shared_worker/shared_worker_host.h b/content/browser/shared_worker/shared_worker_host.h
new file mode 100644
index 0000000..b12487c
--- /dev/null
+++ b/content/browser/shared_worker/shared_worker_host.h
@@ -0,0 +1,38 @@
+// Copyright 2014 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.
+
+#ifndef CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_HOST_H_
+#define CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_HOST_H_
+
+#include <vector>
+
+#include "base/memory/scoped_ptr.h"
+
+namespace content {
+class SharedWorkerMessageFilter;
+class SharedWorkerInstance;
+
+// The SharedWorkerHost is the interface that represents the browser side of
+// the browser <-> worker communication channel.
+class SharedWorkerHost {
+ public:
+ explicit SharedWorkerHost(SharedWorkerInstance* instance);
+ ~SharedWorkerHost();
+
+ // Starts the SharedWorker in the renderer process which is associated with
+ // |filter|.
+ void Init(SharedWorkerMessageFilter* filter);
+
+ SharedWorkerInstance* instance() { return instance_.get(); }
+ int worker_route_id() const { return worker_route_id_; }
+
+ private:
+ scoped_ptr<SharedWorkerInstance> instance_;
+ int worker_route_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(SharedWorkerHost);
+};
+} // namespace content
+
+#endif // CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_HOST_H_
diff --git a/content/browser/shared_worker/shared_worker_instance.cc b/content/browser/shared_worker/shared_worker_instance.cc
new file mode 100644
index 0000000..a55dd91
--- /dev/null
+++ b/content/browser/shared_worker/shared_worker_instance.cc
@@ -0,0 +1,101 @@
+// Copyright 2014 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.
+
+#include "content/browser/shared_worker/shared_worker_instance.h"
+
+#include "base/logging.h"
+#include "content/browser/worker_host/worker_document_set.h"
+
+namespace content {
+
+SharedWorkerInstance::SharedWorkerInstance(
+ const GURL& url,
+ const base::string16& name,
+ const base::string16& content_security_policy,
+ blink::WebContentSecurityPolicyType security_policy_type,
+ ResourceContext* resource_context,
+ const WorkerStoragePartition& partition)
+ : url_(url),
+ closed_(false),
+ name_(name),
+ content_security_policy_(content_security_policy),
+ security_policy_type_(security_policy_type),
+ worker_document_set_(new WorkerDocumentSet()),
+ resource_context_(resource_context),
+ partition_(partition),
+ load_failed_(false) {
+ DCHECK(resource_context_);
+}
+
+SharedWorkerInstance::~SharedWorkerInstance() {
+}
+
+void SharedWorkerInstance::SetMessagePortID(
+ SharedWorkerMessageFilter* filter,
+ int route_id,
+ int message_port_id) {
+ for (FilterList::iterator i = filters_.begin(); i != filters_.end(); ++i) {
+ if (i->filter() == filter && i->route_id() == route_id) {
+ i->set_message_port_id(message_port_id);
+ return;
+ }
+ }
+}
+
+bool SharedWorkerInstance::Matches(const GURL& match_url,
+ const base::string16& match_name,
+ const WorkerStoragePartition& partition,
+ ResourceContext* resource_context) const {
+ // Only match open shared workers.
+ if (closed_)
+ return false;
+
+ // ResourceContext equivalence is being used as a proxy to ensure we only
+ // matched shared workers within the same BrowserContext.
+ if (resource_context_ != resource_context)
+ return false;
+
+ // We must be in the same storage partition otherwise sharing will violate
+ // isolation.
+ if (!partition_.Equals(partition))
+ return false;
+
+ if (url_.GetOrigin() != match_url.GetOrigin())
+ return false;
+
+ if (name_.empty() && match_name.empty())
+ return url_ == match_url;
+
+ return name_ == match_name;
+}
+
+void SharedWorkerInstance::AddFilter(SharedWorkerMessageFilter* filter,
+ int route_id) {
+ CHECK(filter);
+ if (!HasFilter(filter, route_id)) {
+ FilterInfo info(filter, route_id);
+ filters_.push_back(info);
+ }
+}
+
+void SharedWorkerInstance::RemoveFilters(SharedWorkerMessageFilter* filter) {
+ for (FilterList::iterator i = filters_.begin(); i != filters_.end();) {
+ if (i->filter() == filter)
+ i = filters_.erase(i);
+ else
+ ++i;
+ }
+}
+
+bool SharedWorkerInstance::HasFilter(SharedWorkerMessageFilter* filter,
+ int route_id) const {
+ for (FilterList::const_iterator i = filters_.begin(); i != filters_.end();
+ ++i) {
+ if (i->filter() == filter && i->route_id() == route_id)
+ return true;
+ }
+ return false;
+}
+
+} // namespace content
diff --git a/content/browser/shared_worker/shared_worker_instance.h b/content/browser/shared_worker/shared_worker_instance.h
new file mode 100644
index 0000000..e714e43
--- /dev/null
+++ b/content/browser/shared_worker/shared_worker_instance.h
@@ -0,0 +1,109 @@
+// Copyright 2014 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.
+
+#ifndef CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_INSTANCE_H_
+#define CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_INSTANCE_H_
+
+#include <list>
+#include <string>
+
+#include "base/basictypes.h"
+#include "content/browser/worker_host/worker_document_set.h"
+#include "content/browser/worker_host/worker_storage_partition.h"
+#include "content/common/content_export.h"
+#include "third_party/WebKit/public/web/WebContentSecurityPolicy.h"
+#include "url/gurl.h"
+
+namespace content {
+class ResourceContext;
+class SharedWorkerMessageFilter;
+
+class CONTENT_EXPORT SharedWorkerInstance {
+ public:
+ // Unique identifier for a worker client.
+ class FilterInfo {
+ public:
+ FilterInfo(SharedWorkerMessageFilter* filter, int route_id)
+ : filter_(filter), route_id_(route_id), message_port_id_(0) { }
+ SharedWorkerMessageFilter* filter() const { return filter_; }
+ int route_id() const { return route_id_; }
+ int message_port_id() const { return message_port_id_; }
+ void set_message_port_id(int id) { message_port_id_ = id; }
+
+ private:
+ SharedWorkerMessageFilter* filter_;
+ int route_id_;
+ int message_port_id_;
+ };
+
+ typedef std::list<FilterInfo> FilterList;
+
+ SharedWorkerInstance(const GURL& url,
+ const base::string16& name,
+ const base::string16& content_security_policy,
+ blink::WebContentSecurityPolicyType security_policy_type,
+ ResourceContext* resource_context,
+ const WorkerStoragePartition& partition);
+ ~SharedWorkerInstance();
+
+ void AddFilter(SharedWorkerMessageFilter* filter, int route_id);
+ void RemoveFilters(SharedWorkerMessageFilter* filter);
+ bool HasFilter(SharedWorkerMessageFilter* filter, int route_id) const;
+ void SetMessagePortID(SharedWorkerMessageFilter* filter,
+ int route_id,
+ int message_port_id);
+ const FilterList& filters() const { return filters_; }
+
+ // Checks if this SharedWorkerInstance matches the passed url/name params
+ // based on the algorithm in the WebWorkers spec - an instance matches if the
+ // origins of the URLs match, and:
+ // a) the names are non-empty and equal.
+ // -or-
+ // b) the names are both empty, and the urls are equal.
+ bool Matches(
+ const GURL& url,
+ const base::string16& name,
+ const WorkerStoragePartition& partition,
+ ResourceContext* resource_context) const;
+
+ // Accessors.
+ bool closed() const { return closed_; }
+ void set_closed(bool closed) { closed_ = closed; }
+ const GURL& url() const { return url_; }
+ const base::string16 name() const { return name_; }
+ const base::string16 content_security_policy() const {
+ return content_security_policy_;
+ }
+ blink::WebContentSecurityPolicyType security_policy_type() const {
+ return security_policy_type_;
+ }
+ WorkerDocumentSet* worker_document_set() const {
+ return worker_document_set_.get();
+ }
+ ResourceContext* resource_context() const {
+ return resource_context_;
+ }
+ const WorkerStoragePartition& partition() const {
+ return partition_;
+ }
+ void set_load_failed(bool failed) { load_failed_ = failed; }
+ bool load_failed() { return load_failed_; }
+
+ private:
+ GURL url_;
+ bool closed_;
+ base::string16 name_;
+ base::string16 content_security_policy_;
+ blink::WebContentSecurityPolicyType security_policy_type_;
+ FilterList filters_;
+ scoped_refptr<WorkerDocumentSet> worker_document_set_;
+ ResourceContext* const resource_context_;
+ WorkerStoragePartition partition_;
+ bool load_failed_;
+};
+
+} // namespace content
+
+
+#endif // CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_INSTANCE_H_
diff --git a/content/browser/shared_worker/shared_worker_instance_unittest.cc b/content/browser/shared_worker/shared_worker_instance_unittest.cc
new file mode 100644
index 0000000..52edb1b
--- /dev/null
+++ b/content/browser/shared_worker/shared_worker_instance_unittest.cc
@@ -0,0 +1,76 @@
+// Copyright 2014 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.
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string16.h"
+#include "base/strings/utf_string_conversions.h"
+#include "content/browser/shared_worker/shared_worker_instance.h"
+#include "content/browser/worker_host/worker_storage_partition.h"
+#include "content/public/test/test_browser_context.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+class SharedWorkerInstanceTest : public testing::Test {
+ protected:
+ SharedWorkerInstanceTest()
+ : browser_context_(new TestBrowserContext()),
+ partition_(new WorkerStoragePartition(
+ browser_context_->GetRequestContext(),
+ NULL, NULL, NULL, NULL, NULL, NULL)) {
+ }
+
+ bool Matches(const SharedWorkerInstance& instance,
+ const std::string& url,
+ const base::StringPiece& name) {
+ return instance.Matches(GURL(url),
+ base::ASCIIToUTF16(name),
+ *partition_.get(),
+ browser_context_->GetResourceContext());
+ }
+
+ scoped_ptr<TestBrowserContext> browser_context_;
+ scoped_ptr<WorkerStoragePartition> partition_;
+
+ DISALLOW_COPY_AND_ASSIGN(SharedWorkerInstanceTest);
+};
+
+TEST_F(SharedWorkerInstanceTest, MatchesTest) {
+ SharedWorkerInstance instance1(GURL("http://example.com/w.js"),
+ base::string16(),
+ base::string16(),
+ blink::WebContentSecurityPolicyTypeReport,
+ browser_context_->GetResourceContext(),
+ *partition_.get());
+ EXPECT_TRUE(Matches(instance1, "http://example.com/w.js", ""));
+ EXPECT_FALSE(Matches(instance1, "http://example.com/w2.js", ""));
+ EXPECT_FALSE(Matches(instance1, "http://example.net/w.js", ""));
+ EXPECT_FALSE(Matches(instance1, "http://example.net/w2.js", ""));
+ EXPECT_FALSE(Matches(instance1, "http://example.com/w.js", "name"));
+ EXPECT_FALSE(Matches(instance1, "http://example.com/w2.js", "name"));
+ EXPECT_FALSE(Matches(instance1, "http://example.net/w.js", "name"));
+ EXPECT_FALSE(Matches(instance1, "http://example.net/w2.js", "name"));
+
+ SharedWorkerInstance instance2(GURL("http://example.com/w.js"),
+ base::ASCIIToUTF16("name"),
+ base::string16(),
+ blink::WebContentSecurityPolicyTypeReport,
+ browser_context_->GetResourceContext(),
+ *partition_.get());
+ EXPECT_FALSE(Matches(instance2, "http://example.com/w.js", ""));
+ EXPECT_FALSE(Matches(instance2, "http://example.com/w2.js", ""));
+ EXPECT_FALSE(Matches(instance2, "http://example.net/w.js", ""));
+ EXPECT_FALSE(Matches(instance2, "http://example.net/w2.js", ""));
+ EXPECT_TRUE(Matches(instance2, "http://example.com/w.js", "name"));
+ EXPECT_TRUE(Matches(instance2, "http://example.com/w2.js", "name"));
+ EXPECT_FALSE(Matches(instance2, "http://example.net/w.js", "name"));
+ EXPECT_FALSE(Matches(instance2, "http://example.net/w2.js", "name"));
+ EXPECT_FALSE(Matches(instance2, "http://example.com/w.js", "name2"));
+ EXPECT_FALSE(Matches(instance2, "http://example.com/w2.js", "name2"));
+ EXPECT_FALSE(Matches(instance2, "http://example.net/w.js", "name2"));
+ EXPECT_FALSE(Matches(instance2, "http://example.net/w2.js", "name2"));
+}
+
+} // namespace content
diff --git a/content/browser/shared_worker/shared_worker_service_impl.cc b/content/browser/shared_worker/shared_worker_service_impl.cc
index d1e245a..12c3ebb 100644
--- a/content/browser/shared_worker/shared_worker_service_impl.cc
+++ b/content/browser/shared_worker/shared_worker_service_impl.cc
@@ -4,7 +4,11 @@
#include "content/browser/shared_worker/shared_worker_service_impl.h"
+#include "content/browser/shared_worker/shared_worker_host.h"
+#include "content/browser/shared_worker/shared_worker_instance.h"
#include "content/browser/shared_worker/shared_worker_message_filter.h"
+#include "content/browser/worker_host/worker_document_set.h"
+#include "content/common/view_messages.h"
#include "content/common/worker_messages.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/worker_service_observer.h"
@@ -50,8 +54,51 @@ void SharedWorkerServiceImpl::CreateWorker(
ResourceContext* resource_context,
const WorkerStoragePartition& partition,
bool* url_mismatch) {
- // TODO(horo): implement this.
- NOTIMPLEMENTED();
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ *url_mismatch = false;
+ SharedWorkerInstance* existing_instance =
+ FindSharedWorkerInstance(
+ params.url, params.name, partition, resource_context);
+ if (existing_instance) {
+ if (params.url != existing_instance->url()) {
+ *url_mismatch = true;
+ return;
+ }
+ if (existing_instance->load_failed()) {
+ filter->Send(new ViewMsg_WorkerScriptLoadFailed(route_id));
+ return;
+ }
+ existing_instance->AddFilter(filter, route_id);
+ existing_instance->worker_document_set()->Add(
+ filter, params.document_id, filter->render_process_id(),
+ params.render_frame_route_id);
+ filter->Send(new ViewMsg_WorkerCreated(route_id));
+ return;
+ }
+
+ scoped_ptr<SharedWorkerInstance> instance(new SharedWorkerInstance(
+ params.url,
+ params.name,
+ params.content_security_policy,
+ params.security_policy_type,
+ resource_context,
+ partition));
+ instance->AddFilter(filter, route_id);
+ instance->worker_document_set()->Add(
+ filter, params.document_id, filter->render_process_id(),
+ params.render_frame_route_id);
+
+ scoped_ptr<SharedWorkerHost> worker(new SharedWorkerHost(instance.release()));
+ worker->Init(filter);
+ const int worker_route_id = worker->worker_route_id();
+ worker_hosts_.push_back(worker.release());
+
+ FOR_EACH_OBSERVER(
+ WorkerServiceObserver, observers_,
+ WorkerCreated(params.url,
+ params.name,
+ filter->render_process_id(),
+ worker_route_id));
}
void SharedWorkerServiceImpl::ForwardToWorker(
@@ -141,4 +188,21 @@ void SharedWorkerServiceImpl::OnSharedWorkerMessageFilterClosing(
NOTIMPLEMENTED();
}
+SharedWorkerInstance* SharedWorkerServiceImpl::FindSharedWorkerInstance(
+ const GURL& url,
+ const base::string16& name,
+ const WorkerStoragePartition& partition,
+ ResourceContext* resource_context) {
+ for (ScopedVector<SharedWorkerHost>::const_iterator iter =
+ worker_hosts_.begin();
+ iter != worker_hosts_.end();
+ ++iter) {
+ SharedWorkerInstance* instance = (*iter)->instance();
+ if (instance &&
+ instance->Matches(url, name, partition, resource_context))
+ return instance;
+ }
+ return NULL;
+}
+
} // namespace content
diff --git a/content/browser/shared_worker/shared_worker_service_impl.h b/content/browser/shared_worker/shared_worker_service_impl.h
index 4d5d8a0..9b4350e 100644
--- a/content/browser/shared_worker/shared_worker_service_impl.h
+++ b/content/browser/shared_worker/shared_worker_service_impl.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_SERVICE_IMPL_H_
#include "base/compiler_specific.h"
+#include "base/memory/scoped_vector.h"
#include "base/memory/singleton.h"
#include "base/observer_list.h"
#include "content/public/browser/notification_observer.h"
@@ -20,6 +21,8 @@ class Message;
namespace content {
+class SharedWorkerInstance;
+class SharedWorkerHost;
class SharedWorkerMessageFilter;
class ResourceContext;
class WorkerServiceObserver;
@@ -88,6 +91,13 @@ class CONTENT_EXPORT SharedWorkerServiceImpl
SharedWorkerServiceImpl();
virtual ~SharedWorkerServiceImpl();
+ SharedWorkerInstance* FindSharedWorkerInstance(
+ const GURL& url,
+ const base::string16& name,
+ const WorkerStoragePartition& worker_partition,
+ ResourceContext* resource_context);
+
+ ScopedVector<SharedWorkerHost> worker_hosts_;
ObserverList<WorkerServiceObserver> observers_;
DISALLOW_COPY_AND_ASSIGN(SharedWorkerServiceImpl);
diff --git a/content/browser/worker_host/worker_storage_partition.h b/content/browser/worker_host/worker_storage_partition.h
index 49c2deae..3fd0df1 100644
--- a/content/browser/worker_host/worker_storage_partition.h
+++ b/content/browser/worker_host/worker_storage_partition.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_WORKER_HOST_WORKER_STORAGE_PARTITION_H_
#include "base/memory/ref_counted.h"
+#include "content/common/content_export.h"
namespace quota {
class QuotaManager;
@@ -39,7 +40,7 @@ class IndexedDBContextImpl;
// This class is effectively a struct, but we make it a class because we want to
// define copy constructors, assignment operators, and an Equals() function for
// it which makes it look awkward as a struct.
-class WorkerStoragePartition {
+class CONTENT_EXPORT WorkerStoragePartition {
public:
WorkerStoragePartition(
net::URLRequestContextGetter* url_request_context,
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index f058fc5..6fd52c0 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -1133,6 +1133,10 @@
'browser/service_worker/service_worker_storage.h',
'browser/service_worker/service_worker_version.cc',
'browser/service_worker/service_worker_version.h',
+ 'browser/shared_worker/shared_worker_host.cc',
+ 'browser/shared_worker/shared_worker_host.h',
+ 'browser/shared_worker/shared_worker_instance.cc',
+ 'browser/shared_worker/shared_worker_instance.h',
'browser/shared_worker/shared_worker_message_filter.cc',
'browser/shared_worker/shared_worker_message_filter.h',
'browser/shared_worker/shared_worker_service_impl.cc',
diff --git a/content/content_tests.gypi b/content/content_tests.gypi
index cbc4686..2666e12 100644
--- a/content/content_tests.gypi
+++ b/content/content_tests.gypi
@@ -484,6 +484,7 @@
'browser/service_worker/service_worker_registration_unittest.cc',
'browser/service_worker/service_worker_storage_unittest.cc',
'browser/service_worker/service_worker_version_unittest.cc',
+ 'browser/shared_worker/shared_worker_instance_unittest.cc',
'browser/site_instance_impl_unittest.cc',
'browser/speech/chunked_byte_buffer_unittest.cc',
'browser/speech/endpointer/endpointer_unittest.cc',