New issue
Advanced search Search tips

Issue 614568 link

Starred by 2 users

Issue metadata

Status: Fixed
Owner:
Closed: Oct 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Mac
Pri: 3
Type: Bug

Blocking:
issue 604105



Sign in to add a comment

bluetooth: mac: Some requestDevice calls fail to show a chooser.

Project Member Reported by jyasskin@chromium.org, May 25 2016

Issue description

about:version: Chromium	53.0.2748.0 (Developer Build) (64-bit) and 
Google Chrome	51.0.2704.47 (Official Build) beta (64-bit)

https://jyasskin.github.io/sandbox/notfound.html doesn't show a chooser and immediately returns a NotFoundError when you click 'Scan'.

However, basically the same code does show the chooser on https://googlechrome.github.io/samples/web-bluetooth/device-info.html. I'm not sure what's going wrong.

Thanks to barchard for reporting the problem on https://github.com/electron/electron/issues/5565#issuecomment-221270772.
 
Status: WontFix (was: Available)
Simply replace <a> with <button> and it will work.
This is not an issue with Web Bluetooth here.
Status: Available (was: WontFix)
That sounds like it's a user gesture problem, and in fact replacing the href="#" with href="javascript:;" also causes the dialog to show up, but when we're missing a user gesture we need to return a SecurityError, not a NotFoundError. https://webbluetoothcg.github.io/web-bluetooth/#requestDevice-user-gesture
Here's how we currently check user gesture in Web Bluetooth code:

    if (!UserGestureIndicator::consumeUserGesture()) {
        return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(SecurityError, "Must be handling a user gesture to show a permission request."));
    }


For info, element.requestFullScreen() checks user gesture this way:

if (!UserGestureIndicator::utilizeUserGesture()) ...


And HTMLMediaElement.play() with:


Nullable<ExceptionCode> HTMLMediaElement::play()
{
    DVLOG(MEDIA_LOG_LEVEL) << "play(" << (void*)this << ")";

    m_autoplayHelper->playMethodCalled();

    if (!UserGestureIndicator::processingUserGesture()) {
        if (isGestureNeededForPlayback()) {
            // If playback is deferred, then don't start playback but don't
            // fail yet either.
            if (m_autoplayHelper->isPlaybackDeferred())
                return nullptr;

            // If we're already playing, then this play would do nothing anyway.
            // Call playInternal to handle scheduling the promise resolution.
            if (!m_paused) {
                playInternal();
                return nullptr;
            }

            recordAutoplayMetric(PlayMethodFailed);
            String message = ExceptionMessages::failedToExecute("play", "HTMLMediaElement", "API can only be initiated by a user gesture.");
            document().addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message));
            return NotAllowedError;
        }
    } else {
        UserGestureIndicator::utilizeUserGesture();
        // We ask the helper to remove the gesture requirement for us, so that
        // it can record the reason.
        Platform::current()->recordAction(UserMetricsAction("Media_Play_WithGesture"));
        m_autoplayHelper->unlockUserGesture(GesturelessPlaybackEnabledByPlayMethod);
    }

Comment 4 by ortuno@chromium.org, May 25 2016

Cc: juncai@chromium.org hcarmona@chromium.org
I don't think this is a problem with the user gesture. I think this is what's happening:

1. User clicks <a>.
2. We check that there was a user gesture.
3. Since there was a user gesture we open the chooser.
4. At this point the navigation to "#" gets committed.
5. The BubbleManager closes all bubbles. [1]

So the problem is BubbleManager. The solution to this specific problem would be to not close bubbles for in page navigations like we do WebBluetoothServiceImpl[2]:

void WebBluetoothServiceImpl::DidFinishNavigation(
    NavigationHandle* navigation_handle) {
  if (navigation_handle->HasCommitted() &&
      navigation_handle->GetRenderFrameHost() == render_frame_host_ &&
      !navigation_handle->IsSamePage()) {
    ClearState();
  }
}

But I'm not sure if that's a behavior BubbleManager wants. @hcarmona WDYT?

[1] https://code.google.com/p/chromium/codesearch#chromium/src/chrome/browser/ui/chrome_bubble_manager.cc&sq=package:chromium&type=cs&l=160&rcl=1464175305
[2] https://code.google.com/p/chromium/codesearch#chromium/src/content/browser/bluetooth/web_bluetooth_service_impl.cc&sq=package:chromium&type=cs&l=187 
For info, it works fine on Chrome OS 52.0.2727.0
(gentle ping)
Should it be assigned to juncai?
Cc: -juncai@chromium.org
Owner: juncai@chromium.org

Comment 9 by juncai@chromium.org, Sep 16 2016

I found that if double click the link at:
https://jyasskin.github.io/sandbox/notfound.html
The chooser will always show up.
Cc: juncai@chromium.org
Owner: ----
Summary: bluetooth: mac: Some requestDevice calls fail to show a chooser. (was: bluetooth: Some requestDevice calls on Mac fail to show a chooser.)
Here are below logs I get when testing with https://beaufortfrancois.github.io/sandbox/web-bluetooth/request-device-fails/

Chrome OS [OK] 😃

(index):12 MouseEvent {isTrusted: true, screenX: 262, screenY: 92, clientX: 262, clientY: 18…}
(index):16 PopStateEvent {isTrusted: true, state: null, type: "popstate", target: Window, currentTarget: Window…}
(index):19 HashChangeEvent {isTrusted: true, oldURL: "https://beaufortfrancois.github.io/sandbox/web-bluetooth/request-device-fails/", newURL: "https://beaufortfrancois.github.io/sandbox/web-bluetooth/request-device-fails/#clicked", type: "hashchange", target: Window…}

