• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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