1 // Copyright (c) 2012 The Chromium Embedded Framework Authors.
2 // Portions copyright (c) 2011 The Chromium Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5
6 #include "include/cef_browser.h"
7 #include "libcef/browser/alloy/alloy_browser_host_impl.h"
8 #include "libcef/browser/chrome/chrome_browser_host_impl.h"
9 #include "libcef/browser/context.h"
10 #include "libcef/browser/thread_util.h"
11 #include "libcef/features/runtime.h"
12
13 namespace {
14
15 class CreateBrowserHelper {
16 public:
CreateBrowserHelper(const CefWindowInfo & windowInfo,CefRefPtr<CefClient> client,const CefString & url,const CefBrowserSettings & settings,CefRefPtr<CefDictionaryValue> extra_info,CefRefPtr<CefRequestContext> request_context)17 CreateBrowserHelper(const CefWindowInfo& windowInfo,
18 CefRefPtr<CefClient> client,
19 const CefString& url,
20 const CefBrowserSettings& settings,
21 CefRefPtr<CefDictionaryValue> extra_info,
22 CefRefPtr<CefRequestContext> request_context)
23 : window_info_(windowInfo),
24 client_(client),
25 url_(url),
26 settings_(settings),
27 extra_info_(extra_info),
28 request_context_(request_context) {}
29
Run()30 void Run() {
31 CefBrowserHost::CreateBrowserSync(window_info_, client_, url_, settings_,
32 extra_info_, request_context_);
33 }
34
35 CefWindowInfo window_info_;
36 CefRefPtr<CefClient> client_;
37 CefString url_;
38 CefBrowserSettings settings_;
39 CefRefPtr<CefDictionaryValue> extra_info_;
40 CefRefPtr<CefRequestContext> request_context_;
41 };
42
43 } // namespace
44
45 // static
CreateBrowser(const CefWindowInfo & windowInfo,CefRefPtr<CefClient> client,const CefString & url,const CefBrowserSettings & settings,CefRefPtr<CefDictionaryValue> extra_info,CefRefPtr<CefRequestContext> request_context)46 bool CefBrowserHost::CreateBrowser(
47 const CefWindowInfo& windowInfo,
48 CefRefPtr<CefClient> client,
49 const CefString& url,
50 const CefBrowserSettings& settings,
51 CefRefPtr<CefDictionaryValue> extra_info,
52 CefRefPtr<CefRequestContext> request_context) {
53 // Verify that the context is in a valid state.
54 if (!CONTEXT_STATE_VALID()) {
55 NOTREACHED() << "context not valid";
56 return false;
57 }
58
59 // Verify that the settings structure is a valid size.
60 if (settings.size != sizeof(cef_browser_settings_t)) {
61 NOTREACHED() << "invalid CefBrowserSettings structure size";
62 return false;
63 }
64
65 // Verify windowless rendering requirements.
66 if (windowInfo.windowless_rendering_enabled &&
67 !client->GetRenderHandler().get()) {
68 NOTREACHED() << "CefRenderHandler implementation is required";
69 return false;
70 }
71
72 if (windowInfo.windowless_rendering_enabled &&
73 !CefContext::Get()->settings().windowless_rendering_enabled) {
74 LOG(ERROR) << "Creating a windowless browser without setting "
75 "CefSettings.windowless_rendering_enabled may result in "
76 "reduced performance or runtime errors.";
77 }
78
79 if (!request_context) {
80 request_context = CefRequestContext::GetGlobalContext();
81 }
82
83 auto helper = std::make_unique<CreateBrowserHelper>(
84 windowInfo, client, url, settings, extra_info, request_context);
85
86 auto request_context_impl =
87 static_cast<CefRequestContextImpl*>(request_context.get());
88
89 // Wait for the browser context to be initialized before creating the browser.
90 request_context_impl->ExecuteWhenBrowserContextInitialized(base::BindOnce(
91 [](std::unique_ptr<CreateBrowserHelper> helper) {
92 // Always execute asynchronously to avoid potential issues if we're
93 // being called synchronously during app initialization.
94 CEF_POST_TASK(CEF_UIT, base::BindOnce(&CreateBrowserHelper::Run,
95 std::move(helper)));
96 },
97 std::move(helper)));
98
99 return true;
100 }
101
102 // static
CreateBrowserSync(const CefWindowInfo & windowInfo,CefRefPtr<CefClient> client,const CefString & url,const CefBrowserSettings & settings,CefRefPtr<CefDictionaryValue> extra_info,CefRefPtr<CefRequestContext> request_context)103 CefRefPtr<CefBrowser> CefBrowserHost::CreateBrowserSync(
104 const CefWindowInfo& windowInfo,
105 CefRefPtr<CefClient> client,
106 const CefString& url,
107 const CefBrowserSettings& settings,
108 CefRefPtr<CefDictionaryValue> extra_info,
109 CefRefPtr<CefRequestContext> request_context) {
110 // Verify that the context is in a valid state.
111 if (!CONTEXT_STATE_VALID()) {
112 NOTREACHED() << "context not valid";
113 return nullptr;
114 }
115
116 // Verify that the settings structure is a valid size.
117 if (settings.size != sizeof(cef_browser_settings_t)) {
118 NOTREACHED() << "invalid CefBrowserSettings structure size";
119 return nullptr;
120 }
121
122 if (!request_context) {
123 request_context = CefRequestContext::GetGlobalContext();
124 }
125
126 // Verify that the browser context is valid.
127 auto request_context_impl =
128 static_cast<CefRequestContextImpl*>(request_context.get());
129 if (!request_context_impl->VerifyBrowserContext()) {
130 return nullptr;
131 }
132
133 // Verify windowless rendering requirements.
134 if (windowInfo.windowless_rendering_enabled &&
135 !client->GetRenderHandler().get()) {
136 NOTREACHED() << "CefRenderHandler implementation is required";
137 return nullptr;
138 }
139
140 CefBrowserCreateParams create_params;
141 create_params.window_info.reset(new CefWindowInfo(windowInfo));
142 create_params.client = client;
143 create_params.url = url;
144 create_params.settings = settings;
145 create_params.extra_info = extra_info;
146 create_params.request_context = request_context;
147
148 return CefBrowserHostBase::Create(create_params);
149 }
150
151 // static
Create(CefBrowserCreateParams & create_params)152 CefRefPtr<CefBrowserHostBase> CefBrowserHostBase::Create(
153 CefBrowserCreateParams& create_params) {
154 if (cef::IsChromeRuntimeEnabled()) {
155 auto browser = ChromeBrowserHostImpl::Create(create_params);
156 return browser.get();
157 }
158
159 auto browser = AlloyBrowserHostImpl::Create(create_params);
160 return browser.get();
161 }
162