diff options
author | horo@chromium.org <horo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-26 23:13:50 +0000 |
---|---|---|
committer | horo@chromium.org <horo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-26 23:13:50 +0000 |
commit | dafa65d5207ea667a7fdbe5525230fe887298261 (patch) | |
tree | 22ba5e06a1f81a6a35945883f67edf2896391c5b | |
parent | 2e6504478c3cd823dc626729110f27a53ee864b8 (diff) | |
download | chromium_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.cc | 30 | ||||
-rw-r--r-- | content/browser/shared_worker/shared_worker_host.h | 38 | ||||
-rw-r--r-- | content/browser/shared_worker/shared_worker_instance.cc | 101 | ||||
-rw-r--r-- | content/browser/shared_worker/shared_worker_instance.h | 109 | ||||
-rw-r--r-- | content/browser/shared_worker/shared_worker_instance_unittest.cc | 76 | ||||
-rw-r--r-- | content/browser/shared_worker/shared_worker_service_impl.cc | 68 | ||||
-rw-r--r-- | content/browser/shared_worker/shared_worker_service_impl.h | 10 | ||||
-rw-r--r-- | content/browser/worker_host/worker_storage_partition.h | 3 | ||||
-rw-r--r-- | content/content_browser.gypi | 4 | ||||
-rw-r--r-- | content/content_tests.gypi | 1 |
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', |