| // 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/command_line.h" |
| #include "base/logging.h" |
| #include "base/macros.h" |
| #include "base/message_loop/message_loop.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/threading/thread.h" |
| #include "gin/public/isolate_holder.h" |
| #include "mojo/application/application_runner_chromium.h" |
| #include "mojo/public/c/system/main.h" |
| #include "mojo/public/cpp/application/application_connection.h" |
| #include "mojo/public/cpp/application/application_delegate.h" |
| #include "mojo/public/cpp/application/application_impl.h" |
| #include "mojo/public/cpp/application/connect.h" |
| #include "mojo/public/cpp/application/interface_factory_impl.h" |
| #include "mojo/services/content_handler/public/interfaces/content_handler.mojom.h" |
| #include "mojo/services/html_viewer/html_document.h" |
| #include "mojo/services/html_viewer/mojo_blink_platform_impl.h" |
| #include "mojo/services/html_viewer/webmediaplayer_factory.h" |
| #include "mojo/services/network/public/interfaces/network_service.mojom.h" |
| #include "third_party/WebKit/public/web/WebKit.h" |
| #include "third_party/WebKit/public/web/WebRuntimeFeatures.h" |
| |
| #if !defined(COMPONENT_BUILD) |
| #include "base/i18n/icu_util.h" |
| #include "base/path_service.h" |
| #include "ui/base/resource/resource_bundle.h" |
| #include "ui/base/ui_base_paths.h" |
| #endif |
| |
| using mojo::ApplicationConnection; |
| using mojo::Array; |
| using mojo::ContentHandler; |
| using mojo::InterfaceRequest; |
| using mojo::ServiceProvider; |
| using mojo::ServiceProviderPtr; |
| using mojo::ShellPtr; |
| using mojo::String; |
| using mojo::URLLoaderPtr; |
| using mojo::URLResponsePtr; |
| |
| namespace html_viewer { |
| |
| // Switches for html_viewer to be used with "--args-for". For example: |
| // --args-for='mojo:html_viewer --enable-mojo-media-renderer' |
| |
| // Enable MediaRenderer in media pipeline instead of using the internal |
| // media::Renderer implementation. |
| const char kEnableMojoMediaRenderer[] = "enable-mojo-media-renderer"; |
| |
| // Enables support for Encrypted Media Extensions (e.g. MediaKeys). |
| const char kEnableEncryptedMedia[] = "enable-encrypted-media"; |
| |
| class HTMLViewer; |
| |
| class HTMLViewerApplication : public mojo::Application { |
| public: |
| HTMLViewerApplication(ShellPtr shell, |
| URLResponsePtr response, |
| scoped_refptr<base::MessageLoopProxy> compositor_thread, |
| WebMediaPlayerFactory* web_media_player_factory) |
| : url_(response->url), |
| shell_(shell.Pass()), |
| initial_response_(response.Pass()), |
| compositor_thread_(compositor_thread), |
| web_media_player_factory_(web_media_player_factory) { |
| shell_.set_client(this); |
| ServiceProviderPtr service_provider; |
| shell_->ConnectToApplication("mojo:network_service", |
| GetProxy(&service_provider), nullptr); |
| ConnectToService(service_provider.get(), &network_service_); |
| } |
| |
| void Initialize(Array<String> args) override {} |
| |
| void AcceptConnection(const String& requestor_url, |
| InterfaceRequest<ServiceProvider> services, |
| ServiceProviderPtr exposed_services) override { |
| if (initial_response_) { |
| OnResponseReceived(URLLoaderPtr(), services.Pass(), |
| initial_response_.Pass()); |
| } else { |
| URLLoaderPtr loader; |
| network_service_->CreateURLLoader(GetProxy(&loader)); |
| mojo::URLRequestPtr request(mojo::URLRequest::New()); |
| request->url = url_; |
| request->auto_follow_redirects = true; |
| |
| // |loader| will be pass to the OnResponseReceived method through a |
| // callback. Because order of evaluation is undefined, a reference to the |
| // raw pointer is needed. |
| mojo::URLLoader* raw_loader = loader.get(); |
| raw_loader->Start( |
| request.Pass(), |
| base::Bind(&HTMLViewerApplication::OnResponseReceived, |
| base::Unretained(this), base::Passed(&loader), |
| base::Passed(&services))); |
| } |
| } |
| |
| private: |
| void OnResponseReceived(URLLoaderPtr loader, |
| InterfaceRequest<ServiceProvider> services, |
| URLResponsePtr response) { |
| new HTMLDocument(services.Pass(), response.Pass(), shell_.get(), |
| compositor_thread_, web_media_player_factory_); |
| } |
| |
| String url_; |
| ShellPtr shell_; |
| mojo::NetworkServicePtr network_service_; |
| URLResponsePtr initial_response_; |
| scoped_refptr<base::MessageLoopProxy> compositor_thread_; |
| WebMediaPlayerFactory* web_media_player_factory_; |
| }; |
| |
| class ContentHandlerImpl : public mojo::InterfaceImpl<ContentHandler> { |
| public: |
| ContentHandlerImpl(scoped_refptr<base::MessageLoopProxy> compositor_thread, |
| WebMediaPlayerFactory* web_media_player_factory) |
| : compositor_thread_(compositor_thread), |
| web_media_player_factory_(web_media_player_factory) {} |
| ~ContentHandlerImpl() override {} |
| |
| private: |
| // Overridden from ContentHandler: |
| void StartApplication(ShellPtr shell, URLResponsePtr response) override { |
| new HTMLViewerApplication(shell.Pass(), response.Pass(), compositor_thread_, |
| web_media_player_factory_); |
| } |
| |
| scoped_refptr<base::MessageLoopProxy> compositor_thread_; |
| WebMediaPlayerFactory* web_media_player_factory_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ContentHandlerImpl); |
| }; |
| |
| class HTMLViewer : public mojo::ApplicationDelegate, |
| public mojo::InterfaceFactory<ContentHandler> { |
| public: |
| HTMLViewer() : compositor_thread_("compositor thread") {} |
| |
| ~HTMLViewer() override { blink::shutdown(); } |
| |
| private: |
| // Overridden from ApplicationDelegate: |
| void Initialize(mojo::ApplicationImpl* app) override { |
| blink_platform_.reset(new MojoBlinkPlatformImpl(app)); |
| #if defined(V8_USE_EXTERNAL_STARTUP_DATA) |
| gin::IsolateHolder::LoadV8Snapshot(); |
| #endif |
| blink::initialize(blink_platform_.get()); |
| #if !defined(COMPONENT_BUILD) |
| base::i18n::InitializeICU(); |
| |
| ui::RegisterPathProvider(); |
| |
| base::FilePath ui_test_pak_path; |
| CHECK(PathService::Get(ui::UI_TEST_PAK, &ui_test_pak_path)); |
| ui::ResourceBundle::InitSharedInstanceWithPakPath(ui_test_pak_path); |
| #endif |
| |
| base::CommandLine::StringVector command_line_args; |
| #if defined(OS_WIN) |
| for (const auto& arg : app->args()) |
| command_line_args.push_back(base::UTF8ToUTF16(arg)); |
| #elif defined(OS_POSIX) |
| command_line_args = app->args(); |
| #endif |
| |
| base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
| command_line->InitFromArgv(command_line_args); |
| |
| logging::LoggingSettings settings; |
| settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; |
| logging::InitLogging(settings); |
| // Display process ID, thread ID and timestamp in logs. |
| logging::SetLogItems(true, true, true, false); |
| |
| bool enable_mojo_media_renderer = |
| command_line->HasSwitch(kEnableMojoMediaRenderer); |
| |
| if (command_line->HasSwitch(kEnableEncryptedMedia)) |
| blink::WebRuntimeFeatures::enableEncryptedMedia(true); |
| |
| compositor_thread_.Start(); |
| web_media_player_factory_.reset(new WebMediaPlayerFactory( |
| compositor_thread_.message_loop_proxy(), enable_mojo_media_renderer)); |
| } |
| |
| bool ConfigureIncomingConnection(ApplicationConnection* connection) override { |
| connection->AddService(this); |
| return true; |
| } |
| |
| // Overridden from InterfaceFactory<ContentHandler> |
| void Create(ApplicationConnection* connection, |
| mojo::InterfaceRequest<ContentHandler> request) override { |
| BindToRequest( |
| new ContentHandlerImpl(compositor_thread_.message_loop_proxy(), |
| web_media_player_factory_.get()), |
| &request); |
| } |
| |
| scoped_ptr<MojoBlinkPlatformImpl> blink_platform_; |
| base::Thread compositor_thread_; |
| scoped_ptr<WebMediaPlayerFactory> web_media_player_factory_; |
| |
| DISALLOW_COPY_AND_ASSIGN(HTMLViewer); |
| }; |
| |
| } // namespace html_viewer |
| |
| MojoResult MojoMain(MojoHandle shell_handle) { |
| mojo::ApplicationRunnerChromium runner(new html_viewer::HTMLViewer); |
| return runner.Run(shell_handle); |
| } |