chromiumembedded / cef

Chromium Embedded Framework (CEF). A simple framework for embedding Chromium-based browsers in other applications.
https://bitbucket.org/chromiumembedded/cef/
Other
3.09k stars 450 forks source link

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

Open magreenblatt opened 2 months ago

magreenblatt commented 2 months ago

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:

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:

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.
magreenblatt commented 2 months ago

Remaining work:

magreenblatt commented 2 months ago

Test cases have been updated at https://bitbucket.org/chromiumembedded/cef/wiki/ChromiumUpdate#markdown-header-5-run-cef-tests

magreenblatt commented 1 month ago

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

It appears that DevTools frontend [#initializeTarget](https://source.chromium.org/chromium/chromium/src/+/main:third_party/devtools-frontend/src/front_end/entrypoints/main/MainImpl.ts;l=578?q=%23initializeTarget()&ss=chromium%2Fchromium%2Fsrc) 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++
magreenblatt commented 1 month ago

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.