blob: 55706e74279e029384a89b6a88b393c2b5fb08e5 [file] [log] [blame]
/*
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef COBALT_BROWSER_WEB_MODULE_H_
#define COBALT_BROWSER_WEB_MODULE_H_
#include <string>
#include <vector>
#include "base/callback.h"
#include "base/file_path.h"
#include "base/hash_tables.h"
#include "base/message_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "base/threading/thread_checker.h"
#include "cobalt/base/address_sanitizer.h"
#include "cobalt/base/console_commands.h"
#include "cobalt/base/source_location.h"
#include "cobalt/css_parser/parser.h"
#if defined(ENABLE_DEBUG_CONSOLE)
#include "cobalt/debug/debug_server.h"
#include "cobalt/debug/render_overlay.h"
#endif // ENABLE_DEBUG_CONSOLE
#include "cobalt/dom/csp_delegate.h"
#include "cobalt/dom/dom_settings.h"
#include "cobalt/dom/keyboard_event.h"
#include "cobalt/dom/local_storage_database.h"
#include "cobalt/dom/media_source.h"
#include "cobalt/dom/window.h"
#include "cobalt/dom_parser/parser.h"
#include "cobalt/layout/layout_manager.h"
#include "cobalt/loader/fetcher_factory.h"
#include "cobalt/math/size.h"
#include "cobalt/media/media_module.h"
#include "cobalt/network/network_module.h"
#include "cobalt/render_tree/resource_provider.h"
#include "cobalt/script/global_environment.h"
#include "cobalt/script/javascript_engine.h"
#include "cobalt/script/script_runner.h"
#include "cobalt/webdriver/session_driver.h"
#include "googleurl/src/gurl.h"
namespace cobalt {
namespace browser {
// WebModule hosts all components of Cobalt that deal with or implement the
// WebAPI. This includes the ability to fetch resources given a URL, parse
// various web formats like HTML and CSS, host a DOM tree, manage a JavaScript
// engine, and lay out a web page. Ultimately, interaction with WebModule is
// done through calls to InjectEvent() such as when dealing with external input
// (e.g. keyboards and gamepads), and handling render tree output from WebModule
// when it calls the on_render_tree_produced_ callback (provided upon
// construction).
// At creation, the WebModule starts a dedicated thread, on which a private
// implementation object is construted that manages all internal components.
// All methods of the WebModule post tasks to the implementation object on that
// thread, so all internal functions are executed synchronously with respect to
// each other.
// This necessarily implies that details contained within WebModule, such as the
// DOM, are intentionally kept private, since these structures expect to be
// accessed from only one thread.
class WebModule {
public:
struct Options {
typedef base::Callback<scoped_refptr<script::Wrappable>()>
CreateObjectFunction;
typedef base::hash_map<std::string, CreateObjectFunction>
InjectedWindowAttributes;
// All optional parameters defined in this structure should have their
// values initialized in the default constructor to useful defaults.
Options();
// The name of the WebModule. This is useful for debugging purposes as in
// the case where multiple WebModule objects exist, it can be used to
// differentiate which objects belong to which WebModule. It is used
// to name some CVals.
std::string name;
// The LayoutTrigger parameter dictates when a layout should be triggered.
// Tests will often set this up so that layouts are only performed when
// we specifically request them to be.
layout::LayoutManager::LayoutTrigger layout_trigger;
// Optional directory to add to the search path for web files (file://).
FilePath extra_web_file_dir;
// The navigation_callback functor will be called when JavaScript internal
// to the WebModule requests a page navigation, e.g. by modifying
// 'window.location.href'.
base::Callback<void(const GURL&)> navigation_callback;
// A list of callbacks to be called once the web page finishes loading.
std::vector<base::Closure> loaded_callbacks;
// injected_window_attributes contains a map of attributes to be injected
// into the WebModule's window object upon construction. This provides
// a mechanism to inject custom APIs into the WebModule object.
InjectedWindowAttributes injected_window_attributes;
// Options to customize DOMSettings.
dom::DOMSettings::Options dom_settings_options;
// Location policy to enforce, formatted as a Content Security Policy
// directive, e.g. "h5vcc-location-src 'self'"
// This is used to implement a navigation jail, so that location
// can't be changed from the whitelisted origins.
std::string location_policy;
// Image cache capaticy in bytes.
int image_cache_capacity;
// Typeface cache capacity in bytes.
int remote_typeface_cache_capacity;
// Content Security Policy enforcement mode for this web module.
dom::CspEnforcementType csp_enforcement_mode;
// Token obtained from CSP to allow creation of insecure delegates.
int csp_insecure_allowed_token;
// Whether or not the web module's stat tracker should track event stats.
bool track_event_stats;
// If set to something other than 1.0f, when a video starts to play, the
// image cache will be flushed and temporarily multiplied by this value (
// must be less than or equal to 1.0f) until the video ends. This can
// help for platforms that are low on image memory while playing a video.
float image_cache_capacity_multiplier_when_playing_video;
};
typedef layout::LayoutManager::LayoutResults LayoutResults;
typedef base::Callback<void(const LayoutResults&)>
OnRenderTreeProducedCallback;
typedef base::Callback<void(const GURL&, const std::string&)> OnErrorCallback;
WebModule(const GURL& initial_url,
const OnRenderTreeProducedCallback& render_tree_produced_callback,
const OnErrorCallback& error_callback,
const base::Closure& window_close_callback,
media::MediaModule* media_module,
network::NetworkModule* network_module,
const math::Size& window_dimensions,
render_tree::ResourceProvider* resource_provider,
float layout_refresh_rate, const Options& options = Options());
~WebModule();
// Call this to inject a keyboard event into the web module.
void InjectKeyboardEvent(const dom::KeyboardEvent::Data& event);
// Call this to execute Javascript code in this web module. The calling
// thread will block until the JavaScript has executed and the output results
// are available.
std::string ExecuteJavascript(const std::string& script_utf8,
const base::SourceLocation& script_location);
#if defined(ENABLE_WEBDRIVER)
// Creates a new webdriver::WindowDriver that interacts with the Window that
// is owned by this WebModule instance.
scoped_ptr<webdriver::WindowDriver> CreateWindowDriver(
const webdriver::protocol::WindowId& window_id);
#endif
#if defined(ENABLE_DEBUG_CONSOLE)
// Gets a reference to the debug server that interacts with this web module.
// The debug server is part of the debug server module owned by this web
// module, which is lazily created by this function if necessary.
debug::DebugServer* GetDebugServer();
#endif // ENABLE_DEBUG_CONSOLE
#if defined(COBALT_BUILD_TYPE_DEBUG)
// Non-optimized builds require a bigger stack size.
static const size_t kBaseStackSize = 2 * 1024 * 1024;
#else
static const size_t kBaseStackSize = 256 * 1024;
#endif
static const size_t kWebModuleStackSize =
kBaseStackSize + base::kAsanAdditionalStackSize;
private:
// Data required to construct a WebModule, initialized in the constructor and
// passed to |Initialize|.
struct ConstructionData {
ConstructionData(
const GURL& initial_url,
const OnRenderTreeProducedCallback& render_tree_produced_callback,
const OnErrorCallback& error_callback,
const base::Closure& window_close_callback,
media::MediaModule* media_module,
network::NetworkModule* network_module,
const math::Size& window_dimensions,
render_tree::ResourceProvider* resource_provider,
int dom_max_element_depth, float layout_refresh_rate,
const Options& options)
: initial_url(initial_url),
render_tree_produced_callback(render_tree_produced_callback),
error_callback(error_callback),
window_close_callback(window_close_callback),
media_module(media_module),
network_module(network_module),
window_dimensions(window_dimensions),
resource_provider(resource_provider),
dom_max_element_depth(dom_max_element_depth),
layout_refresh_rate(layout_refresh_rate),
options(options) {}
GURL initial_url;
OnRenderTreeProducedCallback render_tree_produced_callback;
OnErrorCallback error_callback;
const base::Closure& window_close_callback;
media::MediaModule* media_module;
network::NetworkModule* network_module;
math::Size window_dimensions;
render_tree::ResourceProvider* resource_provider;
int dom_max_element_depth;
float layout_refresh_rate;
Options options;
};
// Forward declaration of the private implementation class.
class Impl;
// Destruction observer used to safely tear down this WebModule after the
// thread has been stopped.
class DestructionObserver : public MessageLoop::DestructionObserver {
public:
explicit DestructionObserver(WebModule* web_module);
void WillDestroyCurrentMessageLoop() OVERRIDE;
private:
WebModule* web_module_;
};
// Called by the constructor to create the private implementation object and
// perform any other initialization required on the dedicated thread.
void Initialize(const ConstructionData& data);
void ClearAllIntervalsAndTimeouts();
#if defined(ENABLE_PARTIAL_LAYOUT_CONTROL)
void OnPartialLayoutConsoleCommandReceived(const std::string& message);
#endif // defined(ENABLE_PARTIAL_LAYOUT_CONTROL)
// The message loop this object is running on.
MessageLoop* message_loop() const { return thread_.message_loop(); }
// Private implementation object.
scoped_ptr<Impl> impl_;
// The thread created and owned by this WebModule.
// All sub-objects of this object are created on this thread, and all public
// member functions are re-posted to this thread if necessary.
base::Thread thread_;
#if defined(ENABLE_PARTIAL_LAYOUT_CONTROL)
// Handles the 'partial_layout' command.
scoped_ptr<base::ConsoleCommandManager::CommandHandler>
partial_layout_command_handler_;
#endif // defined(ENABLE_PARTIAL_LAYOUT_CONTROL)
};
} // namespace browser
} // namespace cobalt
#endif // COBALT_BROWSER_WEB_MODULE_H_