// Copyright (c) 2015 The Chromium Embedded Framework 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 "tests/cefclient/browser/root_window_manager.h" #include #include "include/base/cef_bind.h" #include "include/base/cef_logging.h" #include "include/wrapper/cef_helpers.h" #include "tests/cefclient/browser/main_context.h" #include "tests/cefclient/browser/test_runner.h" #include "tests/shared/browser/resource_util.h" #include "tests/shared/common/client_switches.h" namespace client { namespace { class ClientRequestContextHandler : public CefRequestContextHandler { public: ClientRequestContextHandler() {} bool OnBeforePluginLoad(const CefString& mime_type, const CefString& plugin_url, bool is_main_frame, const CefString& top_origin_url, CefRefPtr plugin_info, PluginPolicy* plugin_policy) OVERRIDE { // Always allow the PDF plugin to load. if (*plugin_policy != PLUGIN_POLICY_ALLOW && mime_type == "application/pdf") { *plugin_policy = PLUGIN_POLICY_ALLOW; return true; } return false; } private: IMPLEMENT_REFCOUNTING(ClientRequestContextHandler); }; } // namespace RootWindowManager::RootWindowManager(bool terminate_when_all_windows_closed) : terminate_when_all_windows_closed_(terminate_when_all_windows_closed) { CefRefPtr command_line = CefCommandLine::GetGlobalCommandLine(); DCHECK(command_line.get()); request_context_per_browser_ = command_line->HasSwitch(switches::kRequestContextPerBrowser); request_context_shared_cache_ = command_line->HasSwitch(switches::kRequestContextSharedCache); } RootWindowManager::~RootWindowManager() { // All root windows should already have been destroyed. DCHECK(root_windows_.empty()); } scoped_refptr RootWindowManager::CreateRootWindow( bool with_controls, bool with_osr, const CefRect& bounds, const std::string& url) { CefBrowserSettings settings; MainContext::Get()->PopulateBrowserSettings(&settings); scoped_refptr root_window = RootWindow::Create(MainContext::Get()->UseViews()); root_window->Init(this, with_controls, with_osr, bounds, settings, url.empty() ? MainContext::Get()->GetMainURL() : url); // Store a reference to the root window on the main thread. OnRootWindowCreated(root_window); return root_window; } scoped_refptr RootWindowManager::CreateRootWindowAsPopup( bool with_controls, bool with_osr, const CefPopupFeatures& popupFeatures, CefWindowInfo& windowInfo, CefRefPtr& client, CefBrowserSettings& settings) { MainContext::Get()->PopulateBrowserSettings(&settings); scoped_refptr root_window = RootWindow::Create(MainContext::Get()->UseViews()); root_window->InitAsPopup(this, with_controls, with_osr, popupFeatures, windowInfo, client, settings); // Store a reference to the root window on the main thread. OnRootWindowCreated(root_window); return root_window; } scoped_refptr RootWindowManager::GetWindowForBrowser( int browser_id) { REQUIRE_MAIN_THREAD(); RootWindowSet::const_iterator it = root_windows_.begin(); for (; it != root_windows_.end(); ++it) { CefRefPtr browser = (*it)->GetBrowser(); if (browser.get() && browser->GetIdentifier() == browser_id) return *it; } return NULL; } void RootWindowManager::CloseAllWindows(bool force) { if (!CURRENTLY_ON_MAIN_THREAD()) { // Execute this method on the main thread. MAIN_POST_CLOSURE( base::Bind(&RootWindowManager::CloseAllWindows, base::Unretained(this), force)); return; } if (root_windows_.empty()) return; RootWindowSet::const_iterator it = root_windows_.begin(); for (; it != root_windows_.end(); ++it) (*it)->Close(force); } void RootWindowManager::OnRootWindowCreated( scoped_refptr root_window) { if (!CURRENTLY_ON_MAIN_THREAD()) { // Execute this method on the main thread. MAIN_POST_CLOSURE( base::Bind(&RootWindowManager::OnRootWindowCreated, base::Unretained(this), root_window)); return; } root_windows_.insert(root_window); } CefRefPtr RootWindowManager::GetRequestContext( RootWindow* root_window) { REQUIRE_MAIN_THREAD(); if (request_context_per_browser_) { // Create a new request context for each browser. CefRequestContextSettings settings; CefRefPtr command_line = CefCommandLine::GetGlobalCommandLine(); if (command_line->HasSwitch(switches::kCachePath)) { if (request_context_shared_cache_) { // Give each browser the same cache path. The resulting context objects // will share the same storage internally. CefString(&settings.cache_path) = command_line->GetSwitchValue(switches::kCachePath); } else { // Give each browser a unique cache path. This will create completely // isolated context objects. std::stringstream ss; ss << command_line->GetSwitchValue(switches::kCachePath).ToString() << time(NULL); CefString(&settings.cache_path) = ss.str(); } } return CefRequestContext::CreateContext(settings, new ClientRequestContextHandler); } // All browsers will share the global request context. if (!shared_request_context_.get()) { shared_request_context_ = CefRequestContext::CreateContext(CefRequestContext::GetGlobalContext(), new ClientRequestContextHandler); } return shared_request_context_; } CefRefPtr RootWindowManager::GetDefaultWindowIcon() { REQUIRE_MAIN_THREAD(); if (!default_window_icon_) { // Create the Image and load resources at different scale factors. default_window_icon_ = LoadImageIcon("window_icon"); } return default_window_icon_; } void RootWindowManager::OnTest(RootWindow* root_window, int test_id) { REQUIRE_MAIN_THREAD(); test_runner::RunTest(root_window->GetBrowser(), test_id); } void RootWindowManager::OnExit(RootWindow* root_window) { REQUIRE_MAIN_THREAD(); CloseAllWindows(false); } void RootWindowManager::OnRootWindowDestroyed(RootWindow* root_window) { REQUIRE_MAIN_THREAD(); RootWindowSet::iterator it = root_windows_.find(root_window); DCHECK(it != root_windows_.end()); if (it != root_windows_.end()) root_windows_.erase(it); if (terminate_when_all_windows_closed_ && root_windows_.empty()) { // Quit the main message loop after all windows have closed. MainMessageLoop::Get()->Quit(); } } } // namespace client