From d71037bb51403c20fda6ec1901848314fa89afa2 Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Fri, 24 Oct 2014 15:05:42 -0700 Subject: [PATCH] HTMLImportLoader should talk directly to mojo::NetworkService This CL re-routes the loading pipeline for HTMLImportLoader directly to mojo::NetworkService rather than through core/fetch, platform/network, and WebURLLoader. R=eseidel@chromium.org, esprehn@chromium.org Review URL: https://codereview.chromium.org/678683004 --- engine/core/html/imports/HTMLImportLoader.cpp | 36 +++++++---------- engine/core/html/imports/HTMLImportLoader.h | 25 +++++++----- .../html/imports/HTMLImportsController.cpp | 6 +-- engine/platform/BUILD.gn | 10 +++++ engine/platform/DEPS | 3 +- engine/platform/fetcher/MojoFetcher.cpp | 38 ++++++++++++++++++ engine/platform/fetcher/MojoFetcher.h | 39 +++++++++++++++++++ engine/public/platform/Platform.h | 6 +++ engine/wtf/text/CString.h | 6 +++ engine/wtf/text/WTFString.cpp | 5 +++ engine/wtf/text/WTFString.h | 4 ++ viewer/platform/platform_impl.cc | 4 ++ viewer/platform/platform_impl.h | 1 + 13 files changed, 147 insertions(+), 36 deletions(-) create mode 100644 engine/platform/fetcher/MojoFetcher.cpp create mode 100644 engine/platform/fetcher/MojoFetcher.h diff --git a/engine/core/html/imports/HTMLImportLoader.cpp b/engine/core/html/imports/HTMLImportLoader.cpp index d0c326c3b91..e75ede44c12 100644 --- a/engine/core/html/imports/HTMLImportLoader.cpp +++ b/engine/core/html/imports/HTMLImportLoader.cpp @@ -70,47 +70,43 @@ void HTMLImportLoader::clear() m_document->cancelParsing(); m_document.clear(); } + m_fetcher.clear(); + m_drainer.clear(); } #endif -void HTMLImportLoader::startLoading(const ResourcePtr& resource) +void HTMLImportLoader::startLoading(const KURL& url) { - setResource(resource); + m_fetcher = adoptPtr(new MojoFetcher(this, url)); } -void HTMLImportLoader::responseReceived(Resource* resource, const ResourceResponse& response) +void HTMLImportLoader::OnReceivedResponse(mojo::URLResponsePtr response) { - // Resource may already have been loaded with the import loader - // being added as a client later & now being notified. Fail early. - if (resource->loadFailedOrCanceled() || response.httpStatusCode() >= 400) { + if (response->error || response->status_code >= 400) { setState(StateError); return; } - setState(startWritingAndParsing(response)); + mojo::ScopedDataPipeConsumerHandle body = response->body.Pass(); + setState(startWritingAndParsing(response.Pass())); + m_drainer = adoptPtr(new DataPipeDrainer(this, body.Pass())); } -void HTMLImportLoader::dataReceived(Resource*, const char* data, int length) +void HTMLImportLoader::OnDataAvailable(const void* data, size_t length) { RefPtrWillBeRawPtr protectingWriter(m_writer.get()); - m_writer->addData(data, length); + m_writer->addData(static_cast(data), length); } -void HTMLImportLoader::notifyFinished(Resource* resource) +void HTMLImportLoader::OnDataComplete() { - // The writer instance indicates that a part of the document can be already loaded. - // We don't take such a case as an error because the partially-loaded document has been visible from script at this point. - if (resource->loadFailedOrCanceled() && !m_writer) { - setState(StateError); - return; - } - setState(finishWriting()); } -HTMLImportLoader::State HTMLImportLoader::startWritingAndParsing(const ResourceResponse& response) +HTMLImportLoader::State HTMLImportLoader::startWritingAndParsing(mojo::URLResponsePtr response) { ASSERT(!m_imports.isEmpty()); - DocumentInit init = DocumentInit(response.url(), 0, m_controller->master()->contextDocument(), m_controller) + KURL url(ParsedURLString, String::fromUTF8(response->url)); + DocumentInit init = DocumentInit(url, 0, m_controller->master()->contextDocument(), m_controller) .withRegistrationContext(m_controller->master()->registrationContext()); m_document = HTMLDocument::create(init); m_writer = DocumentWriter::create(m_document.get()); @@ -167,8 +163,6 @@ void HTMLImportLoader::didFinishLoading() for (size_t i = 0; i < m_imports.size(); ++i) m_imports[i]->didFinishLoading(); - clearResource(); - ASSERT(!m_document || !m_document->parsing()); } diff --git a/engine/core/html/imports/HTMLImportLoader.h b/engine/core/html/imports/HTMLImportLoader.h index da743baae77..44dbec5f931 100644 --- a/engine/core/html/imports/HTMLImportLoader.h +++ b/engine/core/html/imports/HTMLImportLoader.h @@ -31,8 +31,8 @@ #ifndef HTMLImportLoader_h #define HTMLImportLoader_h -#include "core/fetch/RawResource.h" -#include "core/fetch/ResourceOwner.h" +#include "platform/fetcher/DataPipeDrainer.h" +#include "platform/fetcher/MojoFetcher.h" #include "platform/heap/Handle.h" #include "wtf/OwnPtr.h" #include "wtf/PassOwnPtr.h" @@ -53,7 +53,9 @@ class HTMLImportsController; // HTMLImportLoader is owned by HTMLImportsController. // // -class HTMLImportLoader FINAL : public NoBaseWillBeGarbageCollectedFinalized, public ResourceOwner { +class HTMLImportLoader FINAL : public NoBaseWillBeGarbageCollectedFinalized, + public MojoFetcher::Client, + public DataPipeDrainer::Client { public: enum State { StateLoading, @@ -86,7 +88,7 @@ public: #if !ENABLE(OILPAN) void importDestroyed(); #endif - void startLoading(const ResourcePtr&); + void startLoading(const KURL&); // Tells the loader that the parser is done with this import. // Called by Document::finishedParsing, after DOMContentLoaded was dispatched. @@ -103,12 +105,14 @@ public: private: HTMLImportLoader(HTMLImportsController*); - // RawResourceClient - virtual void responseReceived(Resource*, const ResourceResponse&) OVERRIDE; - virtual void dataReceived(Resource*, const char* data, int length) OVERRIDE; - virtual void notifyFinished(Resource*) OVERRIDE; + // MojoFetcher::Client + void OnReceivedResponse(mojo::URLResponsePtr) override; - State startWritingAndParsing(const ResourceResponse&); + // DataPipeDrainer::Client + void OnDataAvailable(const void* data, size_t num_bytes) override; + void OnDataComplete() override; + + State startWritingAndParsing(mojo::URLResponsePtr); State finishWriting(); State finishParsing(); State finishLoading(); @@ -125,6 +129,9 @@ private: RefPtrWillBeMember m_document; RefPtrWillBeMember m_writer; RefPtrWillBeMember m_microtaskQueue; + + OwnPtr m_fetcher; + OwnPtr m_drainer; }; } // namespace blink diff --git a/engine/core/html/imports/HTMLImportsController.cpp b/engine/core/html/imports/HTMLImportsController.cpp index 57fc45a6cbd..2c3dd26b1eb 100644 --- a/engine/core/html/imports/HTMLImportsController.cpp +++ b/engine/core/html/imports/HTMLImportsController.cpp @@ -114,15 +114,11 @@ HTMLImportChild* HTMLImportsController::load(HTMLImport* parent, HTMLImportChild return child; } - ResourcePtr resource = parent->document()->fetcher()->fetchImport(request); - if (!resource) - return 0; - HTMLImportLoader* loader = createLoader(); HTMLImportChild* child = createChild(request.url(), loader, parent, client); // We set resource after the import tree is built since // Resource::addClient() immediately calls back to feed the bytes when the resource is cached. - loader->startLoading(resource); + loader->startLoading(request.url()); child->didStartLoading(); return child; } diff --git a/engine/platform/BUILD.gn b/engine/platform/BUILD.gn index 9eeccdb2b33..d2424005fe1 100644 --- a/engine/platform/BUILD.gn +++ b/engine/platform/BUILD.gn @@ -221,6 +221,8 @@ component("platform") { "exported/linux/WebFontRenderStyle.cpp", "fetcher/DataPipeDrainer.cpp", "fetcher/DataPipeDrainer.h", + "fetcher/MojoFetcher.cpp", + "fetcher/MojoFetcher.h", "fonts/AlternateFontFamily.h", "fonts/Character.cpp", "fonts/Character.h", @@ -667,6 +669,14 @@ component("platform") { "//third_party/ots", "//third_party/qcms", "//third_party:jpeg", + "//mojo/common", + "//mojo/environment:chromium", + "//mojo/public/c/system:for_shared_library", + "//mojo/public/cpp/bindings", + "//mojo/public/cpp/utility", + "//mojo/services/public/interfaces/network", + "//sky/engine/wtf", + "//sky/engine/platform/heap", "//url", "//v8", ] diff --git a/engine/platform/DEPS b/engine/platform/DEPS index 8b62d03142c..ad6c456db9a 100644 --- a/engine/platform/DEPS +++ b/engine/platform/DEPS @@ -3,8 +3,9 @@ include_rules = [ "+platform", "+public/platform", "+skia/ext", - "+mojo/public", "+mojo/common", + "+mojo/public", + "+mojo/services/public", "+third_party/khronos", "+third_party/skia", "+url", diff --git a/engine/platform/fetcher/MojoFetcher.cpp b/engine/platform/fetcher/MojoFetcher.cpp new file mode 100644 index 00000000000..3edd90970ba --- /dev/null +++ b/engine/platform/fetcher/MojoFetcher.cpp @@ -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. + +#include "config.h" +#include "platform/fetcher/MojoFetcher.h" + +#include "base/bind.h" +#include "mojo/services/public/interfaces/network/network_service.mojom.h" +#include "platform/weborigin/KURL.h" +#include "public/platform/Platform.h" + +namespace blink { + +MojoFetcher::MojoFetcher(Client* client, const KURL& url) + : client_(client), + weak_factory_(this) { + DCHECK(client_); + + mojo::NetworkService* net = Platform::current()->networkService(); + net->CreateURLLoader(GetProxy(&url_loader_)); + + mojo::URLRequestPtr url_request = mojo::URLRequest::New(); + url_request->url = url.string().toUTF8(); + url_request->auto_follow_redirects = true; + url_loader_->Start(url_request.Pass(), + base::Bind(&MojoFetcher::OnReceivedResponse, + weak_factory_.GetWeakPtr())); +} + +MojoFetcher::~MojoFetcher() { +} + +void MojoFetcher::OnReceivedResponse(mojo::URLResponsePtr response) { + client_->OnReceivedResponse(response.Pass()); +} + +} // namespace blink diff --git a/engine/platform/fetcher/MojoFetcher.h b/engine/platform/fetcher/MojoFetcher.h new file mode 100644 index 00000000000..d435c6bc979 --- /dev/null +++ b/engine/platform/fetcher/MojoFetcher.h @@ -0,0 +1,39 @@ +// 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 SKY_ENGINE_PLATFORM_FETCHER_MOJO_FETCHER_H_ +#define SKY_ENGINE_PLATFORM_FETCHER_MOJO_FETCHER_H_ + +#include "base/memory/weak_ptr.h" +#include "mojo/services/public/interfaces/network/url_loader.mojom.h" + +namespace blink { +class KURL; + +class MojoFetcher { + public: + class Client { + public: + virtual void OnReceivedResponse(mojo::URLResponsePtr) = 0; + + protected: + virtual ~Client() { } + }; + + MojoFetcher(Client*, const KURL&); + ~MojoFetcher(); + + private: + void OnReceivedResponse(mojo::URLResponsePtr); + + Client* client_; + mojo::URLLoaderPtr url_loader_; + base::WeakPtrFactory weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(MojoFetcher); +}; + +} // namespace blink + +#endif // SKY_ENGINE_PLATFORM_FETCHER_MOJO_FETCHER_H_ diff --git a/engine/public/platform/Platform.h b/engine/public/platform/Platform.h index b350525b67d..4bce22f9a1c 100644 --- a/engine/public/platform/Platform.h +++ b/engine/public/platform/Platform.h @@ -47,6 +47,10 @@ class GrContext; +namespace mojo { +class NetworkService; +} + namespace blink { class WebBlobRegistry; @@ -169,6 +173,8 @@ public: // Network ------------------------------------------------------------- + virtual mojo::NetworkService* networkService() { return 0; } + // Returns a new WebURLLoader instance. virtual WebURLLoader* createURLLoader() { return 0; } diff --git a/engine/wtf/text/CString.h b/engine/wtf/text/CString.h index 02a9a30d33c..1a51d662d3c 100644 --- a/engine/wtf/text/CString.h +++ b/engine/wtf/text/CString.h @@ -29,6 +29,7 @@ #include "wtf/RefCounted.h" #include "wtf/RefPtr.h" #include "wtf/WTFExport.h" +#include namespace WTF { @@ -64,6 +65,11 @@ public: CString(CStringBuffer* buffer) : m_buffer(buffer) { } static CString newUninitialized(size_t length, char*& characterBuffer); + std::string toStdString() const + { + return std::string(data(), length()); + } + const char* data() const { return m_buffer ? m_buffer->data() : 0; diff --git a/engine/wtf/text/WTFString.cpp b/engine/wtf/text/WTFString.cpp index d72969f19a6..e23f7286a6f 100644 --- a/engine/wtf/text/WTFString.cpp +++ b/engine/wtf/text/WTFString.cpp @@ -871,6 +871,11 @@ CString String::utf8(UTF8ConversionMode mode) const return CString(bufferVector.data(), buffer - bufferVector.data()); } +std::string String::toUTF8() const +{ + return utf8().toStdString(); +} + String String::make8BitFrom16BitSource(const UChar* source, size_t length) { if (!length) diff --git a/engine/wtf/text/WTFString.h b/engine/wtf/text/WTFString.h index d76742abb43..62c7a25fa7f 100644 --- a/engine/wtf/text/WTFString.h +++ b/engine/wtf/text/WTFString.h @@ -179,6 +179,9 @@ public: CString latin1() const; CString utf8(UTF8ConversionMode = LenientUTF8Conversion) const; + // We should replace CString with std::string. + std::string toUTF8() const; + UChar operator[](unsigned index) const { if (!m_impl || index >= m_impl->length()) @@ -400,6 +403,7 @@ public: static String fromUTF8(const char* s, size_t length) { return fromUTF8(reinterpret_cast(s), length); }; static String fromUTF8(const char* s) { return fromUTF8(reinterpret_cast(s)); }; static String fromUTF8(const CString&); + static String fromUTF8(const std::string& s) { return fromUTF8(s.data(), s.size()); } // Tries to convert the passed in string to UTF-8, but will fall back to Latin-1 if the string is not valid UTF-8. static String fromUTF8WithLatin1Fallback(const LChar*, size_t); diff --git a/viewer/platform/platform_impl.cc b/viewer/platform/platform_impl.cc index 744c43d76b2..d5627768d33 100644 --- a/viewer/platform/platform_impl.cc +++ b/viewer/platform/platform_impl.cc @@ -153,6 +153,10 @@ blink::WebScrollbarBehavior* PlatformImpl::scrollbarBehavior() { return &scrollbar_behavior_; } +mojo::NetworkService* PlatformImpl::networkService() { + return network_service_.get(); +} + blink::WebURLLoader* PlatformImpl::createURLLoader() { return new WebURLLoaderImpl(network_service_.get()); } diff --git a/viewer/platform/platform_impl.h b/viewer/platform/platform_impl.h index 113c37624f2..be65126d242 100644 --- a/viewer/platform/platform_impl.h +++ b/viewer/platform/platform_impl.h @@ -41,6 +41,7 @@ class PlatformImpl : public blink::Platform { virtual void callOnMainThread(void (*func)(void*), void* context); virtual bool isThreadedCompositingEnabled(); virtual blink::WebCompositorSupport* compositorSupport(); + virtual mojo::NetworkService* networkService(); virtual blink::WebURLLoader* createURLLoader(); virtual blink::WebData parseDataURL( const blink::WebURL& url, blink::WebString& mime_type,