chromiumembedded/cef

chrome: Support creation of lightweight (Alloy-style) windows and browsers

magreenblatt opened this issue · 4 comments

Is your feature request related to a problem? Please describe.
Use of the Chrome or Alloy runtime must currently be configured at app startup and cannot be mixed in a single app instance. Each runtime has its own strengths and weaknesses. For example:

  • Chrome runtime supports the full Chrome UI and functionality (details).
  • Alloy runtime supports off-screen rendering, client-provided parent windows, and some callbacks that are missing with the Chrome runtime (issues).

Describe the solution you'd like
Start with the Chrome runtime. Add the ability to create lightweight (Alloy-style) windows and browsers that behave the same as existing Alloy windows/browsers. This would include support for the following:

  • Off-screen rendering with Chrome runtime via Alloy-style browser (issue #3293).
  • Client-provided parent windows with Chrome runtime via Alloy-style browser (issue #3294).
  • Multiple browsers in a single Chrome window (1 Chrome browser + multiple Alloy-style browsers). For example, the Alloy-style browsers might contain web-based controls separate from the main browser view (with different CefRequestContext, etc).

Additional context
Chrome runtime bootstrap means that all global objects and CefRequestContext (Profile) will be Chrome objects. For Alloy-style we will create Widget and WebContents objects directly (like with current Alloy runtime) and modify the existing Alloy implementations to work with Chrome global objects. This can be done in stages:

  1. Use per-browser/window state instead of global IsChromeRuntimeEnabled/IsAlloyRuntimeEnabled functions.
  2. Add argument to CefBrowserHost/CefWindow creation to specify Chrome or Alloy style. Chrome style windows can contain Alloy style browsers, but not visa-versa. Some of this behavior may be implicit (for example, always create Alloy style with off-screen rendering or when a parent window handle is specified).
  3. Fix various issues with Alloy* implementations to make it all work nicely.
  4. Delete the Alloy runtime bootstrap and related unused classes. Chrome runtime bootstrap becomes the only option.

Remaining work:

  • Add support for CefDownloadHandler API. (DONE)
  • views: Add Chrome theme support for Alloy style BrowserView in Chrome style Window. (DONE)
  • views: Test multiple Alloy style BrowserViews in a single Window.
  • Add build configuration to disable Alloy bootstrap. (DONE)

DevTools popups don't load successfully in combination with windowless rendering.

It appears that DevTools frontend #initializeTarget never completes (await runnableInstanceFunction().run() never returns when running the InspectorMainImpl), and consequently DevToolsUIBindings::ReadyForTest is never called. Adding console.log statements in InspectorMainImpl shows that waitForPrimaryPageTarget never resolves because targetManager.primaryPageTarget() returns null. It looks like the problem is parentTarget has type "browser" instead of the expected type "frame".
image
Here are the expected |targets| when not using OSR:
image

It looks like BuildTargetInfo is passing the wrong |type| value ("other" vs the expected "page") to AttachedToTarget.

With OSR:

+		m_targetId	0x00000237d0c06f30 "134E9E28B3E4D3F7DE74F1875541583F"	std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>>
+		m_type	0x00000237d045d340 "other"	std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>>
+		m_title	0x00000237d045d358 "Google"	std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>>
+		m_url	0x00000237d0c07080 "https://www.google.com/"	std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>>
		m_attached	true	bool
+		m_openerId	{is_just_=false value_=0x00000237d045d398 "" }	crdtp::detail::ValueMaybe<std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>>>
		m_canAccessOpener	false	bool
+		m_openerFrameId	{is_just_=false value_=0x00000237d045d3c0 "" }	crdtp::detail::ValueMaybe<std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>>>
+		m_browserContextId	{is_just_=true value_=0x00000237d0c06e50 "4B8CD36561F1E032B21AABA6461B51DD" }	crdtp::detail::ValueMaybe<std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>>>
+		m_subtype	{is_just_=false value_=0x00000237d045d400 "" }	crdtp::detail::ValueMaybe<std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>>>

Without OSR:

+		m_targetId	0x0000011aecb61280 "20E74CA864F5116161F41D82A6665643"	std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>>
+		m_type	0x0000011aee9c6b30 "page"	std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>>
+		m_title	0x0000011aee9c6b48 "Google"	std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>>
+		m_url	0x0000011aed556940 "https://www.google.com/"	std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>>
		m_attached	true	bool
+		m_openerId	{is_just_=false value_=0x0000011aee9c6b88 "" }	crdtp::detail::ValueMaybe<std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>>>
		m_canAccessOpener	false	bool
+		m_openerFrameId	{is_just_=false value_=0x0000011aee9c6bb0 "" }	crdtp::detail::ValueMaybe<std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>>>
+		m_browserContextId	{is_just_=true value_=0x0000011ae8f8b420 "7165BA42B823C82D06C6EA9BDF786D9E" }	crdtp::detail::ValueMaybe<std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>>>
+		m_subtype	{is_just_=false value_=0x0000011aee9c6bf0 "" }	crdtp::detail::ValueMaybe<std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>>>

Call stack:

 	content.dll!content::protocol::`anonymous namespace'::BuildTargetInfo(content::DevToolsAgentHost * agent_host) Line 114	C++
>	content.dll!content::protocol::TargetHandler::Session::Attach(content::protocol::TargetHandler * handler, content::DevToolsAgentHost * agent_host, bool waiting_for_debugger, bool flatten_protocol) Line 437	C++
 	content.dll!content::protocol::TargetHandler::AutoAttach(content::protocol::TargetAutoAttacher * source, content::DevToolsAgentHost * host, bool waiting_for_debugger) Line 849	C++
 	content.dll!content::protocol::TargetHandler::SetAttachedTargetsOfType(content::protocol::TargetAutoAttacher * source, const base::internal::flat_tree<scoped_refptr<content::DevToolsAgentHost>,std::__Cr::identity,std::__Cr::less<void>,std::__Cr::vector<scoped_refptr<content::DevToolsAgentHost>,std::__Cr::allocator<scoped_refptr<content::DevToolsAgentHost>>>> & new_hosts, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> & type) Line 887	C++
 	content.dll!content::protocol::TargetAutoAttacher::DispatchSetAttachedTargetsOfType(const base::internal::flat_tree<scoped_refptr<content::DevToolsAgentHost>,std::__Cr::identity,std::__Cr::less<void>,std::__Cr::vector<scoped_refptr<content::DevToolsAgentHost>,std::__Cr::allocator<scoped_refptr<content::DevToolsAgentHost>>>> & hosts, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> & type) Line 140	C++
 	content.dll!content::WebContentsDevToolsAgentHost::AutoAttacher::UpdateAssociatedPages() Line 110	C++
 	content.dll!content::WebContentsDevToolsAgentHost::AutoAttacher::UpdateAutoAttach(base::OnceCallback<void ()> callback) Line 94	C++
 	content.dll!content::protocol::TargetAutoAttacher::AddClient(content::protocol::TargetAutoAttacher::Client * client, bool wait_for_debugger_on_start, base::OnceCallback<void ()> callback) Line 88	C++
 	content.dll!content::protocol::TargetHandler::SetAutoAttachInternal(bool auto_attach, bool wait_for_debugger_on_start, bool flatten, base::OnceCallback<void ()> callback) Line 816	C++
 	content.dll!content::protocol::TargetHandler::SetAutoAttach(bool auto_attach, bool wait_for_debugger_on_start, crdtp::detail::ValueMaybe<bool> flatten, crdtp::detail::PtrMaybe<std::__Cr::vector<std::__Cr::unique_ptr<content::protocol::Target::FilterEntry,std::__Cr::default_delete<content::protocol::Target::FilterEntry>>,std::__Cr::allocator<std::__Cr::unique_ptr<content::protocol::Target::FilterEntry,std::__Cr::default_delete<content::protocol::Target::FilterEntry>>>>> filter, std::__Cr::unique_ptr<content::protocol::Target::Backend::SetAutoAttachCallback,std::__Cr::default_delete<content::protocol::Target::Backend::SetAutoAttachCallback>> callback) Line 1028	C++
 	content.dll!content::protocol::Target::DomainDispatcherImpl::setAutoAttach(const crdtp::Dispatchable & dispatchable) Line 899	C++
 	content.dll!content::protocol::Target::DomainDispatcherImpl::Dispatch::<lambda_14>::operator()(const crdtp::Dispatchable & dispatchable) Line 288	C++
 	content.dll!std::__Cr::__invoke<`lambda at gen\content\browser\devtools\protocol\target.cc:286:10' &,const crdtp::Dispatchable &>(content::protocol::Target::DomainDispatcherImpl::Dispatch::<lambda_14> & __f, const crdtp::Dispatchable & __args) Line 150	C++
 	content.dll!std::__Cr::__invoke_void_return_wrapper<void,1>::__call<`lambda at gen\content\browser\devtools\protocol\target.cc:286:10' &,const crdtp::Dispatchable &>(content::protocol::Target::DomainDispatcherImpl::Dispatch::<lambda_14> & __args, const crdtp::Dispatchable & __args) Line 226	C++
 	content.dll!std::__Cr::__function::__default_alloc_func<`lambda at gen\content\browser\devtools\protocol\target.cc:286:10',void (const crdtp::Dispatchable &)>::operator()(const crdtp::Dispatchable & __arg) Line 208	C++
 	content.dll!std::__Cr::__function::__policy_invoker<void (const crdtp::Dispatchable &)>::__call_impl<std::__Cr::__function::__default_alloc_func<`lambda at gen\content\browser\devtools\protocol\target.cc:286:10',void (const crdtp::Dispatchable &)>>(const std::__Cr::__function::__policy_storage * __buf, const crdtp::Dispatchable & __args) Line 608	C++
 	third_party_inspector_protocol_crdtp.dll!std::__Cr::__function::__policy_func<void (const crdtp::Dispatchable &)>::operator()(const crdtp::Dispatchable & __args) Line 714	C++
 	third_party_inspector_protocol_crdtp.dll!std::__Cr::function<void (const crdtp::Dispatchable &)>::operator()(const crdtp::Dispatchable & __arg) Line 987	C++
 	third_party_inspector_protocol_crdtp.dll!crdtp::UberDispatcher::Dispatch::<lambda_0>::operator()() Line 545	C++
 	third_party_inspector_protocol_crdtp.dll!std::__Cr::__invoke<`lambda at ..\..\third_party\inspector_protocol\crdtp\dispatch.cc:543:19' &>(crdtp::UberDispatcher::Dispatch::<lambda_0> & __f) Line 150	C++
 	third_party_inspector_protocol_crdtp.dll!std::__Cr::__invoke_void_return_wrapper<void,1>::__call<`lambda at ..\..\third_party\inspector_protocol\crdtp\dispatch.cc:543:19' &>(crdtp::UberDispatcher::Dispatch::<lambda_0> & __args) Line 226	C++
 	third_party_inspector_protocol_crdtp.dll!std::__Cr::__function::__default_alloc_func<`lambda at ..\..\third_party\inspector_protocol\crdtp\dispatch.cc:543:19',void ()>::operator()() Line 208	C++
 	third_party_inspector_protocol_crdtp.dll!std::__Cr::__function::__policy_invoker<void ()>::__call_impl<std::__Cr::__function::__default_alloc_func<`lambda at ..\..\third_party\inspector_protocol\crdtp\dispatch.cc:543:19',void ()>>(const std::__Cr::__function::__policy_storage * __buf) Line 608	C++
 	third_party_inspector_protocol_crdtp.dll!std::__Cr::__function::__policy_func<void ()>::operator()() Line 714	C++
 	third_party_inspector_protocol_crdtp.dll!std::__Cr::function<void ()>::operator()() Line 987	C++
 	third_party_inspector_protocol_crdtp.dll!crdtp::UberDispatcher::DispatchResult::Run() Line 509	C++
 	content.dll!content::DevToolsSession::HandleCommandInternal(crdtp::Dispatchable dispatchable, base::span<const unsigned char,18446744073709551615,const unsigned char *> message) Line 380	C++
 	content.dll!content::DevToolsSession::HandleCommand(base::span<const unsigned char,18446744073709551615,const unsigned char *> message) Line 365	C++
 	content.dll!base::internal::DecayedFunctorTraits<void (content::DevToolsSession::*)(base::span<const unsigned char,18446744073709551615,const unsigned char *>),base::WeakPtr<content::DevToolsSession> &&>::Invoke<void (content::DevToolsSession::*)(base::span<const unsigned char,18446744073709551615,const unsigned char *>),const base::WeakPtr<content::DevToolsSession> &,base::span<const unsigned char,18446744073709551615,const unsigned char *>>(void(content::DevToolsSession::*)(base::span<const unsigned char,18446744073709551615,const unsigned char *>) method, const base::WeakPtr<content::DevToolsSession> & receiver_ptr, base::span<const unsigned char,18446744073709551615,const unsigned char *> && args) Line 738	C++
 	content.dll!base::internal::InvokeHelper<1,base::internal::FunctorTraits<void (content::DevToolsSession::*&&)(base::span<const unsigned char,18446744073709551615,const unsigned char *>),base::WeakPtr<content::DevToolsSession> &&>,void,0>::MakeItSo<void (content::DevToolsSession::*)(base::span<const unsigned char,18446744073709551615,const unsigned char *>),std::__Cr::tuple<base::WeakPtr<content::DevToolsSession>>,base::span<const unsigned char,18446744073709551615,const unsigned char *>>(void(content::DevToolsSession::*)(base::span<const unsigned char,18446744073709551615,const unsigned char *>) && functor, std::__Cr::tuple<base::WeakPtr<content::DevToolsSession>> && bound, base::span<const unsigned char,18446744073709551615,const unsigned char *> && args) Line 958	C++
 	content.dll!base::internal::Invoker<base::internal::FunctorTraits<void (content::DevToolsSession::*&&)(base::span<const unsigned char,18446744073709551615,const unsigned char *>),base::WeakPtr<content::DevToolsSession> &&>,base::internal::BindState<1,1,0,void (content::DevToolsSession::*)(base::span<const unsigned char,18446744073709551615,const unsigned char *>),base::WeakPtr<content::DevToolsSession>>,void (base::span<const unsigned char,18446744073709551615,const unsigned char *>)>::RunImpl<void (content::DevToolsSession::*)(base::span<const unsigned char,18446744073709551615,const unsigned char *>),std::__Cr::tuple<base::WeakPtr<content::DevToolsSession>>,0>(void(content::DevToolsSession::*)(base::span<const unsigned char,18446744073709551615,const unsigned char *>) && functor, std::__Cr::tuple<base::WeakPtr<content::DevToolsSession>> && bound, std::__Cr::integer_sequence<unsigned long long,0>, base::span<const unsigned char,18446744073709551615,const unsigned char *> && unbound_args) Line 1067	C++
 	content.dll!base::internal::Invoker<base::internal::FunctorTraits<void (content::DevToolsSession::*&&)(base::span<const unsigned char,18446744073709551615,const unsigned char *>),base::WeakPtr<content::DevToolsSession> &&>,base::internal::BindState<1,1,0,void (content::DevToolsSession::*)(base::span<const unsigned char,18446744073709551615,const unsigned char *>),base::WeakPtr<content::DevToolsSession>>,void (base::span<const unsigned char,18446744073709551615,const unsigned char *>)>::RunOnce(base::internal::BindStateBase * base, base::span<const unsigned char,18446744073709551615,const unsigned char *> && unbound_args) Line 980	C++
 	libcef.dll!base::OnceCallback<void (base::span<const unsigned char,18446744073709551615,const unsigned char *>)>::Run(base::span<const unsigned char,18446744073709551615,const unsigned char *> args) Line 157	C++
 	libcef.dll!ChromeDevToolsSession::HandleCommand(base::span<const unsigned char,18446744073709551615,const unsigned char *> message, base::OnceCallback<void (base::span<const unsigned char,18446744073709551615,const unsigned char *>)> callback) Line 141	C++
 	libcef.dll!ChromeDevToolsManagerDelegate::HandleCommand(content::DevToolsAgentHostClientChannel * channel, base::span<const unsigned char,18446744073709551615,const unsigned char *> message, base::OnceCallback<void (base::span<const unsigned char,18446744073709551615,const unsigned char *>)> callback) Line 232	C++
 	content.dll!content::DevToolsSession::DispatchProtocolMessageInternal(crdtp::Dispatchable dispatchable, base::span<const unsigned char,18446744073709551615,const unsigned char *> message) Line 356	C++
 	content.dll!content::DevToolsSession::DispatchProtocolMessage(base::span<const unsigned char,18446744073709551615,const unsigned char *> message) Line 315	C++
 	content.dll!content::DevToolsAgentHostImpl::DispatchProtocolMessage(content::DevToolsAgentHostClient * client, base::span<const unsigned char,18446744073709551615,const unsigned char *> message) Line 349	C++
 	libcef.dll!DevToolsUIBindings::DispatchProtocolMessageFromDevToolsFrontend(const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> & message) Line 1532	C++

DevTools popups don't load successfully in combination with windowless rendering.
It looks like BuildTargetInfo is passing the wrong |type| value ("other" vs the expected "page") to AttachedToTarget.

The problem is ChromeDevToolsManagerDelegate::GetTargetType. The AllTabContentses case catches Chrome style browsers and the WebView::IsWebViewContents case catches Alloy style windowed browsers, but there's no handling for OSR browsers.