WICG / interventions

A place for browsers and web developers to collaborate on user agent interventions.
Other
177 stars 28 forks source link

Require user activation for navigator.vibrate #47

Closed lubin2010 closed 2 years ago

lubin2010 commented 7 years ago

Vibrate is being abused by malicious contents, and some users have complained about it (e.g., this reddit thread). To better protect user, we would like to gate vibrate with user activation (aka. user gesture or user initiated actions, defined here in the html spec). The metrics from Chrome shows that vibrate was being used by ~0.02% of pages (in Feb 2017, the metrics link).

A frame would be able to vibrate user devices if it or any of its embedded frames has ever received a user activation. In implementation terms, when a user clicks on an iframe, we would set a bit up the ancestor chain saying that it had received a user gesture, so then any frame in the ancestor chain would be able to vibrate from then on.

This is a follow-up effort of #25 "Require user gesture for navigator.vibrate in cross-origin iframes".

cc/ @ojanvafai @RByers @mikewest @bzbarsky @chrisbro-MSFT @VicenteDiaz

RByers commented 7 years ago

And this would apply to the root document too, right? This seems reasonable to me - the root document can't play audio or open a pop-up without user activation, adding vibration to that set seems reasonable.

RByers commented 7 years ago

Note there is some mechanism for measuring in blink how often this would be triggered (UserGestureToken::setUserGestureUtilizedCallback) but it's got some flaws and would require some changes to correctly handle this "ever had" case. Personally, given the existing state of vibrate and likely low risk, I'd probably recommend just adding a UseCounter tracking all blocked vibration (if we don't already have one) and keep an eye on it while this change rolls out to beta.

lubin2010 commented 7 years ago

@RByers Yes, it would apply to the root document too. We have a histogram metrics in Blink: It shows ~5.6% of vibrate calls in the past month were being triggered while processing a user gesture, but it's not measuring this 'ever had a user gesture' case. I'll add a UserCounter for it & keep an eye on it while rolling out it. Thanks Rick for the comment.

VicenteDiaz commented 7 years ago

Thanks @lubin2010 for this new initiative to improve vibration behavior. Nevertheless, I don't understand your above sentence:

It shows ~23.5% of vibrate calls are being triggered while processing a user gesture

It means that 23.5% of users make a gesture to activate it when receiving a vibrating content? Which content? Malvertising, Haptter videos or other content?

I'm afraid that any measurement performed this way has limited use to understand user behavior with respect to vibrating content, because it will depend on the content and also on its attractiveness. Consider that a Haptter autoplayed vibrating video (with vibration and sound deactivated by default) is shown to the user (advertising or any other) and is very bad quality, ugly or is not related with user interests; probably it will generate similar user behavior and statistics than a malvertising: user won't make any gesture or just will close it, not because it vibrates (it can't!) but because he/she doesn't like it actually. So what kind of information/statistics we can get by counting such gesture activation/deactivation?

Complementary, just to provide a better experience for users that unblock vibration, according to your answer to @RByers comment, it is possible to consider a kind of "historical" approach so when a user activate vibration once, in cross-domain iframes (by a gesture), Chrome store it and allows vibrating in any future vibrating content.

In order to avoid possible abuse, different strategies can be used. For instance, if user is not exposed to vibrating content in 30 days, or user doesn't make any gesture on vibrating content when exposed to it in such a period, vibrating content in cross-origin iframes is blocked again until next user interaction with this kind of content. It behaves like a watch-dog counter.

What do you think? Thanks in advance.

lubin2010 commented 7 years ago

Thanks @VicenteDiaz for the comment.

It means that 23.5% of users make a gesture to activate it when receiving a vibrating content? Which content? Malvertising, Haptter videos or other content?

Basically, it means that for those cases, the vibrate function is called during the processing of a user gesture, but we don't have information on the type of the contents since we don't collect the contents during the metrics collecting process. BTW: The number of 23.5% was wrong: It's actually ~5.6%, and I've changed it in the original comment. sorry about that.

it is possible to "historical" approach so when a user activate vibration once, in cross-domain iframes (by a gesture), Chrome store it and allows vibrating in any future vibrating content.

We did chat about this option using the site engagement service, but the concern raised is that it would make the behavior of the vibrate API unpredictable which somehow violates this predictability effort. Also we measured the correlation between vibrate & the site engagement score, and most of them are from sites with no user engagement at all (see chromestatus): image But anyway, if this is required by a lot of web developers, we can revisit this later.

What do you think?

VicenteDiaz commented 7 years ago

You're welcome @lubin2010! ~5.6% is more realistic and, in fact those must be related to other content different from our, because we stopped publishing Haptter videos on January, as soon as we detected that Chrome was unable to vibrate in cross-origin iframes. So it is normal that no engagement is measured. That's the demonstration that such malvertising content doesn't create any interaction with users... fortunately ;-).

We just have made a small number of tests with Chrome Canary and now with Chrome Beta that, by the way, we consider it works according to our expectations when user interact with iframe.

Just another pending question is that we supposed that feature-policy, defined months ago, will still be active in this and future versions. I mean, for instance, "Feature-Policy: {"vibrate": []}". We have been trying to test this feature to provide to our editors to install in their websites and it doesn't work yet. We have used it in the head and body using <meta Feature-Policy: {"vibrate": []}> without any success, using Chrome Beta V.57.02987.88 on Android.

First of all, does this directive works in current versions? Can you help us providing an example of use of this directive in a webpage so we can test it with our haptter content?

Best regards Vicente

lubin2010 commented 7 years ago

@VicenteDiaz It seems that Feature Policy hasn't launched yet in V57. Also since vibrate is currently allowed after user gesture, the semantics of using Feature Policy for vibrate might change (eg., giving the permission of vibrate from the top-level page to subframe may not make sense any more).

Since it is directly not related to this intervention, could we move the discussion to this Feature Policy issue?

Schepp commented 6 years ago

Hey there! I'm using Vibration API to support the user while scrolling a long news page by indicating with short bursts when the user has scrolled into the next topic section. This does not work reliably anymore, since apparently what you interpret as "user gesture" is limited to a user tapping the page. Can we change things so that a scroll also counts as a valid gesture?

lubin2010 commented 6 years ago

Hi @Schepp, We changed to stricter user gestures for touch in #13 due to receiving reports of poorly written (or possibly malicious) code that takes a sensitive action in response to a touchstart event, or all touchend events including after a scroll. Would it be possible for you to try other approaches for your use case?

Also +@RByers +@ojanvafai for suggestions.

RByers commented 6 years ago

Once you tap somewhere on the page it then works for the lifetime of the page, right? @Schepp can you share a demo and/or live site example? We definitely don't want to eliminate some generally useful capability entirely (though in cases of significant abuse it is sadly sometimes necessary).

Schepp commented 6 years ago

Thanks for the quick feeback, @lubin2010 and @RByers!

It's true that once you tap the screen Vibration API turns on. The problem is: Tapping is not the first action a user does when landing on our index page. Instead the user scrolls and scans for news articles to read.

You can find a WIP of our site over here: https://templates.park.works/ Disclaimer: I was still in the middle of tuning and balancing out the tactile feedback when suddenly Chrome 60 appeared and put and end to my plan. So it's not yet brilliant but you'll get my point. Also try flicking through image libraries.

Coming back to the problem: Maybe you can whitelist the topmost window (_top) for vibrations? Or maybe you allow just short bursts like I use at above site. I noticed that those SPAM screens trigger a very long and very intrusive vibration scheme.

lubin2010 commented 6 years ago

@Schepp The site you mentioned asks for user/password to visit.

Maybe you can whitelist the topmost window (_top) for vibrations?

The topmost window was where most abuses happen, and so whitelisting it would not solve the abuse issue.

Or maybe you allow just short bursts like I use at above site. I noticed that those SPAM screens trigger a very long and very intrusive vibration scheme.

IIUC, even just allowing short bursts, the adversaries would abuse it as much as possible.

Would it be possible for the web page to add a short button/message between topic sections reminding people to click/tap to turn on the vibrate mode? It can be shown only if the call to navigator.vibrate returns false (ie., vibrate is disabled and user hasn't tapped or clicked the page).

Schepp commented 6 years ago

Would it be possible for the web page to add a short button/message between topic sections reminding people to click/tap to turn on the vibrate mode? It can be shown only if the call to navigator.vibrate returns false (ie., vibrate is disabled and user hasn't tapped or clicked the page).

@lubin2010 Nah, not really. It is a too subtle feature to ask people to activate it on every page load (which happens a lot on traditional websites). I think I'll then go for removing vibrations for scroll-position-indication as people will only be irritated by it being there sometimes and sometimes not. I still appreciate you help and I'm interested in finding other use cases for it. So thank you!

kylemacfarlane commented 6 years ago

I'm running into some problems with this.

1) Navigator.vibrate is blocked in PWAs even though we're allowed to do anything we want with audio and video and can even spam users with service worker notifications (which actually do vibrate).

2) User interactions from bluetooth keyboards are not counted as valid gestures to enable vibration.

ojanvafai commented 6 years ago

I've argued that installed apps should get all of the persistent gesture requirements. Chromium already does this for autoplay video. Seems like vibrate, etc. should be the same. If you'd be willing to file a bug (crbug.com/new) for that I can route it to the right people.

The bluetooth keyboard thing is definitely just a Chromium bug. Can you file a separate bug at crbug.com/new?

kylemacfarlane commented 6 years ago

I opened a bug for 1: https://bugs.chromium.org/p/chromium/issues/detail?id=796810

I can't find a way to reproduce 2 reliably.

ImHappyMostOfTheTime commented 6 years ago

So I've got this web site where I take orders and pass notifications back and forwards between customer and business. Thought this would be great to vibrate when a new message appears but if you reload or go to a different page it disables vibrating if you don't interact. Well customer isn't going to interact so no more vibration idea.

As we get more and more access to underlying hardware we must get these issues sorted. Getting gps permissions for example is a complete nightmare with browsers handling permissions differently and then moving permissions from place to place.

From a users point it would be nice to push a button on a web page that would display all the settings/permissions required for a web page. At the moment it's scattered or I get a long list of permissions that the web site doesn't even use.

So I'm thinking some sort of standardised permission object that we can put in a manifest and maybe an api call to optionally call bits as and when. Possibly restricted to https and only the master frame. I say the manifiest so the browser can refer to that for whether permission is required as well as manually being able to open it with a javascript call.

SjengHWK commented 5 years ago

Not been able to find anything about it, I encounter the following problem. Once I click on the iFrame, it enables vibration. However once and a while my html5 page needs to refresh. As a consequence of that vibration is disabled again. Is there anyway to keep vibration activated once activated?

lubin2010 commented 5 years ago

@ImHappyMostOfTheTime Since the feature request is more than vibrate, how about you find a new Chromium bug (crbug.com/new) to have someone triage the idea?

@SjengHWK I guess there is no such way currently. Is it possible to avoid the refresh (say using Ajax)?

johannhof commented 2 years ago

(As noted in https://github.com/WICG/interventions/pull/72, we intend to archive this repository and are thus triaging and resolving all open issues)

I filed https://github.com/w3c/vibration/issues/29 for encoding this change in the spec (and to continue related discussions if desired).