1 // Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that
3 // can be found in the LICENSE file.
4
5 #include "tests/cefsimple/simple_handler.h"
6
7 #include <sstream>
8 #include <string>
9
10 #include "include/base/cef_callback.h"
11 #include "include/cef_app.h"
12 #include "include/cef_parser.h"
13 #include "include/views/cef_browser_view.h"
14 #include "include/views/cef_window.h"
15 #include "include/wrapper/cef_closure_task.h"
16 #include "include/wrapper/cef_helpers.h"
17
18 namespace {
19
20 SimpleHandler* g_instance = nullptr;
21
22 // Returns a data: URI with the specified contents.
GetDataURI(const std::string & data,const std::string & mime_type)23 std::string GetDataURI(const std::string& data, const std::string& mime_type) {
24 return "data:" + mime_type + ";base64," +
25 CefURIEncode(CefBase64Encode(data.data(), data.size()), false)
26 .ToString();
27 }
28
29 } // namespace
30
SimpleHandler(bool use_views)31 SimpleHandler::SimpleHandler(bool use_views)
32 : use_views_(use_views), is_closing_(false) {
33 DCHECK(!g_instance);
34 g_instance = this;
35 }
36
~SimpleHandler()37 SimpleHandler::~SimpleHandler() {
38 g_instance = nullptr;
39 }
40
41 // static
GetInstance()42 SimpleHandler* SimpleHandler::GetInstance() {
43 return g_instance;
44 }
45
OnTitleChange(CefRefPtr<CefBrowser> browser,const CefString & title)46 void SimpleHandler::OnTitleChange(CefRefPtr<CefBrowser> browser,
47 const CefString& title) {
48 CEF_REQUIRE_UI_THREAD();
49
50 if (use_views_) {
51 // Set the title of the window using the Views framework.
52 CefRefPtr<CefBrowserView> browser_view =
53 CefBrowserView::GetForBrowser(browser);
54 if (browser_view) {
55 CefRefPtr<CefWindow> window = browser_view->GetWindow();
56 if (window)
57 window->SetTitle(title);
58 }
59 } else if (!IsChromeRuntimeEnabled()) {
60 // Set the title of the window using platform APIs.
61 PlatformTitleChange(browser, title);
62 }
63 }
64
OnAfterCreated(CefRefPtr<CefBrowser> browser)65 void SimpleHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
66 CEF_REQUIRE_UI_THREAD();
67
68 // Add to the list of existing browsers.
69 browser_list_.push_back(browser);
70 }
71
DoClose(CefRefPtr<CefBrowser> browser)72 bool SimpleHandler::DoClose(CefRefPtr<CefBrowser> browser) {
73 CEF_REQUIRE_UI_THREAD();
74
75 // Closing the main window requires special handling. See the DoClose()
76 // documentation in the CEF header for a detailed destription of this
77 // process.
78 if (browser_list_.size() == 1) {
79 // Set a flag to indicate that the window close should be allowed.
80 is_closing_ = true;
81 }
82
83 // Allow the close. For windowed browsers this will result in the OS close
84 // event being sent.
85 return false;
86 }
87
OnBeforeClose(CefRefPtr<CefBrowser> browser)88 void SimpleHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
89 CEF_REQUIRE_UI_THREAD();
90
91 // Remove from the list of existing browsers.
92 BrowserList::iterator bit = browser_list_.begin();
93 for (; bit != browser_list_.end(); ++bit) {
94 if ((*bit)->IsSame(browser)) {
95 browser_list_.erase(bit);
96 break;
97 }
98 }
99
100 if (browser_list_.empty()) {
101 // All browser windows have closed. Quit the application message loop.
102 CefQuitMessageLoop();
103 }
104 }
105
OnLoadError(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,ErrorCode errorCode,const CefString & errorText,const CefString & failedUrl)106 void SimpleHandler::OnLoadError(CefRefPtr<CefBrowser> browser,
107 CefRefPtr<CefFrame> frame,
108 ErrorCode errorCode,
109 const CefString& errorText,
110 const CefString& failedUrl) {
111 CEF_REQUIRE_UI_THREAD();
112
113 // Allow Chrome to show the error page.
114 if (IsChromeRuntimeEnabled())
115 return;
116
117 // Don't display an error for downloaded files.
118 if (errorCode == ERR_ABORTED)
119 return;
120
121 // Display a load error message using a data: URI.
122 std::stringstream ss;
123 ss << "<html><body bgcolor=\"white\">"
124 "<h2>Failed to load URL "
125 << std::string(failedUrl) << " with error " << std::string(errorText)
126 << " (" << errorCode << ").</h2></body></html>";
127
128 frame->LoadURL(GetDataURI(ss.str(), "text/html"));
129 }
130
CloseAllBrowsers(bool force_close)131 void SimpleHandler::CloseAllBrowsers(bool force_close) {
132 if (!CefCurrentlyOn(TID_UI)) {
133 // Execute on the UI thread.
134 CefPostTask(TID_UI, base::BindOnce(&SimpleHandler::CloseAllBrowsers, this,
135 force_close));
136 return;
137 }
138
139 if (browser_list_.empty())
140 return;
141
142 BrowserList::const_iterator it = browser_list_.begin();
143 for (; it != browser_list_.end(); ++it)
144 (*it)->GetHost()->CloseBrowser(force_close);
145 }
146
147 // static
IsChromeRuntimeEnabled()148 bool SimpleHandler::IsChromeRuntimeEnabled() {
149 static int value = -1;
150 if (value == -1) {
151 CefRefPtr<CefCommandLine> command_line =
152 CefCommandLine::GetGlobalCommandLine();
153 value = command_line->HasSwitch("enable-chrome-runtime") ? 1 : 0;
154 }
155 return value == 1;
156 }
157