Android [OK] 😃

(index):12 MouseEvent {isTrusted: true, screenX: 213, screenY: 96, clientX: 305, clientY: 22…}
(index):16 PopStateEvent {isTrusted: true, state: null, type: "popstate", target: Window, currentTarget: Window…}
(index):19 HashChangeEvent {isTrusted: true, oldURL: "https://beaufortfrancois.github.io/sandbox/web-bluetooth/request-device-fails/", newURL: "https://beaufortfrancois.github.io/sandbox/web-bluetooth/request-device-fails/#clicked", type: "hashchange", target: Window…}bubbles: falsecancelBubble: falsecancelable: falsecomposed: falsecurrentTarget: WindowdefaultPrevented: falseeventPhase: 2isTrusted: truenewURL: "https://beaufortfrancois.github.io/sandbox/web-bluetooth/request-device-fails/#clicked"oldURL: "https://beaufortfrancois.github.io/sandbox/web-bluetooth/request-device-fails/"path: Array[1]returnValue: truesrcElement: Windowtarget: WindowtimeStamp: 2725.9700000000003type: "hashchange"__proto__: HashChangeEvent

Mac OS [FAIL] 😢

(index):12 MouseEvent {isTrusted: true, screenX: 385, screenY: 269, clientX: 216, clientY: 23…}
(index):16 PopStateEvent {isTrusted: true, state: null, type: "popstate", target: Window, currentTarget: Window…}
(index):19 HashChangeEvent {isTrusted: true, oldURL: "https://beaufortfrancois.github.io/sandbox/web-bluetooth/request-device-fails/", newURL: "https://beaufortfrancois.github.io/sandbox/web-bluetooth/request-device-fails/#clicked", type: "hashchange", target: Window…}
/sandbox/web-bluetooth/request-device-fails/#clicked:1 Uncaught (in promise) DOMException: User cancelled the requestDevice() chooser.
Dismissing the bubble on navigate seems like the right thing to do most of the time. This is to prevent the bubble from showing up in the wrong URL.

Permission bubbles had a similar issue:  http://crbug.com/507855 
Updating ChromeBubbleManager::NavigationEntryCommitted to not dismiss when load_details.is_in_page should fix this.

I'm not sure why the bubble isn't being dismissed on chromeos, it should be broken there too. It will not dismiss the request if you change the href in chromeos to a different URL which is bad.

Bubble manager isn't part of android, so it makes sense that it behaves differently there.
Great. juncai: Can you work on a patch to not close bubbles when load_details.is_in_page is true?

https://cs.chromium.org/chromium/src/chrome/browser/ui/chrome_bubble_manager.cc?sq=package:chromium&type=cs&l=160&rcl=1464175305
Cc: -juncai@chromium.org
Owner: juncai@chromium.org
Status: Assigned (was: Available)
Sure!
hcarmona@ is right! Thanks!

There is a bug in Chrome OS when we change href to a different domain.
You can reproduce it in https://beaufortfrancois.github.io/sandbox/web-bluetooth/request-device-fails/

jun@ Can we fix it as well as part of this bug?


Screenshot 2016-10-25 at 1.14.40 PM.png
75.3 KB View Download
Status: Started (was: Assigned)
Sure!
Question: Is the following the expected result for the two links?
"Show Bluetooth chooser from <a href="#clicked">"
chooser will show up.

"Show Bluetooth chooser from <a href="http://google.com">"
chooser shouldn't show up.
In the second case the chooser should show up but then go away when the page navigates.

FWIW: I can't reproduce the bug in #16
The bug in #16 is reproducible on ChromeOS, but on Mac, it works fine.
What version of Chrome OS? I'm testing on ToT and I don't see this behavior.
version 56.0.2898.0.

I did some experiments and found:
On ChromeOS:
"Show Bluetooth chooser from <a href="#clicked">"
chooser shows up.

"Show Bluetooth chooser from <a href="http://google.com">"
chooser shows up and doesn't go away when the page navigates.

On Mac:
"Show Bluetooth chooser from <a href="#clicked">"
chooser doesn't shows up.

"Show Bluetooth chooser from <a href="http://google.com">"
chooser shows up and then goes away when the page navigates.
Blocking: 604105
huh this seems to be Chrome OS specific. Linux and macOS work correctly... I took a look at the web_bluetooth_service_impl.cc code. Everything seems to be the same on both platforms which leads me to believe the problem lies in the chooser code.

Nothing bad happens if you pick a device in a different domain.

I opened  Issue 659433  for this bug. I don't think we need to fix both in the same patch.
Project Member

Comment 25 by bugdroid1@chromium.org, Oct 26 2016

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

commit 189740490f79e9c04c4fb06f8f5bdf80e8af977d
Author: juncai <juncai@chromium.org>
Date: Wed Oct 26 22:28:33 2016

Not close bubble if the navigation is in-page

This CL updates ChromeBubbleManager::NavigationEntryCommitted to
not close the bubble when load_details.is_in_page is true.

BUG= 614568 

Review-Url: https://codereview.chromium.org/2451573004
Cr-Commit-Position: refs/heads/master@{#427849}

[modify] https://crrev.com/189740490f79e9c04c4fb06f8f5bdf80e8af977d/chrome/browser/ui/chrome_bubble_manager.cc
[modify] https://crrev.com/189740490f79e9c04c4fb06f8f5bdf80e8af977d/chrome/browser/ui/chrome_bubble_manager_unittest.cc

Status: Fixed (was: Started)

Sign in to add a comment