New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 915572 link

Starred by 4 users

Issue metadata

Status: Fixed
Owner:
Closed: Jan 10
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Mac
Pri: 1
Type: Bug



Sign in to add a comment

Mac PWAs: Hang when attempting to exit Fullscreen

Project Member Reported by hwi@chromium.org, Dec 17

Issue description

Chrome Version: 73.0.3642.0 (Official Build) canary (64-bit)
OS: MacOS

What steps will reproduce the problem?
(1) Open a PWA
(2) 3 dot menu > Click on the full screen icon
(3) 3 dot menu > Click on the exit full screen icon

What is the expected result?

Exit full screen

What happens instead?

App hangs


Please use labels and text to provide additional information.

If this is a regression (i.e., worked before), please consider using the
bisect tool (https://www.chromium.org/developers/bisect-builds-py) to help
us identify the root cause and more rapidly triage the issue.

For graphics-related bugs, please copy/paste the contents of the about:gpu
page at the end of this report.


 
mac pwa fullscreen.mp4
5.6 MB View Download
Labels: -Pri-2 Pri-1
Owner: alancutter@chromium.org
Status: Assigned (was: Untriaged)
Summary: Mac PWAs: Hang when attempting to exit Fullscreen (was: Mac PWAs: Fullscreen exit not working)
Alan can you take a look?

Bumping to P1 since this is a hang.
I can repro this on 73.0.3642.0 - which has the fix from Issue 913337 (another fullscreen hang related problem) applied. It seems to hang the entire browser as well.
Yeah, same here. It's probably crashing/hanging the browser process (which then hangs all apps).
It gets stuck at 100% CPU.

Here's a stack trace during the hang:
#0  std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >* logging::CheckNEImpl<(anonymous namespace)::TlsVectorEntry*, void*>((anonymous namespace)::TlsVectorEntry* const&, void* const&, char const*) at base/logging.h:799
#1  base::ThreadLocalStorage::Slot::Get() const at base/threading/thread_local_storage.cc:365
#2  base::ThreadLocalPointer<base::internal::BlockingObserver>::Get() [inlined] at base/threading/thread_local.h:64
#3  base::internal::UncheckedScopedBlockingCall::UncheckedScopedBlockingCall(base::BlockingType) at base/threading/scoped_blocking_call.cc:50
#4  base::internal::ScopedBlockingCallWithBaseSyncPrimitives::ScopedBlockingCallWithBaseSyncPrimitives(base::BlockingType) at base/threading/scoped_blocking_call.cc:106
#5  base::WaitableEvent::WaitMany(base::WaitableEvent**, unsigned long) at base/synchronization/waitable_event_mac.cc:181
#6  mojo::WaitSet::State::Wait(base::WaitableEvent**, unsigned long*, mojo::Handle*, unsigned int*, MojoHandleSignalsState*) at mojo/public/cpp/system/wait_set.cc:203
#7  mojo::WaitSet::Wait(base::WaitableEvent**, unsigned long*, mojo::Handle*, unsigned int*, MojoHandleSignalsState*) at mojo/public/cpp/system/wait_set.cc:361
#8  mojo::SyncHandleRegistry::Wait(bool const**, unsigned long) at mojo/public/cpp/bindings/lib/sync_handle_registry.cc:140
#9  mojo::SyncEventWatcher::SyncWatch(bool const**, unsigned long) at mojo/public/cpp/bindings/lib/sync_event_watcher.cc:51
#10 mojo::SequenceLocalSyncEventWatcher::SequenceLocalState::SyncWatch(mojo::SequenceLocalSyncEventWatcher const*, mojo::(anonymous namespace)::WatcherState*, bool const*) [inlined] at mojo/public/cpp/bindings/lib/sequence_local_sync_event_watcher.cc:161
#11 mojo::SequenceLocalSyncEventWatcher::SyncWatch(bool const*) at mojo/public/cpp/bindings/lib/sequence_local_sync_event_watcher.cc:282
#12 mojo::internal::MultiplexRouter::InterfaceEndpoint::SyncWatch(bool const*) at mojo/public/cpp/bindings/lib/multiplex_router.cc:146
#13 mojo::InterfaceEndpointClient::AcceptWithResponder(mojo::Message*, std::__1::unique_ptr<mojo::MessageReceiver, std::__1::default_delete<mojo::MessageReceiver> >) at mojo/public/cpp/bindings/lib/interface_endpoint_client.cc:285
#14 views_bridge_mac::mojom::BridgedNativeWidgetHostProxy::GetWidgetIsModal(bool*) at gen/ui/views_bridge_mac/mojo/bridged_native_widget_host.mojom.cc:1390
#15 views::BridgedNativeWidgetImpl::ShouldRunCustomAnimationFor(views_bridge_mac::mojom::VisibilityTransition) const [inlined] at ui/views_bridge_mac/bridged_native_widget_impl.mm:1021
#16 views::BridgedNativeWidgetImpl::CloseWindow() at ui/views_bridge_mac/bridged_native_widget_impl.mm:561
#17 views_bridge_mac::mojom::BridgedNativeWidgetStubDispatch::Accept(views_bridge_mac::mojom::BridgedNativeWidget*, mojo::Message*) at gen/ui/views_bridge_mac/mojo/bridged_native_widget.mojom.cc:1375
#18 mojo::InterfaceEndpointClient::HandleValidatedMessage(mojo::Message*) at mojo/public/cpp/bindings/lib/interface_endpoint_client.cc:423
#19 mojo::FilterChain::Accept(mojo::Message*) at mojo/public/cpp/bindings/lib/filter_chain.cc:40
#20 mojo::InterfaceEndpointClient::HandleIncomingMessage(mojo::Message*) at mojo/public/cpp/bindings/lib/interface_endpoint_client.cc:306
#21 mojo::internal::MultiplexRouter::ProcessIncomingMessage(mojo::internal::MultiplexRouter::MessageWrapper*, mojo::internal::MultiplexRouter::ClientCallBehavior, base::SequencedTaskRunner*) at mojo/public/cpp/bindings/lib/multiplex_router.cc:869
#22 mojo::internal::MultiplexRouter::ProcessTasks(mojo::internal::MultiplexRouter::ClientCallBehavior, base::SequencedTaskRunner*) at mojo/public/cpp/bindings/lib/multiplex_router.cc:704
#23 mojo::internal::MultiplexRouter::LockAndCallProcessTasks() at mojo/public/cpp/bindings/lib/multiplex_router.cc:897
#24 void base::internal::FunctorTraits<void (mojo::internal::MultiplexRouter::*)(), void>::Invoke<void (mojo::internal::MultiplexRouter::*)(), scoped_refptr<mojo::internal::MultiplexRouter> >(void (mojo::internal::MultiplexRouter::*)(), scoped_refptr<mojo::internal::MultiplexRouter>&&) [inlined] at base/bind_internal.h:516
#25 void base::internal::InvokeHelper<false, void>::MakeItSo<void (mojo::internal::MultiplexRouter::*)(), scoped_refptr<mojo::internal::MultiplexRouter> >(void (mojo::internal::MultiplexRouter::*&&)(), scoped_refptr<mojo::internal::MultiplexRouter>&&) [inlined] at base/bind_internal.h:616
#26 void base::internal::Invoker<base::internal::BindState<void (mojo::internal::MultiplexRouter::*)(), scoped_refptr<mojo::internal::MultiplexRouter> >, void ()>::RunImpl<void (mojo::internal::MultiplexRouter::*)(), std::__1::tuple<scoped_refptr<mojo::internal::MultiplexRouter> >, 0ul>(void (mojo::internal::MultiplexRouter::*&&)(), std::__1::tuple<scoped_refptr<mojo::internal::MultiplexRouter> >&&, std::__1::integer_sequence<unsigned long, 0ul>) [inlined] at base/bind_internal.h:689
#27 base::internal::Invoker<base::internal::BindState<void (mojo::internal::MultiplexRouter::*)(), scoped_refptr<mojo::internal::MultiplexRouter> >, void ()>::RunOnce(base::internal::BindStateBase*) at base/bind_internal.h:658
#28 base::OnceCallback<void ()>::Run() && at base/callback.h:99
#29 base::OnceCallback<void ()>::Run() && [inlined] at base/callback.h:99
#30 base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*) at base/debug/task_annotator.cc:99
#31 base::MessageLoopImpl::RunTask(base::PendingTask*) at base/message_loop/message_loop_impl.cc:374
#32 base::MessageLoopImpl::DeferOrRunPendingTask(base::PendingTask) [inlined] at base/message_loop/message_loop_impl.cc:385
#33 base::MessageLoopImpl::DoWork() at base/message_loop/message_loop_impl.cc:473
#34 base::MessagePumpCFRunLoopBase::RunWork() at base/message_loop/message_pump_mac.mm:487
#35 base::mac::CallWithEHFrame(void () block_pointer) at base/mac/call_with_eh_frame_asm.S:36
#36 base::MessagePumpCFRunLoopBase::RunWorkSource(void*) at base/message_loop/message_pump_mac.mm:461
#37 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ ()
#38 __CFRunLoopDoSource0 ()
#39 __CFRunLoopDoSources0 ()
#40 __CFRunLoopRun ()
#41 CFRunLoopRunSpecific ()
#42 RunCurrentEventLoopInMode ()
#43 ReceiveNextEventCommon ()
#44 _BlockUntilNextEventMatchingListInModeWithFilter ()
#45 _DPSNextEvent ()
#46 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] ()
#47 -[NSApplication run] ()
#48 base::MessagePumpNSApplication::DoRun(base::MessagePump::Delegate*) at base/message_loop/message_pump_mac.mm:847
#49 base::MessagePumpCFRunLoopBase::Run(base::MessagePump::Delegate*) at base/message_loop/message_pump_mac.mm:185
#50 base::MessageLoopImpl::Run(bool) at base/message_loop/message_loop_impl.cc:326
#51 base::RunLoop::Run() at base/run_loop.cc:102
#52 ::ChromeAppModeStart_v4(const app_mode::ChromeAppModeInfo *) at chrome/app_shim/chrome_main_app_mode_mac.mm:294
#53 main ()
#54 start ()
#55 start ()

BridgedNativeWidgetImpl::ShouldRunCustomAnimationFor(VisibilityTransition) is calling a [Sync] mojo method host_->GetWidgetIsModal(&widget_is_modal);. There's a chance it's deadlocking with the main browser process.

Interestingly this doesn't occur if you use the green button to go full screen. If you use the menu to go full screen both the menu and the green button hang when exiting fullscreen.
On the browser side it crashes trying to close the app shim host once it detects the mojo channel has died:


#0  views::BridgedNativeWidgetHostImpl::OnBridgeFactoryHostDestroying(views::BridgeFactoryHost*)
#1  views::BridgeFactoryHost::~BridgeFactoryHost()
#2  std::__1::default_delete<views::BridgeFactoryHost>::operator()(views::BridgeFactoryHost*) const [inlined]
#3  std::__1::unique_ptr<views::BridgeFactoryHost, std::__1::default_delete<views::BridgeFactoryHost> >::reset(views::BridgeFactoryHost*) [inlined]
#4  std::__1::unique_ptr<views::BridgeFactoryHost, std::__1::default_delete<views::BridgeFactoryHost> >::~unique_ptr() [inlined]
#5  std::__1::unique_ptr<views::BridgeFactoryHost, std::__1::default_delete<views::BridgeFactoryHost> >::~unique_ptr() [inlined]
#6  AppShimHost::~AppShimHost()
#7  AppShimHost::~AppShimHost() [inlined]
#8  AppShimHost::~AppShimHost()
#9  AppShimHost::Close() [inlined]
#10 AppShimHost::ChannelError(unsigned int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)

It dies with "CrBrowserMain (1): EXC_BAD_ACCESS (code=EXC_I386_GPFLT)" on "children_.front()->OnBridgeFactoryHostDestroying(host);" where children_ has 2 items.
|children_| is a vector of raw pointers to BridgedNativeWidgetHostImpls. The EXC_BAD_ACCESS implies that the child we are trying to send a message to has been freed already and not cleared from the list.

I *think* the HostImpl is owned by https://cs.chromium.org/chromium/src/ui/views/widget/native_widget_mac.h?q=BridgedNativeWidgetHostImpl&sq=package:chromium&dr=C&l=215, so perhaps there is some lifetime oddness going on here?
Asan to the rescue:

==61476==ERROR: AddressSanitizer: heap-use-after-free on address 0x616000573380 at pc 0x0001234b444f bp 0x7ffeecde30a0 sp 0x7ffeecde3098
READ of size 8 at 0x616000573380 thread T0
    #0 0x1234b444e in non-virtual thunk to views::BridgedNativeWidgetHostImpl::OnBridgeFactoryHostDestroying(views::BridgeFactoryHost*) bridged_native_widget_host_impl.mm:529
    #1 0x1234a7473 in views::BridgeFactoryHost::~BridgeFactoryHost() bridge_factory_host.cc:20
    #2 0x10aa792f5 in AppShimHost::~AppShimHost() memory:2638
    #3 0x10aa794ed in AppShimHost::~AppShimHost() app_shim_host_mac.cc:60
    #4 0x10aa79757 in AppShimHost::ChannelError(unsigned int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) app_shim_host_mac.cc:93

freed by thread T0 here:
    #0 0x102e84a32  (libclang_rt.asan_osx_dynamic.dylib:x86_64+0x66a32)
    #1 0x12344478d in views::NativeWidgetMac::~NativeWidgetMac() native_widget_mac.mm:75
    #2 0x123457748 in views::Widget::~Widget() widget.cc:189
    #3 0x1234580dd in views::Widget::~Widget() widget.cc:186
    #4 0x11413474f in base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*) callback.h:99
    #5 0x1141b5b21 in base::MessageLoopImpl::RunTask(base::PendingTask*) message_loop_impl.cc:374

previously allocated by thread T0 here:
    #0 0x102e84432  (libclang_rt.asan_osx_dynamic.dylib:x86_64+0x66432)
    #1 0x12344aaf2 in views::internal::NativeWidgetPrivate::CreateNativeWidget(views::Widget::InitParams const&, views::internal::NativeWidgetDelegate*) native_widget_mac.mm:72
    #2 0x1234592e2 in views::Widget::Init(views::Widget::InitParams const&) widget.cc:78
    #3 0x10f69c524 in SubtleNotificationView::CreatePopupWidget(gfx::NativeView, SubtleNotificationView*) subtle_notification_view.cc:185
    #4 0x10f4aa3e8 in ExclusiveAccessBubbleViews::ExclusiveAccessBubbleViews(ExclusiveAccessBubbleViewsContext*, GURL const&, ExclusiveAccessBubbleType, base::OnceCallback<void (ExclusiveAccessBubbleHideReason)>) exclusive_access_bubble_views.cc:65
    #5 0x10f4e92de in BrowserView::UpdateExclusiveAccessExitBubbleContent(GURL const&, ExclusiveAccessBubbleType, base::OnceCallback<void (ExclusiveAccessBubbleHideReason)>, bool) browser_view.cc:1051
    #6 0x10f4e8a3f in BrowserView::ProcessFullscreen(bool, GURL const&, ExclusiveAccessBubbleType) browser_view.cc:2777
    #7 0x10f02da7c in FullscreenController::EnterFullscreenModeInternal(FullscreenController::FullscreenInternalOption) fullscreen_controller.cc:402
    #8 0x10f02acee in FullscreenController::ToggleFullscreenModeInternal(FullscreenController::FullscreenInternalOption) fullscreen_controller.cc:380
    #9 0x10f02a9ab in FullscreenController::ToggleBrowserFullscreenMode() fullscreen_controller.cc:74
    #10 0x10efdad1a in chrome::BrowserCommandController::ExecuteCommandWithDisposition(int, WindowOpenDisposition) browser_command_controller.cc:410
    #11 0x10f72c7ac in AppMenu::OnMenuClosed(views::MenuItemView*) app_menu.cc:1062
    #12 0x123306cf8 in views::internal::MenuRunnerImpl::OnMenuClosed(views::internal::MenuControllerDelegate::NotifyType, views::MenuItemView*, int) menu_runner_impl.cc:184
    #13 0x1232d2a34 in views::MenuController::ExitMenu() menu_controller.cc:2799
    #14 0x12328bf54 in views::Button::OnMouseReleased(ui::MouseEvent const&) button.cc
Components: UI>Browser>FullScreen
We can't make this a P2 just by hiding the fullscreen menu option unfortunately. This bug is also triggered by fullscreening from the web e.g. fullscreening a video.

We don't create a new Widget when the user presses the green button but we do when they use the menu. This is likely part of what's going wrong here.
I can take a quick look at the stacks
Mmmh, this is hitting CloseNow (as opposed to Close), which probably doesn't tie up loose ends like it needs to.
This call sequence violates a bunch of my assumptions.

On the browser side: NativeWidgetMac::CloseNow assumes that NativeWidgetMac::WindowDestroyed will be called before the function ends (it doesn't). This is pretty easy to fix -- we already handle an equivalent sequence of events in BridgedNativeWidgetHostImpl::OnBridgeFactoryHostDestroying.

The app side I haven't quite figured out yet. We're getting jammed in a sync mojo call to an interface that has been destroyed on the other side. I wonder if we're hitting this because we're on an associated channel. I'll harass rockot tomorrow if I don't figure it out by then.

Comment 13 Deleted

The stack from #4 looks like your sync call. If it's sitting at 100% CPU inside the sync wait, that's pretty alarming.

How sync waiting works is that we establish a bunch of WaitableEvents on the calling sequence (one for anything which might be doing a sync wait in the same call stack) and we base::WaitableEvent::WaitMany on them, which puts the thread to sleep. We do this in a tight loop until a condition set by the innermost waiter is met, at which point the loop breaks out, possibly unwinding to other outer sync waits.

Since you can easily repro the hang, I would be interested to know what's going on here: https://cs.chromium.org/chromium/src/mojo/public/cpp/bindings/lib/sync_handle_registry.cc?rcl=6a01a1a078f2439bbf64e675596f828a09895b90&l=140

Namely, are we busy-looping because something is permanently signaled but never resetting its signal?
Cc: rockot@google.com
Some printf debugging from SyncHandleRegistry::Wait...

To me it looks that there may be a permanently signaled event.

==================
SyncHandleRegistry::Wait count:3
  New while(true) iteration...
    Checking should_stop:[0, 0, 0, ]
    Waiting...
      ... Done, ready_event:0x0, num_ready_handles:0

  New while(true) iteration...
    Checking should_stop:[0, 0, 0, ]
    Waiting...
      ... Done, ready_event:0x7f917474f720, num_ready_handles:0
    In if (ready_event) ...
      was_dispatching_callbacks: 0
      has 1 callbacks
      Running callback 0...
        ... Done

  New while(true) iteration...
    Checking should_stop:[0, 0, 0, ]
    Waiting...
      ... Done, ready_event:0x7f917474f720, num_ready_handles:0
    In if (ready_event) ...
      was_dispatching_callbacks: 0
      has 1 callbacks
      Running callback 0...
        ... Done

  New while(true) iteration...
    Checking should_stop:[0, 0, 0, ]
    Waiting...
      ... Done, ready_event:0x7f917474f720, num_ready_handles:0
    In if (ready_event) ...
      was_dispatching_callbacks: 0
      has 1 callbacks
      Running callback 0...
        ... Done

  New while(true) iteration...
    Checking should_stop:[0, 0, 0, ]
    Waiting...
      ... Done, ready_event:0x7f917474f720, num_ready_handles:0
    In if (ready_event) ...
      was_dispatching_callbacks: 0
      has 1 callbacks
      Running callback 0...
        ... Done

... and so on forever ...

Indeed it does, in every iteration, in the "running callbacks" part.

  New while(true) iteration...
    Checking should_stop:[0, 0, 0, ]
    Waiting...
      ... Done, ready_event:0x7fb56ce2ac90, num_ready_handles:0, ready_handle_result:0
    In if (ready_event) ...
      was_dispatching_callbacks: 0
      has 1 callbacks
      Running callback 0...
** SequenceLocalSyncEventWatcher::SequenceLocalState::OnEventSignaled this=0x7fb56ce2ac90 **
        ... Done

The |this| argument is the same every time around. The stack doesn't look very interesting (looks to just be the goo to do a callback).
If I comment out "base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, popup_);" in ~ExclusiveAccessBubbleViews() then the PWA window no longer hangs.
I think there's a race condition triggered by ~ExclusiveAccessBubbleViews() between telling the widget to close and destroying it.

Call stack *A*:
~ExclusiveAccessBubbleViews()
    calls Widget::Close() which
    calls NativeWidgetMac::Close() which
    mojo calls BridgedNativeWidgetImpl::CloseWindow() which
    sync mojo calls BridgedNativeWidgetHostImpl::GetWidgetIsModal().

Call stack *B*:
~ExclusiveAccessBubbleViews() also
  async calls ~Widget() which
  calls NativeWidgetMac::CloseNow() which
  mojo calls BridgedNativeWidgetImpl::CloseWindowNow()

Repro steps:
1. Open ruby-clover.glitch.me
2. Start video.
3. Fullscreen video.
4. Press escape to exit video.

Normal browser window:
[91261:775:1221/132006.082392:ERROR:exclusive_access_bubble_views.cc(82)] ~ExclusiveAccessBubbleViews() *AB*
[91261:775:1221/132006.082441:ERROR:widget.cc(608)] Widget::Close() *A*
[91261:775:1221/132006.082455:ERROR:native_widget_mac.mm(382)] NativeWidgetMac::Close() *A*
[91261:775:1221/132006.082464:ERROR:bridged_native_widget_impl.mm(550)] BridgedNativeWidgetImpl::CloseWindow() *A*
[91261:775:1221/132006.082473:ERROR:bridged_native_widget_impl.mm(1031)] calling BridgedNativeWidgetHostImpl::GetWidgetIsModal() *A*
[91261:775:1221/132006.140253:ERROR:bridged_native_widget_host_impl.mm(102)] ~BridgedNativeWidgetHostImpl()
[91261:775:1221/132006.140286:ERROR:bridged_native_widget_impl.mm(313)] ~BridgedNativeWidgetImpl()
[91261:775:1221/132006.141419:ERROR:widget.cc(187)] ~Widget() *B*
[91261:775:1221/132006.141516:ERROR:native_widget_mac.mm(388)] NativeWidgetMac::CloseNow() *B*

Cross process PWA window:
[91261:775:1221/132032.146520:ERROR:exclusive_access_bubble_views.cc(82)] ~ExclusiveAccessBubbleViews() *AB*
[91261:775:1221/132032.146548:ERROR:widget.cc(608)] Widget::Close() *A*
[91261:775:1221/132032.146561:ERROR:native_widget_mac.mm(382)] NativeWidgetMac::Close() *A*
[91261:775:1221/132032.147089:ERROR:widget.cc(187)] ~Widget() *B*
[          1221/132032.147231:ERROR:bridged_native_widget_impl.mm(550)] BridgedNativeWidgetImpl::CloseWindow() *A*
[          1221/132032.147285:ERROR:bridged_native_widget_impl.mm(1031)] calling BridgedNativeWidgetHostImpl::GetWidgetIsModal() *A*
(PWA Window is now hanging.)
[91261:775:1221/132032.147295:ERROR:native_widget_mac.mm(388)] NativeWidgetMac::CloseNow() *B*
[91261:775:1221/132032.147310:ERROR:native_widget_mac.mm(390)] calling BridgedNativeWidgetImpl::CloseWindowNow() *B*
[91261:775:1221/132032.147337:ERROR:bridged_native_widget_host_impl.mm(102)] ~BridgedNativeWidgetHostImpl()
For context the ExclusiveAccessBubbleViews is managing the "Press escape to exit fullscreen" pop over widget.
rockot@ and I sat down with this and we made some progress.

There appears to be a bug somewhere in handling sync calls over associated interfaces. We have a simple workaround, which is to unbind BridgedNativeWidgetHostImpl's AssociatedBinding and then rebind the AssociatedInterfaceRequest to a dummy object that deletes itself once the channel goes down.

There's another bug in RemoteMacViews that has a fix in the CQ.

Btw, this bug is also triggered when using the mouse to dismiss the "uninstall app" dialog.
Project Member

Comment 23 by bugdroid1@chromium.org, Dec 21

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/85aa61033bb520cebfc0f657d97616f5fe883ee0

commit 85aa61033bb520cebfc0f657d97616f5fe883ee0
Author: Christopher Cameron <ccameron@chromium.org>
Date: Fri Dec 21 23:55:51 2018

MacPWAs: Fix part of fullscreen-exit hang

NativeWidgetMac::CloseNow expects that the callbacks for window closure
will happen before the function exits. For out-of-process windows, this
will not be the case (and the callbacks will never be made because the
host interface will have been destroyed).

In out-of-process mode, add explicit calls to these callbacks.

This matches the behavior BridgedNativeWidgetHostImpl's
OnBridgeFactoryHostDestroying (which has the same problem where the
window destroy callbacks won't come in).

Bug:  915572 
Change-Id: Ie65dfef1a7e483364ee95df2e52083c777523a61
Reviewed-on: https://chromium-review.googlesource.com/c/1388722
Commit-Queue: ccameron <ccameron@chromium.org>
Reviewed-by: Sidney San Martín <sdy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#618682}
[modify] https://crrev.com/85aa61033bb520cebfc0f657d97616f5fe883ee0/ui/views/cocoa/bridged_native_widget_host_impl.h
[modify] https://crrev.com/85aa61033bb520cebfc0f657d97616f5fe883ee0/ui/views/cocoa/bridged_native_widget_host_impl.mm
[modify] https://crrev.com/85aa61033bb520cebfc0f657d97616f5fe883ee0/ui/views/widget/native_widget_mac.mm

Cc: swarnasree.mukkala@chromium.org
Labels: Needs-Feedback
Tried testing the issue on latest chrome #73.0.3650.0 using Mac OS 10.14 by following below steps.

Steps:
=====
1.Launched chrome.
2.Installed PWA-"https://killer-marmot.appspot.com/web" and opened it.
3.Clicked on 3-dot menu and clicked on full screen.
4.After getting into full-screen mode, clicked again on three-dot menu.
5.Selected to exit full-screen mode.
6.Observed that the app became unresponsive and unable to exit fullscreen mode.
7.Observed the same behaviour in reported chrome version #73.0.3642.0.

Attached screencast for reference.
@Christopher Cameron: Could you please review attached screencast and let us know if anything is being missed here.
Thanks.!
915572.mp4
1.4 MB View Download
This still has a second part of the fix that needs to land.
Workaround is at
https://chromium-review.googlesource.com/c/chromium/src/+/1390269

We may want to apply that workaround to call interfaces that use sync calls as well.
Project Member

Comment 27 by bugdroid1@chromium.org, Jan 9

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/37917d994b9757c1b0c887070cd55e8a53c5ce59

commit 37917d994b9757c1b0c887070cd55e8a53c5ce59
Author: Christopher Cameron <ccameron@chromium.org>
Date: Wed Jan 09 06:55:27 2019

RemoteMacViews: Work around mojo hang

There exists a bug wherein synchronous mojo calls to an associated
interface might hang if the interface request has been unbound.

Work around this bug by allocating and binding temporary dummy
implementation of the interface, which deletes itself when the
connection closes.

Bug:  915572 
Change-Id: Icb27e8c572ff070e4af90da1f380937a3c11674e
Reviewed-on: https://chromium-review.googlesource.com/c/1390269
Commit-Queue: ccameron <ccameron@chromium.org>
Reviewed-by: Ken Rockot <rockot@google.com>
Cr-Commit-Position: refs/heads/master@{#621063}
[modify] https://crrev.com/37917d994b9757c1b0c887070cd55e8a53c5ce59/ui/views/cocoa/bridged_native_widget_host_impl.mm

Owner: ccameron@chromium.org
Status: Fixed (was: Assigned)
Thanks ccameron!

Sign in to add a comment