| // Copyright 2014 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_BROWSER_MODULE_H_ |
| #define COBALT_BROWSER_BROWSER_MODULE_H_ |
| |
| #include <string> |
| #include <vector> |
| |
| #include "base/memory/scoped_ptr.h" |
| #include "base/observer_list.h" |
| #include "base/synchronization/lock.h" |
| #include "base/synchronization/waitable_event.h" |
| #include "base/threading/thread.h" |
| #include "base/timer.h" |
| #include "cobalt/account/account_manager.h" |
| #include "cobalt/base/application_state.h" |
| #include "cobalt/base/message_queue.h" |
| #include "cobalt/browser/h5vcc_url_handler.h" |
| #include "cobalt/browser/lifecycle_observer.h" |
| #include "cobalt/browser/memory_settings/auto_mem.h" |
| #include "cobalt/browser/memory_settings/checker.h" |
| #include "cobalt/browser/render_tree_combiner.h" |
| #include "cobalt/browser/screen_shot_writer.h" |
| #include "cobalt/browser/splash_screen.h" |
| #include "cobalt/browser/suspend_fuzzer.h" |
| #include "cobalt/browser/system_platform_error_handler.h" |
| #include "cobalt/browser/url_handler.h" |
| #include "cobalt/browser/web_module.h" |
| #include "cobalt/dom/array_buffer.h" |
| #include "cobalt/dom/keyboard_event_init.h" |
| #include "cobalt/dom/pointer_event_init.h" |
| #include "cobalt/dom/wheel_event_init.h" |
| #include "cobalt/input/input_device_manager.h" |
| #include "cobalt/layout/layout_manager.h" |
| #include "cobalt/network/network_module.h" |
| #include "cobalt/render_tree/resource_provider.h" |
| #include "cobalt/render_tree/resource_provider_stub.h" |
| #include "cobalt/renderer/renderer_module.h" |
| #include "cobalt/storage/storage_manager.h" |
| #include "cobalt/system_window/system_window.h" |
| #include "cobalt/webdriver/session_driver.h" |
| #include "googleurl/src/gurl.h" |
| #if defined(ENABLE_DEBUG_CONSOLE) |
| #include "cobalt/base/console_commands.h" |
| #include "cobalt/browser/debug_console.h" |
| #include "cobalt/browser/trace_manager.h" |
| #include "cobalt/debug/debug_server.h" |
| #endif // ENABLE_DEBUG_CONSOLE |
| #include "starboard/configuration.h" |
| |
| namespace cobalt { |
| namespace browser { |
| |
| // BrowserModule hosts all major components of the Cobalt browser application. |
| // It also contains all of the glue components required to connect the |
| // different subsystems together. |
| class BrowserModule { |
| public: |
| // All browser subcomponent options should have default constructors that |
| // setup reasonable default options. |
| struct Options { |
| explicit Options(const WebModule::Options& web_options) |
| : web_module_options(web_options), |
| command_line_auto_mem_settings( |
| memory_settings::AutoMemSettings::kTypeCommandLine), |
| build_auto_mem_settings( |
| memory_settings::AutoMemSettings::kTypeBuild) {} |
| network::NetworkModule::Options network_module_options; |
| renderer::RendererModule::Options renderer_module_options; |
| storage::StorageManager::Options storage_manager_options; |
| WebModule::Options web_module_options; |
| media::MediaModule::Options media_module_options; |
| std::string language; |
| std::string initial_deep_link; |
| base::Closure web_module_recreated_callback; |
| memory_settings::AutoMemSettings command_line_auto_mem_settings; |
| memory_settings::AutoMemSettings build_auto_mem_settings; |
| base::optional<GURL> fallback_splash_screen_url; |
| base::optional<math::Size> requested_viewport_size; |
| }; |
| |
| // Type for a collection of URL handler callbacks that can potentially handle |
| // a URL before using it to initialize a new WebModule. |
| typedef std::vector<URLHandler::URLHandlerCallback> URLHandlerCollection; |
| |
| BrowserModule(const GURL& url, |
| base::ApplicationState initial_application_state, |
| base::EventDispatcher* event_dispatcher, |
| account::AccountManager* account_manager, |
| const Options& options); |
| ~BrowserModule(); |
| |
| const std::string& GetUserAgent() { return network_module_.GetUserAgent(); } |
| |
| // Recreates web module with the given URL. In the case where Cobalt is |
| // currently suspended, this defers the navigation and instead sets |
| // |pending_navigate_url_| to the specified url, which will trigger a |
| // navigation when Cobalt resumes. |
| void Navigate(const GURL& url); |
| // Reloads web module. |
| void Reload(); |
| |
| SystemPlatformErrorHandler* system_platform_error_handler() { |
| return &system_platform_error_handler_; |
| } |
| |
| // Adds/removes a URL handler. |
| void AddURLHandler(const URLHandler::URLHandlerCallback& callback); |
| void RemoveURLHandler(const URLHandler::URLHandlerCallback& callback); |
| |
| #if defined(ENABLE_SCREENSHOT) |
| // Request a screenshot to be written to the specified path. Callback will |
| // be fired after the screenshot has been written to disk. |
| void RequestScreenshotToFile(const FilePath& path, |
| const base::Closure& done_cb); |
| |
| // Request a screenshot to an in-memory buffer. |
| void RequestScreenshotToBuffer( |
| const ScreenShotWriter::PNGEncodeCompleteCallback& screenshot_ready); |
| #endif |
| |
| #if defined(ENABLE_WEBDRIVER) |
| scoped_ptr<webdriver::SessionDriver> CreateSessionDriver( |
| const webdriver::protocol::SessionId& session_id); |
| #endif |
| |
| #if defined(ENABLE_DEBUG_CONSOLE) |
| debug::DebugServer* GetDebugServer(); |
| void GetDebugServerInternal(debug::DebugServer** out_debug_server); |
| #endif // ENABLE_DEBUG_CONSOLE |
| |
| // Change the network proxy settings while the application is running. |
| void SetProxy(const std::string& proxy_rules); |
| |
| // LifecycleObserver-similar interface. |
| void Start(); |
| void Pause(); |
| void Unpause(); |
| void Suspend(); |
| void Resume(); |
| |
| // Attempt to reduce overall memory consumption. Called in response to a |
| // system indication that memory usage is nearing a critical level. |
| void ReduceMemory(); |
| |
| void CheckMemory(const int64_t& used_cpu_memory, |
| const base::optional<int64_t>& used_gpu_memory); |
| |
| private: |
| #if SB_HAS(CORE_DUMP_HANDLER_SUPPORT) |
| static void CoreDumpHandler(void* browser_module_as_void); |
| int on_error_triggered_count_; |
| #if defined(COBALT_CHECK_RENDER_TIMEOUT) |
| int recovery_mechanism_triggered_count_; |
| int timeout_response_trigger_count_; |
| #endif // defined(COBALT_CHECK_RENDER_TIMEOUT) |
| #endif // SB_HAS(CORE_DUMP_HANDLER_SUPPORT) |
| |
| // Called when the WebModule's Window.onload event is fired. |
| void OnLoad(); |
| |
| // Wait for the onload event to be fired with the specified timeout. If the |
| // webmodule is not currently loading the document, this will return |
| // immediately. |
| bool WaitForLoad(const base::TimeDelta& timeout); |
| |
| // Glue function to deal with the production of the main render tree, |
| // and will manage handing it off to the renderer. |
| void QueueOnRenderTreeProduced( |
| int web_module_generation, |
| const browser::WebModule::LayoutResults& layout_results); |
| void OnRenderTreeProduced( |
| int web_module_generation, |
| const browser::WebModule::LayoutResults& layout_results); |
| |
| // Glue function to deal with the production of the splash screen render tree, |
| // and will manage handing it off to the renderer. |
| void QueueOnSplashScreenRenderTreeProduced( |
| const browser::WebModule::LayoutResults& layout_results); |
| void OnSplashScreenRenderTreeProduced( |
| const browser::WebModule::LayoutResults& layout_results); |
| |
| // Saves/loads the debug console mode to/from local storage so we can |
| // persist the user's preference. |
| void SaveDebugConsoleMode(); |
| |
| // Glue function to deal with the production of a keyboard input event from a |
| // keyboard input device, and manage handing it off to the web module for |
| // interpretation. |
| void OnKeyEventProduced(base::Token type, |
| const dom::KeyboardEventInit& event); |
| |
| // Glue function to deal with the production of a pointer input event from a |
| // pointer input device, and manage handing it off to the web module for |
| // interpretation. |
| void OnPointerEventProduced(base::Token type, |
| const dom::PointerEventInit& event); |
| |
| // Glue function to deal with the production of a wheel input event from a |
| // wheel input device, and manage handing it off to the web module for |
| // interpretation. |
| void OnWheelEventProduced(base::Token type, const dom::WheelEventInit& event); |
| |
| // Injects a key event directly into the main web module, useful for setting |
| // up an input fuzzer whose input should be sent directly to the main |
| // web module and not filtered into the debug console. |
| void InjectKeyEventToMainWebModule(base::Token type, |
| const dom::KeyboardEventInit& event); |
| |
| // Error callback for any error that stops the program. |
| void OnError(const GURL& url, const std::string& error); |
| |
| // OnErrorRetry() runs a retry URL through the URL handlers. It should only be |
| // called by |on_error_retry_timer_|. |
| void OnErrorRetry(); |
| |
| // Filters a key event. |
| // Returns true if the event should be passed on to other handlers, |
| // false if it was consumed within this function. |
| bool FilterKeyEvent(base::Token type, const dom::KeyboardEventInit& event); |
| |
| // Filters a key event for hotkeys. |
| // Returns true if the event should be passed on to other handlers, |
| // false if it was consumed within this function. |
| bool FilterKeyEventForHotkeys(base::Token type, |
| const dom::KeyboardEventInit& event); |
| |
| // Tries all registered URL handlers for a URL. Returns true if one of the |
| // handlers handled the URL, false if otherwise. |
| bool TryURLHandlers(const GURL& url); |
| |
| // Destroys the splash screen, if currently displayed. |
| void DestroySplashScreen(base::TimeDelta close_time); |
| |
| // Called when web module has received window.close(). |
| void OnWindowClose(base::TimeDelta close_time); |
| |
| // Called when web module has received window.minimize(). |
| void OnWindowMinimize(); |
| |
| #if defined(ENABLE_DEBUG_CONSOLE) |
| // Toggles the input fuzzer on/off. Ignores the parameter. |
| void OnFuzzerToggle(const std::string&); |
| |
| // Use the config in the form of '<string name>=<int value>' to call |
| // MediaModule::SetConfiguration(). |
| void OnSetMediaConfig(const std::string& config); |
| |
| // Glue function to deal with the production of the debug console render tree, |
| // and will manage handing it off to the renderer. |
| void QueueOnDebugConsoleRenderTreeProduced( |
| const browser::WebModule::LayoutResults& layout_results); |
| void OnDebugConsoleRenderTreeProduced( |
| const browser::WebModule::LayoutResults& layout_results); |
| #endif // defined(ENABLE_DEBUG_CONSOLE) |
| |
| #if defined(ENABLE_WEBDRIVER) |
| scoped_ptr<webdriver::WindowDriver> CreateWindowDriver( |
| const webdriver::protocol::WindowId& window_id); |
| |
| void CreateWindowDriverInternal( |
| const webdriver::protocol::WindowId& window_id, |
| scoped_ptr<webdriver::WindowDriver>* out_window_driver); |
| #endif |
| |
| // Called when a renderer submission has been rasterized. Used to hide the |
| // system splash screen after the first render has completed. |
| void OnRendererSubmissionRasterized(); |
| |
| // Process all messages queued into the |render_tree_submission_queue_|. |
| void ProcessRenderTreeSubmissionQueue(); |
| |
| #if defined(COBALT_CHECK_RENDER_TIMEOUT) |
| // Poll for render timeout. Called from timeout_polling_thread_. |
| void OnPollForRenderTimeout(const GURL& url); |
| #endif |
| |
| // Gets the current resource provider. |
| render_tree::ResourceProvider* GetResourceProvider(); |
| |
| // Initializes the system window, and all components that require it. |
| void InitializeSystemWindow(); |
| |
| // Updates all components that have already been created with information |
| // resulting from the creation of the system window. |
| void UpdateFromSystemWindow(); |
| |
| // Does all the steps for either a Suspend or the first half of a Start. |
| void SuspendInternal(bool is_start); |
| |
| // Does all the steps for either a Resume or the second half of a Start that |
| // happen prior to the app state update. |
| void StartOrResumeInternalPreStateUpdate(bool is_start); |
| // Does all the steps for either a Resume or the second half of a Start that |
| // happen after the app state update. |
| void StartOrResumeInternalPostStateUpdate(); |
| |
| // Gets a viewport size to use for now. This may change depending on the |
| // current application state. While preloading, this returns the requested |
| // viewport size. If there was no requested viewport size, it returns a |
| // default viewport size of 1280x720 (720p). Once a system window is created, |
| // it returns the confirmed size of the window. |
| math::Size GetViewportSize(); |
| |
| // Applies the current AutoMem settings to all applicable submodules. |
| void ApplyAutoMemSettings(); |
| |
| // If it exists, takes the current combined render tree from |
| // |render_tree_combiner_| and submits it to the pipeline in the renderer |
| // module. |
| void SubmitCurrentRenderTreeToRenderer(); |
| |
| // TODO: |
| // WeakPtr usage here can be avoided if BrowserModule has a thread to |
| // own where it can ensure that its tasks are all resolved when it is |
| // destructed. |
| // |
| // BrowserModule provides weak pointers to itself to prevent tasks generated |
| // by its components when attempting to communicate to other components (e.g. |
| // input events being generated and passed into WebModule). By passing |
| // references to BrowserModule as WeakPtrs, we do not access invalid memory |
| // if they are processed after the BrowserModule is destroyed. |
| base::WeakPtrFactory<BrowserModule> weak_ptr_factory_; |
| // After constructing |weak_ptr_factory_| we immediately construct a WeakPtr |
| // in order to bind the BrowserModule WeakPtr object to its thread. When we |
| // need a WeakPtr, we copy construct this, which is safe to do from any |
| // thread according to weak_ptr.h (versus calling |
| // |weak_ptr_factory_.GetWeakPtr() which is not). |
| base::WeakPtr<BrowserModule> weak_this_; |
| |
| // Memory configuration tool. |
| scoped_ptr<memory_settings::AutoMem> auto_mem_; |
| |
| // A copy of the BrowserModule Options passed into the constructor. |
| Options options_; |
| |
| // The browser module runs on this message loop. |
| MessageLoop* const self_message_loop_; |
| |
| // Handler for system errors, which is owned by browser module. |
| SystemPlatformErrorHandler system_platform_error_handler_; |
| |
| // Collection of URL handlers that can potentially handle a URL before |
| // using it to initialize a new WebModule. |
| URLHandlerCollection url_handlers_; |
| |
| base::EventDispatcher* event_dispatcher_; |
| |
| storage::StorageManager storage_manager_; |
| |
| // Whether the browser module has yet rendered anything. On the very first |
| // render, we hide the system splash screen. |
| bool is_rendered_; |
| |
| // The main system window for our application. This routes input event |
| // callbacks, and provides a native window handle on desktop systems. |
| scoped_ptr<system_window::SystemWindow> system_window_; |
| |
| // Wraps input device and produces input events that can be passed into |
| // the web module. |
| scoped_ptr<input::InputDeviceManager> input_device_manager_; |
| |
| // Sets up everything to do with graphics, from backend objects like the |
| // display and graphics context to the rasterizer and rendering pipeline. |
| scoped_ptr<renderer::RendererModule> renderer_module_; |
| |
| // A stub implementation of ResourceProvider that can be used until a real |
| // ResourceProvider is created. Only valid in the Preloading state. |
| base::optional<render_tree::ResourceProviderStub> resource_provider_stub_; |
| |
| // Optional memory allocator used by ArrayBuffer. |
| scoped_ptr<dom::ArrayBuffer::Allocator> array_buffer_allocator_; |
| |
| // Optional cache used by ArrayBuffer. |
| scoped_ptr<dom::ArrayBuffer::Cache> array_buffer_cache_; |
| |
| // Controls all media playback related objects/resources. |
| scoped_ptr<media::MediaModule> media_module_; |
| |
| // Sets up the network component for requesting internet resources. |
| network::NetworkModule network_module_; |
| |
| // Manages the three render trees, combines and renders them. |
| scoped_ptr<RenderTreeCombiner> render_tree_combiner_; |
| scoped_ptr<RenderTreeCombiner::Layer> main_web_module_layer_; |
| scoped_ptr<RenderTreeCombiner::Layer> debug_console_layer_; |
| scoped_ptr<RenderTreeCombiner::Layer> splash_screen_layer_; |
| |
| #if defined(ENABLE_SCREENSHOT) |
| // Helper object to create screen shots of the last layout tree. |
| scoped_ptr<ScreenShotWriter> screen_shot_writer_; |
| #endif // defined(ENABLE_SCREENSHOT) |
| |
| // Keeps track of all messages containing render tree submissions that will |
| // ultimately reference the |render_tree_combiner_| and the |
| // |renderer_module_|. It is important that this is destroyed before the |
| // above mentioned references are. It must however outlive all WebModules |
| // that may be producing render trees. |
| base::MessageQueue render_tree_submission_queue_; |
| |
| // Sets up everything to do with web page management, from loading and |
| // parsing the web page and all referenced files to laying it out. The |
| // web module will ultimately produce a render tree that can be passed |
| // into the renderer module. |
| scoped_ptr<WebModule> web_module_; |
| |
| // Will be signalled when the WebModule's Window.onload event is fired. |
| base::WaitableEvent web_module_loaded_; |
| |
| // This will be called after the WebModule has been destroyed and recreated, |
| // which could occur on navigation. |
| base::Closure web_module_recreated_callback_; |
| |
| // The time when a URL navigation starts. This is recorded after the previous |
| // WebModule is destroyed. |
| base::CVal<int64> navigate_time_; |
| |
| // The time when the WebModule's Window.onload event is fired. |
| base::CVal<int64> on_load_event_time_; |
| |
| #if defined(ENABLE_DEBUG_CONSOLE) |
| // Possibly null, but if not, will contain a reference to an instance of |
| // a debug fuzzer input device manager. |
| scoped_ptr<input::InputDeviceManager> input_device_manager_fuzzer_; |
| |
| // Manages a second web module to implement the debug console. |
| scoped_ptr<DebugConsole> debug_console_; |
| |
| TraceManager trace_manager_; |
| |
| // Command handler object for toggling the input fuzzer on/off. |
| base::ConsoleCommandManager::CommandHandler fuzzer_toggle_command_handler_; |
| |
| // Command handler object for setting media module config. |
| base::ConsoleCommandManager::CommandHandler set_media_config_command_handler_; |
| |
| #if defined(ENABLE_SCREENSHOT) |
| // Command handler object for screenshot command from the debug console. |
| base::ConsoleCommandManager::CommandHandler screenshot_command_handler_; |
| #endif // defined(ENABLE_SCREENSHOT) |
| |
| base::optional<SuspendFuzzer> suspend_fuzzer_; |
| #endif // defined(ENABLE_DEBUG_CONSOLE) |
| |
| // Handler object for h5vcc URLs. |
| scoped_ptr<H5vccURLHandler> h5vcc_url_handler_; |
| |
| // The splash screen. The pointer wrapped here should be non-NULL iff |
| // the splash screen is currently displayed. |
| scoped_ptr<SplashScreen> splash_screen_; |
| |
| // Reset when the browser is paused, signalled to resume. |
| base::WaitableEvent has_resumed_; |
| |
| #if defined(COBALT_CHECK_RENDER_TIMEOUT) |
| base::Thread timeout_polling_thread_; |
| |
| // Counts the number of continuous render timeout expirations. This value is |
| // updated and used from OnPollForRenderTimeout. |
| int render_timeout_count_; |
| #endif |
| |
| // The URL that Cobalt will attempt to navigate to during an OnErrorRetry() |
| // and also when starting from a preloaded state or resuming from a suspended |
| // state. This url is set within OnError() and also when a navigation is |
| // deferred as a result of Cobalt being suspended; it is cleared when a |
| // navigation occurs. |
| std::string pending_navigate_url_; |
| |
| // The number of OnErrorRetry() calls that have occurred since the last |
| // OnDone() call. This is used to determine the exponential backoff delay |
| // between the call to OnError() and the timer call to OnErrorRetry(). |
| int on_error_retry_count_; |
| // The time OnErrorRetry() was last called. This is used to limit how |
| // frequently |on_error_retry_timer_| can call OnErrorRetry(). |
| base::TimeTicks on_error_retry_time_; |
| // The timer for the next call to OnErrorRetry(). It is started in OnError() |
| // when it is not already active. |
| base::OneShotTimer<BrowserModule> on_error_retry_timer_; |
| |
| // Set when the application is about to quit. May be set from a thread other |
| // than the one hosting this object, and read from another. |
| bool will_quit_; |
| |
| // The |will_quit_| flag may be set from one thread (e.g. not the one hosting |
| // this object) and read from another. This lock is used to |
| // ensure synchronous access. |
| base::Lock quit_lock_; |
| |
| // The current application state. |
| base::ApplicationState application_state_; |
| |
| // The list of LifecycleObserver that need to be managed. |
| ObserverList<LifecycleObserver> lifecycle_observers_; |
| |
| // Fires memory warning once when memory exceeds specified max cpu/gpu |
| // memory. |
| memory_settings::Checker memory_settings_checker_; |
| |
| // The fallback URL to the splash screen. If empty (the default), no splash |
| // screen will be displayed. |
| base::optional<GURL> fallback_splash_screen_url_; |
| |
| // The splash screen cache. |
| scoped_ptr<SplashScreenCache> splash_screen_cache_; |
| |
| // Number of main web modules that have take place so far, helpful for |
| // ditinguishing lingering events produced by older web modules as we switch |
| // from one to another. This is incremented with each navigation. |
| int main_web_module_generation_; |
| |
| // Keeps track of a unique next ID to be assigned to new splash screen or |
| // main web module timelines. |
| int next_timeline_id_; |
| |
| // The following values are specified on submissions sent into the renderer |
| // so that the renderer can identify when it is changing from one timeline |
| // to another (in which case it may need to clear its submission queue). |
| int current_splash_screen_timeline_id_; |
| int current_main_web_module_timeline_id_; |
| }; |
| |
| } // namespace browser |
| } // namespace cobalt |
| |
| #endif // COBALT_BROWSER_BROWSER_MODULE_H_ |