Commit 4336d85f authored by darin@chromium.org's avatar darin@chromium.org

Mojo: HTML Viewer based on Blink.

Review URL: https://codereview.chromium.org/340453002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@278800 0039d316-1c4b-4281-b951-d872f2087c98
parent a5f1381d
include_rules = [
"+skia",
"+net/base",
"+third_party/skia/include",
"+third_party/WebKit/public",
]
// 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 "mojo/examples/html_viewer/blink_platform_impl.h"
#include <cmath>
#include "base/rand_util.h"
#include "base/stl_util.h"
#include "base/synchronization/waitable_event.h"
#include "base/time/time.h"
#include "mojo/examples/html_viewer/webthread_impl.h"
#include "mojo/examples/html_viewer/weburlloader_impl.h"
#include "mojo/public/cpp/application/application.h"
#include "net/base/data_url.h"
#include "net/base/mime_util.h"
#include "net/base/net_errors.h"
#include "third_party/WebKit/public/platform/WebWaitableEvent.h"
namespace mojo {
namespace examples {
namespace {
// TODO(darin): Figure out what our UA should really be.
const char kUserAgentString[] =
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/35.0.1916.153 Safari/537.36";
class WebWaitableEventImpl : public blink::WebWaitableEvent {
public:
WebWaitableEventImpl() : impl_(new base::WaitableEvent(false, false)) {}
virtual ~WebWaitableEventImpl() {}
virtual void wait() { impl_->Wait(); }
virtual void signal() { impl_->Signal(); }
base::WaitableEvent* impl() {
return impl_.get();
}
private:
scoped_ptr<base::WaitableEvent> impl_;
DISALLOW_COPY_AND_ASSIGN(WebWaitableEventImpl);
};
} // namespace
BlinkPlatformImpl::BlinkPlatformImpl(Application* app)
: main_loop_(base::MessageLoop::current()),
shared_timer_func_(NULL),
shared_timer_fire_time_(0.0),
shared_timer_fire_time_was_set_while_suspended_(false),
shared_timer_suspended_(0),
current_thread_slot_(&DestroyCurrentThread) {
app->ConnectTo("mojo:mojo_network_service", &network_service_);
}
BlinkPlatformImpl::~BlinkPlatformImpl() {
}
blink::WebMimeRegistry* BlinkPlatformImpl::mimeRegistry() {
return &mime_registry_;
}
blink::WebThemeEngine* BlinkPlatformImpl::themeEngine() {
return &dummy_theme_engine_;
}
blink::WebString BlinkPlatformImpl::defaultLocale() {
return blink::WebString::fromUTF8("en-US");
}
double BlinkPlatformImpl::currentTime() {
return base::Time::Now().ToDoubleT();
}
double BlinkPlatformImpl::monotonicallyIncreasingTime() {
return base::TimeTicks::Now().ToInternalValue() /
static_cast<double>(base::Time::kMicrosecondsPerSecond);
}
void BlinkPlatformImpl::cryptographicallyRandomValues(unsigned char* buffer,
size_t length) {
base::RandBytes(buffer, length);
}
void BlinkPlatformImpl::setSharedTimerFiredFunction(void (*func)()) {
shared_timer_func_ = func;
}
void BlinkPlatformImpl::setSharedTimerFireInterval(
double interval_seconds) {
shared_timer_fire_time_ = interval_seconds + monotonicallyIncreasingTime();
if (shared_timer_suspended_) {
shared_timer_fire_time_was_set_while_suspended_ = true;
return;
}
// By converting between double and int64 representation, we run the risk
// of losing precision due to rounding errors. Performing computations in
// microseconds reduces this risk somewhat. But there still is the potential
// of us computing a fire time for the timer that is shorter than what we
// need.
// As the event loop will check event deadlines prior to actually firing
// them, there is a risk of needlessly rescheduling events and of
// needlessly looping if sleep times are too short even by small amounts.
// This results in measurable performance degradation unless we use ceil() to
// always round up the sleep times.
int64 interval = static_cast<int64>(
ceil(interval_seconds * base::Time::kMillisecondsPerSecond)
* base::Time::kMicrosecondsPerMillisecond);
if (interval < 0)
interval = 0;
shared_timer_.Stop();
shared_timer_.Start(FROM_HERE, base::TimeDelta::FromMicroseconds(interval),
this, &BlinkPlatformImpl::DoTimeout);
}
void BlinkPlatformImpl::stopSharedTimer() {
shared_timer_.Stop();
}
void BlinkPlatformImpl::callOnMainThread(
void (*func)(void*), void* context) {
main_loop_->PostTask(FROM_HERE, base::Bind(func, context));
}
const unsigned char* BlinkPlatformImpl::getTraceCategoryEnabledFlag(
const char* category_name) {
static const unsigned char buf[] = "*";
return buf;
}
blink::WebURLLoader* BlinkPlatformImpl::createURLLoader() {
return new WebURLLoaderImpl(network_service_.get());
}
blink::WebString BlinkPlatformImpl::userAgent() {
return blink::WebString::fromUTF8(kUserAgentString);
}
blink::WebData BlinkPlatformImpl::parseDataURL(
const blink::WebURL& url,
blink::WebString& mimetype_out,
blink::WebString& charset_out) {
std::string mimetype, charset, data;
if (net::DataURL::Parse(url, &mimetype, &charset, &data)
&& net::IsSupportedMimeType(mimetype)) {
mimetype_out = blink::WebString::fromUTF8(mimetype);
charset_out = blink::WebString::fromUTF8(charset);
return data;
}
return blink::WebData();
}
blink::WebURLError BlinkPlatformImpl::cancelledError(const blink::WebURL& url)
const {
blink::WebURLError error;
error.domain = blink::WebString::fromUTF8(net::kErrorDomain);
error.reason = net::ERR_ABORTED;
error.unreachableURL = url;
error.staleCopyInCache = false;
error.isCancellation = true;
return error;
}
blink::WebThread* BlinkPlatformImpl::createThread(const char* name) {
return new WebThreadImpl(name);
}
blink::WebThread* BlinkPlatformImpl::currentThread() {
WebThreadImplForMessageLoop* thread =
static_cast<WebThreadImplForMessageLoop*>(current_thread_slot_.Get());
if (thread)
return (thread);
scoped_refptr<base::MessageLoopProxy> message_loop =
base::MessageLoopProxy::current();
if (!message_loop.get())
return NULL;
thread = new WebThreadImplForMessageLoop(message_loop.get());
current_thread_slot_.Set(thread);
return thread;
}
blink::WebWaitableEvent* BlinkPlatformImpl::createWaitableEvent() {
return new WebWaitableEventImpl();
}
blink::WebWaitableEvent* BlinkPlatformImpl::waitMultipleEvents(
const blink::WebVector<blink::WebWaitableEvent*>& web_events) {
std::vector<base::WaitableEvent*> events;
for (size_t i = 0; i < web_events.size(); ++i)
events.push_back(static_cast<WebWaitableEventImpl*>(web_events[i])->impl());
size_t idx = base::WaitableEvent::WaitMany(
vector_as_array(&events), events.size());
DCHECK_LT(idx, web_events.size());
return web_events[idx];
}
// static
void BlinkPlatformImpl::DestroyCurrentThread(void* thread) {
WebThreadImplForMessageLoop* impl =
static_cast<WebThreadImplForMessageLoop*>(thread);
delete impl;
}
} // namespace examples
} // namespace mojo
// 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 MOJO_EXAMPLE_HTML_VIEWER_BLINK_PLATFORM_IMPL_H_
#define MOJO_EXAMPLE_HTML_VIEWER_BLINK_PLATFORM_IMPL_H_
#include "base/message_loop/message_loop.h"
#include "base/threading/thread_local_storage.h"
#include "base/timer/timer.h"
#include "mojo/examples/html_viewer/webmimeregistry_impl.h"
#include "mojo/services/public/interfaces/network/network_service.mojom.h"
#include "third_party/WebKit/public/platform/Platform.h"
#include "third_party/WebKit/public/platform/WebThemeEngine.h"
namespace mojo {
class Application;
namespace examples {
class BlinkPlatformImpl : public blink::Platform {
public:
explicit BlinkPlatformImpl(Application* app);
virtual ~BlinkPlatformImpl();
// blink::Platform methods:
virtual blink::WebMimeRegistry* mimeRegistry();
virtual blink::WebThemeEngine* themeEngine();
virtual blink::WebString defaultLocale();
virtual double currentTime();
virtual double monotonicallyIncreasingTime();
virtual void cryptographicallyRandomValues(
unsigned char* buffer, size_t length);
virtual void setSharedTimerFiredFunction(void (*func)());
virtual void setSharedTimerFireInterval(double interval_seconds);
virtual void stopSharedTimer();
virtual void callOnMainThread(void (*func)(void*), void* context);
virtual blink::WebURLLoader* createURLLoader();
virtual blink::WebString userAgent();
virtual blink::WebData parseDataURL(
const blink::WebURL& url, blink::WebString& mime_type,
blink::WebString& charset);
virtual blink::WebURLError cancelledError(const blink::WebURL& url) const;
virtual blink::WebThread* createThread(const char* name);
virtual blink::WebThread* currentThread();
virtual blink::WebWaitableEvent* createWaitableEvent();
virtual blink::WebWaitableEvent* waitMultipleEvents(
const blink::WebVector<blink::WebWaitableEvent*>& events);
virtual const unsigned char* getTraceCategoryEnabledFlag(
const char* category_name);
private:
void SuspendSharedTimer();
void ResumeSharedTimer();
void DoTimeout() {
if (shared_timer_func_ && !shared_timer_suspended_)
shared_timer_func_();
}
static void DestroyCurrentThread(void*);
NetworkServicePtr network_service_;
base::MessageLoop* main_loop_;
base::OneShotTimer<BlinkPlatformImpl> shared_timer_;
void (*shared_timer_func_)();
double shared_timer_fire_time_;
bool shared_timer_fire_time_was_set_while_suspended_;
int shared_timer_suspended_; // counter
base::ThreadLocalStorage::Slot current_thread_slot_;
blink::WebThemeEngine dummy_theme_engine_;
WebMimeRegistryImpl mime_registry_;
};
} // namespace examples
} // namespace mojo
#endif // MOJO_EXAMPLE_HTML_VIEWER_BLINK_PLATFORM_IMPL_H_
// 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 "mojo/examples/html_viewer/html_document_view.h"
#include "base/bind.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
#include "mojo/services/public/cpp/view_manager/node.h"
#include "mojo/services/public/cpp/view_manager/view.h"
#include "skia/ext/refptr.h"
#include "third_party/WebKit/public/web/WebConsoleMessage.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebElement.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebScriptSource.h"
#include "third_party/WebKit/public/web/WebSettings.h"
#include "third_party/WebKit/public/web/WebView.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkDevice.h"
namespace mojo {
namespace examples {
namespace {
blink::WebData CopyToWebData(DataPipeConsumerHandle handle) {
std::vector<char> data;
for (;;) {
char buf[4096];
uint32_t num_bytes = sizeof(buf);
MojoResult result = ReadDataRaw(
handle,
buf,
&num_bytes,
MOJO_READ_DATA_FLAG_NONE);
if (result == MOJO_RESULT_SHOULD_WAIT) {
Wait(handle,
MOJO_HANDLE_SIGNAL_READABLE,
MOJO_DEADLINE_INDEFINITE);
} else if (result == MOJO_RESULT_OK) {
data.insert(data.end(), buf, buf + num_bytes);
} else {
break;
}
}
return blink::WebData(data);
}
void ConfigureSettings(blink::WebSettings* settings) {
settings->setAcceleratedCompositingEnabled(false);
settings->setLoadsImagesAutomatically(true);
settings->setJavaScriptEnabled(true);
}
} // namespace
HTMLDocumentView::HTMLDocumentView(view_manager::ViewManager* view_manager)
: view_manager_(view_manager),
view_(view_manager::View::Create(view_manager_)),
web_view_(NULL),
repaint_pending_(false),
weak_factory_(this) {
}
HTMLDocumentView::~HTMLDocumentView() {
if (web_view_)
web_view_->close();
}
void HTMLDocumentView::AttachToNode(view_manager::Node* node) {
node->SetActiveView(view_);
view_->SetColor(SK_ColorCYAN); // Dummy background color.
web_view_ = blink::WebView::create(this);
ConfigureSettings(web_view_->settings());
web_view_->setMainFrame(blink::WebLocalFrame::create(this));
// TODO(darin): Track size of view_manager::Node.
web_view_->resize(gfx::Size(800, 600));
}
void HTMLDocumentView::Load(URLResponsePtr response,
ScopedDataPipeConsumerHandle response_body_stream) {
DCHECK(web_view_);
// TODO(darin): A better solution would be to use loadRequest, but intercept
// the network request and connect it to the response we already have.
blink::WebData data = CopyToWebData(response_body_stream.get());
web_view_->mainFrame()->loadHTMLString(
data, GURL(response->url), GURL(response->url));
}
void HTMLDocumentView::didInvalidateRect(const blink::WebRect& rect) {
if (!repaint_pending_) {
repaint_pending_ = true;
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::Bind(&HTMLDocumentView::Repaint, weak_factory_.GetWeakPtr()));
}
}
bool HTMLDocumentView::allowsBrokenNullLayerTreeView() const {
// TODO(darin): Switch to using compositor bindings.
//
// NOTE: Note to Blink maintainers, feel free to just break this code if it
// is the last using compositor bindings and you want to delete the old path.
//
return true;
}
void HTMLDocumentView::didAddMessageToConsole(
const blink::WebConsoleMessage& message,
const blink::WebString& source_name,
unsigned source_line,
const blink::WebString& stack_trace) {
printf("### console: %s\n", std::string(message.text.utf8()).c_str());
}
void HTMLDocumentView::Repaint() {
repaint_pending_ = false;
web_view_->animate(0.0);
web_view_->layout();
int width = web_view_->size().width;
int height = web_view_->size().height;
skia::RefPtr<SkCanvas> canvas = skia::AdoptRef(SkCanvas::NewRaster(
SkImageInfo::MakeN32(width, height, kOpaque_SkAlphaType)));
web_view_->paint(canvas.get(), gfx::Rect(0, 0, width, height));
view_->SetContents(canvas->getDevice()->accessBitmap(false));
}
} // namespace examples
} // namespace mojo
// 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 MOJO_EXAMPLES_HTML_VIEWER_HTML_DOCUMENT_VIEW_H_
#define MOJO_EXAMPLES_HTML_VIEWER_HTML_DOCUMENT_VIEW_H_
#include "base/memory/weak_ptr.h"
#include "mojo/services/public/interfaces/network/url_loader.mojom.h"
#include "third_party/WebKit/public/web/WebFrameClient.h"
#include "third_party/WebKit/public/web/WebViewClient.h"
namespace mojo {
namespace view_manager {
class Node;
class ViewManager;
class View;
}
namespace examples {
// A view for a single HTML document.
class HTMLDocumentView : public blink::WebViewClient,
public blink::WebFrameClient {
public:
explicit HTMLDocumentView(view_manager::ViewManager* view_manager);
virtual ~HTMLDocumentView();
void AttachToNode(view_manager::Node* node);
void Load(URLResponsePtr response,
ScopedDataPipeConsumerHandle response_body_stream);
private:
// WebWidgetClient methods:
virtual void didInvalidateRect(const blink::WebRect& rect);
virtual bool allowsBrokenNullLayerTreeView() const;
// WebFrameClient methods:
virtual void didAddMessageToConsole(
const blink::WebConsoleMessage& message,
const blink::WebString& source_name,
unsigned source_line,
const blink::WebString& stack_trace);
void Repaint();
view_manager::ViewManager* view_manager_;
view_manager::View* view_;
blink::WebView* web_view_;
bool repaint_pending_;
base::WeakPtrFactory<HTMLDocumentView> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(HTMLDocumentView);
};
} // namespace examples
} // namespace mojo
#endif // MOJO_EXAMPLES_HTML_VIEWER_HTML_DOCUMENT_VIEW_H_
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "mojo/examples/html_viewer/blink_platform_impl.h"
#include "mojo/examples/html_viewer/html_document_view.h"
#include "mojo/public/cpp/application/application.h"
#include "mojo/services/public/cpp/view_manager/node.h"
#include "mojo/services/public/cpp/view_manager/types.h"
......@@ -9,6 +11,7 @@
#include "mojo/services/public/cpp/view_manager/view_manager.h"
#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
#include "mojo/services/public/interfaces/navigation/navigation.mojom.h"
#include "third_party/WebKit/public/web/WebKit.h"
namespace mojo {
namespace examples {
......@@ -25,34 +28,7 @@ class NavigatorImpl : public InterfaceImpl<navigation::Navigator> {
virtual void Navigate(
uint32_t node_id,
navigation::NavigationDetailsPtr navigation_details,
navigation::ResponseDetailsPtr response_details) OVERRIDE {
printf("In HTMLViewer, rendering url: %s\n",
response_details->response->url.data());
printf("HTML: \n");
for (;;) {
char buf[512];
uint32_t num_bytes = sizeof(buf);
MojoResult result = ReadDataRaw(
response_details->response_body_stream.get(),
buf,
&num_bytes,
MOJO_READ_DATA_FLAG_NONE);
if (result == MOJO_RESULT_SHOULD_WAIT) {
Wait(response_details->response_body_stream.get(),
MOJO_HANDLE_SIGNAL_READABLE,
MOJO_DEADLINE_INDEFINITE);
} else if (result == MOJO_RESULT_OK) {
fwrite(buf, num_bytes, 1, stdout);
} else {
break;
}
}
printf("\n>>>> EOF <<<<\n\n");
UpdateView();
}
void UpdateView();
navigation::ResponseDetailsPtr response_details) OVERRIDE;
HTMLViewer* viewer_;
......@@ -62,14 +38,26 @@ class NavigatorImpl : public InterfaceImpl<navigation::Navigator> {
class HTMLViewer : public Application,
public view_manager::ViewManagerDelegate {
public:
HTMLViewer() : content_view_(NULL) {}
virtual ~HTMLViewer() {}
HTMLViewer() : document_view_(NULL) {
}
virtual ~HTMLViewer() {
blink::shutdown();
}
private:
friend class NavigatorImpl;
void Load(URLResponsePtr response,
ScopedDataPipeConsumerHandle response_body_stream) {
// Need to wait for OnRootAdded.
response_ = response.Pass();
response_body_stream_ = response_body_stream.Pass();
MaybeLoad();
}
private:
// Overridden from Application:
virtual void Initialize() OVERRIDE {
blink_platform_impl_.reset(new BlinkPlatformImpl(this));
blink::initialize(blink_platform_impl_.get());
AddService<NavigatorImpl>(this);
view_manager::ViewManager::Create(this, this);
}
......@@ -77,18 +65,34 @@ class HTMLViewer : public Application,
// Overridden from view_manager::ViewManagerDelegate:
virtual void OnRootAdded(view_manager::ViewManager* view_manager,
view_manager::Node* root) OVERRIDE {
content_view_ = view_manager::View::Create(view_manager);
root->SetActiveView(content_view_);
content_view_->SetColor(SK_ColorRED);
document_view_ = new HTMLDocumentView(view_manager);
document_view_->AttachToNode(root);
MaybeLoad();
}
void MaybeLoad() {
if (document_view_ && response_.get())
document_view_->Load(response_.Pass(), response_body_stream_.Pass());
}
view_manager::View* content_view_;
scoped_ptr<BlinkPlatformImpl> blink_platform_impl_;
// TODO(darin): Figure out proper ownership of this instance.
HTMLDocumentView* document_view_;
URLResponsePtr response_;
ScopedDataPipeConsumerHandle response_body_stream_;
DISALLOW_COPY_AND_ASSIGN(HTMLViewer);
};
void NavigatorImpl::UpdateView() {
viewer_->content_view_->SetColor(SK_ColorGREEN);
void NavigatorImpl::Navigate(
uint32_t node_id,
navigation::NavigationDetailsPtr navigation_details,
navigation::ResponseDetailsPtr response_details) {
printf("In HTMLViewer, rendering url: %s\n",
response_details->response->url.data());
viewer_->Load(response_details->response.Pass(),
response_details->response_body_stream.Pass());
}
}
......
// 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 "mojo/examples/html_viewer/webmimeregistry_impl.h"
#include "base/files/file_path.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "net/base/mime_util.h"
#include "third_party/WebKit/public/platform/WebString.h"
namespace mojo {
namespace examples {
namespace {
std::string ToASCIIOrEmpty(const blink::WebString& string) {
return base::IsStringASCII(string) ? base::UTF16ToASCII(string)
: std::string();
}
} // namespace
blink::WebMimeRegistry::SupportsType WebMimeRegistryImpl::supportsMIMEType(
const blink::WebString& mime_type) {
return net::IsSupportedMimeType(ToASCIIOrEmpty(mime_type)) ?
blink::WebMimeRegistry::IsSupported :
blink::WebMimeRegistry::IsNotSupported;
}
blink::WebMimeRegistry::SupportsType WebMimeRegistryImpl::supportsImageMIMEType(
const blink::WebString& mime_type) {
return net::IsSupportedImageMimeType(ToASCIIOrEmpty(mime_type)) ?
blink::WebMimeRegistry::IsSupported :
blink::WebMimeRegistry::IsNotSupported;
}
blink::WebMimeRegistry::SupportsType
WebMimeRegistryImpl::supportsJavaScriptMIMEType(
const blink::WebString& mime_type) {
return net::IsSupportedJavascriptMimeType(ToASCIIOrEmpty(mime_type)) ?
blink::WebMimeRegistry::IsSupported :
blink::WebMimeRegistry::IsNotSupported;
}
blink::WebMimeRegistry::SupportsType WebMimeRegistryImpl::supportsMediaMIMEType(
const blink::WebString& mime_type,
const blink::WebString& codecs,
const blink::WebString& key_system) {
NOTIMPLEMENTED();
return IsNotSupported;
}
bool WebMimeRegistryImpl::supportsMediaSourceMIMEType(
const blink::WebString& mime_type,
const blink::WebString& codecs) {
NOTIMPLEMENTED();
return false;
}
bool WebMimeRegistryImpl::supportsEncryptedMediaMIMEType(
const blink::WebString& key_system,
const blink::WebString& mime_type,
const blink::WebString& codecs) {
NOTIMPLEMENTED();
return false;
}
blink::WebMimeRegistry::SupportsType
WebMimeRegistryImpl::supportsNonImageMIMEType(
const blink::WebString& mime_type) {
return net::IsSupportedNonImageMimeType(ToASCIIOrEmpty(mime_type)) ?
blink::WebMimeRegistry::IsSupported :
blink::WebMimeRegistry::IsNotSupported;
}
blink::WebString WebMimeRegistryImpl::mimeTypeForExtension(
const blink::WebString& file_extension) {
NOTIMPLEMENTED();
return blink::WebString();
}
blink::WebString WebMimeRegistryImpl::wellKnownMimeTypeForExtension(
const blink::WebString& file_extension) {
NOTIMPLEMENTED();
return blink::WebString();
}
blink::WebString WebMimeRegistryImpl::mimeTypeFromFile(
const blink::WebString& file_path) {
NOTIMPLEMENTED();
return blink::WebString();
}
} // namespace examples
} // namespace mojo
// 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 MOJO_EXAMPLES_HTML_VIEWER_WEBMIMEREGISTRY_IMPL_H_
#define MOJO_EXAMPLES_HTML_VIEWER_WEBMIMEREGISTRY_IMPL_H_
#include "base/compiler_specific.h"
#include "third_party/WebKit/public/platform/WebMimeRegistry.h"
namespace mojo {
namespace examples {
class WebMimeRegistryImpl : public blink::WebMimeRegistry {
public:
WebMimeRegistryImpl() {}
virtual ~WebMimeRegistryImpl() {}
// WebMimeRegistry methods:
virtual blink::WebMimeRegistry::SupportsType supportsMIMEType(
const blink::WebString& mime_type);
virtual blink::WebMimeRegistry::SupportsType supportsImageMIMEType(
const blink::WebString& mime_type);
virtual blink::WebMimeRegistry::SupportsType supportsJavaScriptMIMEType(
const blink::WebString& mime_type);
virtual blink::WebMimeRegistry::SupportsType supportsMediaMIMEType(
const blink::WebString& mime_type,
const blink::WebString& codecs,
const blink::WebString& key_system);
virtual bool supportsMediaSourceMIMEType(
const blink::WebString& mime_type,
const blink::WebString& codecs);
virtual bool supportsEncryptedMediaMIMEType(
const blink::WebString& key_system,
const blink::WebString& mime_type,
const blink::WebString& codecs);
virtual blink::WebMimeRegistry::SupportsType supportsNonImageMIMEType(
const blink::WebString& mime_type);
virtual blink::WebString mimeTypeForExtension(
const blink::WebString& extension);
virtual blink::WebString wellKnownMimeTypeForExtension(
const blink::WebString& extension);
virtual blink::WebString mimeTypeFromFile(
const blink::WebString& path);
};
} // namespace examples
} // namespace mojo
#endif // MOJO_EXAMPLES_HTML_VIEWER_WEBMIMEREGISTRY_IMPL_H_
// 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.
// An implementation of WebThread in terms of base::MessageLoop and
// base::Thread
#include "mojo/examples/html_viewer/webthread_impl.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/message_loop/message_loop.h"
#include "base/pending_task.h"
#include "base/threading/platform_thread.h"
namespace mojo {
namespace examples {
WebThreadBase::WebThreadBase() {}
WebThreadBase::~WebThreadBase() {}
class WebThreadBase::TaskObserverAdapter
: public base::MessageLoop::TaskObserver {
public:
TaskObserverAdapter(WebThread::TaskObserver* observer)
: observer_(observer) {}
virtual void WillProcessTask(const base::PendingTask& pending_task) OVERRIDE {
observer_->willProcessTask();
}
virtual void DidProcessTask(const base::PendingTask& pending_task) OVERRIDE {
observer_->didProcessTask();
}
private:
WebThread::TaskObserver* observer_;
};
void WebThreadBase::addTaskObserver(TaskObserver* observer) {
CHECK(isCurrentThread());
std::pair<TaskObserverMap::iterator, bool> result = task_observer_map_.insert(
std::make_pair(observer, static_cast<TaskObserverAdapter*>(NULL)));
if (result.second)
result.first->second = new TaskObserverAdapter(observer);
base::MessageLoop::current()->AddTaskObserver(result.first->second);
}
void WebThreadBase::removeTaskObserver(TaskObserver* observer) {
CHECK(isCurrentThread());
TaskObserverMap::iterator iter = task_observer_map_.find(observer);
if (iter == task_observer_map_.end())
return;
base::MessageLoop::current()->RemoveTaskObserver(iter->second);
delete iter->second;
task_observer_map_.erase(iter);
}
WebThreadImpl::WebThreadImpl(const char* name)
: thread_(new base::Thread(name)) {
thread_->Start();
}
void WebThreadImpl::postTask(Task* task) {
thread_->message_loop()->PostTask(
FROM_HERE, base::Bind(&blink::WebThread::Task::run, base::Owned(task)));
}
void WebThreadImpl::postDelayedTask(Task* task, long long delay_ms) {
thread_->message_loop()->PostDelayedTask(
FROM_HERE,
base::Bind(&blink::WebThread::Task::run, base::Owned(task)),
base::TimeDelta::FromMilliseconds(delay_ms));
}
void WebThreadImpl::enterRunLoop() {
CHECK(isCurrentThread());
CHECK(!thread_->message_loop()->is_running()); // We don't support nesting.
thread_->message_loop()->Run();
}
void WebThreadImpl::exitRunLoop() {
CHECK(isCurrentThread());
CHECK(thread_->message_loop()->is_running());
thread_->message_loop()->Quit();
}
bool WebThreadImpl::isCurrentThread() const {
return thread_->thread_id() == base::PlatformThread::CurrentId();
}
WebThreadImpl::~WebThreadImpl() {
thread_->Stop();
}
WebThreadImplForMessageLoop::WebThreadImplForMessageLoop(
base::MessageLoopProxy* message_loop)
: message_loop_(message_loop) {}
void WebThreadImplForMessageLoop::postTask(Task* task) {
message_loop_->PostTask(
FROM_HERE, base::Bind(&blink::WebThread::Task::run, base::Owned(task)));
}
void WebThreadImplForMessageLoop::postDelayedTask(Task* task,
long long delay_ms) {
message_loop_->PostDelayedTask(
FROM_HERE,
base::Bind(&blink::WebThread::Task::run, base::Owned(task)),
base::TimeDelta::FromMilliseconds(delay_ms));
}
void WebThreadImplForMessageLoop::enterRunLoop() {
CHECK(isCurrentThread());
// We don't support nesting.
CHECK(!base::MessageLoop::current()->is_running());
base::MessageLoop::current()->Run();
}
void WebThreadImplForMessageLoop::exitRunLoop() {
CHECK(isCurrentThread());
CHECK(base::MessageLoop::current()->is_running());
base::MessageLoop::current()->Quit();
}
bool WebThreadImplForMessageLoop::isCurrentThread() const {
return message_loop_->BelongsToCurrentThread();
}
WebThreadImplForMessageLoop::~WebThreadImplForMessageLoop() {}
} // namespace examples
} // namespace mojo
// 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 MOJO_EXAMPLES_HTML_VIEWER_WEBTHREAD_IMPL_H_
#define MOJO_EXAMPLES_HTML_VIEWER_WEBTHREAD_IMPL_H_
#include <map>
#include "base/memory/scoped_ptr.h"
#include "base/threading/thread.h"
#include "third_party/WebKit/public/platform/WebThread.h"
namespace mojo {
namespace examples {
class WebThreadBase : public blink::WebThread {
public:
virtual ~WebThreadBase();
virtual void addTaskObserver(TaskObserver* observer);
virtual void removeTaskObserver(TaskObserver* observer);
virtual bool isCurrentThread() const = 0;
protected:
WebThreadBase();
private:
class TaskObserverAdapter;
typedef std::map<TaskObserver*, TaskObserverAdapter*> TaskObserverMap;
TaskObserverMap task_observer_map_;
};
class WebThreadImpl : public WebThreadBase {
public:
explicit WebThreadImpl(const char* name);
virtual ~WebThreadImpl();
virtual void postTask(Task* task);
virtual void postDelayedTask(Task* task, long long delay_ms);
virtual void enterRunLoop();
virtual void exitRunLoop();
base::MessageLoop* message_loop() const { return thread_->message_loop(); }
virtual bool isCurrentThread() const;
private:
scoped_ptr<base::Thread> thread_;
};
class WebThreadImplForMessageLoop : public WebThreadBase {
public:
explicit WebThreadImplForMessageLoop(
base::MessageLoopProxy* message_loop);
virtual ~WebThreadImplForMessageLoop();
virtual void postTask(Task* task);
virtual void postDelayedTask(Task* task, long long delay_ms);
virtual void enterRunLoop();
virtual void exitRunLoop();
private:
virtual bool isCurrentThread() const;
scoped_refptr<base::MessageLoopProxy> message_loop_;
};
} // namespace examples
} // namespace mojo
#endif // MOJO_EXAMPLES_HTML_VIEWER_WEBTHREAD_IMPL_H_
// 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 "mojo/examples/html_viewer/weburlloader_impl.h"
#include "base/bind.h"
#include "base/logging.h"
#include "mojo/services/public/interfaces/network/network_service.mojom.h"
#include "third_party/WebKit/public/platform/WebURLError.h"
#include "third_party/WebKit/public/platform/WebURLLoaderClient.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h"
#include "third_party/WebKit/public/platform/WebURLResponse.h"
namespace mojo {
namespace examples {
namespace {
blink::WebURLResponse ToWebURLResponse(const URLResponsePtr& url_response) {
blink::WebURLResponse result;
result.initialize();
result.setURL(GURL(url_response->url));
// TODO(darin): Copy other fields.
return result;
}
} // namespace
WebURLLoaderImpl::WebURLLoaderImpl(NetworkService* network_service)
: client_(NULL),
weak_factory_(this) {
network_service->CreateURLLoader(Get(&url_loader_));
url_loader_.set_client(this);
}
WebURLLoaderImpl::~WebURLLoaderImpl() {
}
void WebURLLoaderImpl::loadSynchronously(
const blink::WebURLRequest& request,
blink::WebURLResponse& response,
blink::WebURLError& error,
blink::WebData& data) {
NOTIMPLEMENTED();
}
void WebURLLoaderImpl::loadAsynchronously(const blink::WebURLRequest& request,
blink::WebURLLoaderClient* client) {
client_ = client;
URLRequestPtr url_request(URLRequest::New());
url_request->url = request.url().spec();
url_request->auto_follow_redirects = false;
// TODO(darin): Copy other fields.
DataPipe pipe;
url_loader_->Start(url_request.Pass(), pipe.producer_handle.Pass());
response_body_stream_ = pipe.consumer_handle.Pass();
}
void WebURLLoaderImpl::cancel() {
url_loader_.reset();
response_body_stream_.reset();
// TODO(darin): Need to asynchronously call didFail.
}
void WebURLLoaderImpl::setDefersLoading(bool defers_loading) {
NOTIMPLEMENTED();
}
void WebURLLoaderImpl::OnReceivedRedirect(URLResponsePtr url_response,
const String& new_url,
const String& new_method) {
blink::WebURLRequest new_request;
new_request.initialize();
new_request.setURL(GURL(new_url));
client_->willSendRequest(this, new_request, ToWebURLResponse(url_response));
// TODO(darin): Check if new_request was rejected.
url_loader_->FollowRedirect();
}
void WebURLLoaderImpl::OnReceivedResponse(URLResponsePtr url_response) {
client_->didReceiveResponse(this, ToWebURLResponse(url_response));
// Start streaming data
ReadMore();
}
void WebURLLoaderImpl::OnReceivedError(NetworkErrorPtr error) {
// TODO(darin): Construct a meaningful WebURLError.
client_->didFail(this, blink::WebURLError());
}
void WebURLLoaderImpl::OnReceivedEndOfResponseBody() {
// This is the signal that the response body was not truncated.
}
void WebURLLoaderImpl::ReadMore() {
const void* buf;
uint32_t buf_size;
MojoResult rv = BeginReadDataRaw(response_body_stream_.get(),
&buf,
&buf_size,
MOJO_READ_DATA_FLAG_NONE);
if (rv == MOJO_RESULT_OK) {
client_->didReceiveData(this, static_cast<const char*>(buf), buf_size, -1);
EndReadDataRaw(response_body_stream_.get(), buf_size);
WaitToReadMore();
} else if (rv == MOJO_RESULT_SHOULD_WAIT) {
WaitToReadMore();
} else if (rv == MOJO_RESULT_FAILED_PRECONDITION) {
// We reached end-of-file.
double finish_time = base::Time::Now().ToDoubleT();
client_->didFinishLoading(
this,
finish_time,
blink::WebURLLoaderClient::kUnknownEncodedDataLength);
} else {
// TODO(darin): Oops!
}
}
void WebURLLoaderImpl::WaitToReadMore() {
handle_watcher_.Start(
response_body_stream_.get(),
MOJO_HANDLE_SIGNAL_READABLE,
MOJO_DEADLINE_INDEFINITE,
base::Bind(&WebURLLoaderImpl::OnResponseBodyStreamReady,
weak_factory_.GetWeakPtr()));
}
void WebURLLoaderImpl::OnResponseBodyStreamReady(MojoResult result) {
ReadMore();
}
} // namespace examples
} // namespace mojo
// 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 MOJO_EXAMPLE_HTML_VIEWER_WEBURLLOADER_IMPL_H_
#define MOJO_EXAMPLE_HTML_VIEWER_WEBURLLOADER_IMPL_H_
#include "base/memory/weak_ptr.h"
#include "mojo/common/handle_watcher.h"
#include "mojo/services/public/interfaces/network/url_loader.mojom.h"
#include "third_party/WebKit/public/platform/WebURLLoader.h"
namespace mojo {
class NetworkService;
namespace examples {
class WebURLLoaderImpl : public blink::WebURLLoader,
public URLLoaderClient {
public:
explicit WebURLLoaderImpl(NetworkService* network_service);
private:
virtual ~WebURLLoaderImpl();
// blink::WebURLLoader methods:
virtual void loadSynchronously(
const blink::WebURLRequest& request, blink::WebURLResponse& response,
blink::WebURLError& error, blink::WebData& data) OVERRIDE;
virtual void loadAsynchronously(
const blink::WebURLRequest&, blink::WebURLLoaderClient* client) OVERRIDE;
virtual void cancel() OVERRIDE;
virtual void setDefersLoading(bool defers_loading) OVERRIDE;
// URLLoaderClient methods:
virtual void OnReceivedRedirect(URLResponsePtr response,
const String& new_url,
const String& new_method) OVERRIDE;
virtual void OnReceivedResponse(URLResponsePtr response) OVERRIDE;
virtual void OnReceivedError(NetworkErrorPtr error) OVERRIDE;
virtual void OnReceivedEndOfResponseBody() OVERRIDE;
void ReadMore();
void WaitToReadMore();
void OnResponseBodyStreamReady(MojoResult result);
URLLoaderPtr url_loader_;
blink::WebURLLoaderClient* client_;
ScopedDataPipeConsumerHandle response_body_stream_;
common::HandleWatcher handle_watcher_;
base::WeakPtrFactory<WebURLLoaderImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(WebURLLoaderImpl);
};
} // namespace examples
} // namespace mojo
#endif // MOJO_EXAMPLE_HTML_VIEWER_WEBURLLOADER_IMPL_H_
......@@ -95,7 +95,10 @@
'target_name': 'mojo_html_viewer',
'type': 'shared_library',
'dependencies': [
'../net/net.gyp:net',
'../skia/skia.gyp:skia',
'../third_party/WebKit/public/blink.gyp:blink',
'../url/url.gyp:url_lib',
'mojo_application',
'mojo_cpp_bindings',
'mojo_environment_chromium',
......@@ -106,8 +109,21 @@
'mojo_utility',
'mojo_view_manager_lib',
],
'include_dirs': [
'third_party/WebKit'
],
'sources': [
'examples/html_viewer/blink_platform_impl.cc',
'examples/html_viewer/blink_platform_impl.h',
'examples/html_viewer/html_viewer.cc',
'examples/html_viewer/html_document_view.cc',
'examples/html_viewer/html_document_view.h',
'examples/html_viewer/webmimeregistry_impl.cc',
'examples/html_viewer/webmimeregistry_impl.h',
'examples/html_viewer/webthread_impl.cc',
'examples/html_viewer/webthread_impl.h',
'examples/html_viewer/weburlloader_impl.cc',
'examples/html_viewer/weburlloader_impl.h',
'public/cpp/application/lib/mojo_main_chromium.cc',
],
},
......
......@@ -207,7 +207,7 @@ void URLLoaderImpl::ReadMore() {
uint32_t num_bytes;
if (!pending_write_->BeginWrite(&num_bytes))
CHECK(false); // Oops!
CHECK(false); // Oops! TODO(darin): crbug/386877: The pipe might be full!
if (num_bytes > static_cast<uint32_t>(std::numeric_limits<int>::max()))
CHECK(false); // Oops!
......
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