Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Useless interface exposure on non-B2G build of Gecko

60 views
Skip to first unread message

Timothy Chien

unread,
Mar 4, 2012, 3:17:52 PM3/4/12
to mozilla...@lists.mozilla.org
Hi,

I was talking with Kanru the other day on how web app authors do feature
detection: we simply check if the existence of the interface. For
example, if (!!window.Worker) or ('Worker' in window) evaluates to
true, we assume the browser supports web workers and it's safe to run
code with it.

But then I realize the practice failed on many of our newly created
mobility APIs.

If you download Nightly/Mac today, fire up Web Console and type
window.navigator.moz
, you will find mozPower, mozBattery, mozSms(*1), and mozVibrate.

Functions and properties reports useless or incorrect information when
attempt to access them on a Mac.

I understand many of them aren't support to work on desktops, or they
are incomplete code that will behavior correctly once finished(*2). But
for now I think they should be removed from DOM, or web developers will
be force to check (navigator.userAgent.indexOf('B2G') !== -1) to know if
they are real APIs.

*1 (mozSms === null) on Mac, but attempt to detect it with ('mozSms' in
window.navigator) will give false positive.

*2 We are certainly not going to enable website to power off my Mac. But
will we allow websites to check your laptop battery life?


Tim

Justin Lebar

unread,
Mar 4, 2012, 3:34:29 PM3/4/12
to Timothy Chien, mozilla...@lists.mozilla.org
> If you download Nightly/Mac today, fire up Web Console and type
> window.navigator.moz
> , you will find mozPower, mozBattery, mozSms(*1), and mozVibrate.

I think the idea was that mozPower should return null for unprivileged
websites. Similarly, I'd expect mozBattery and mozSMS to be null
where they're inaccessible. We intentionally made mozVibrate
un-feature-detectable, but we could change that.

I think we have the ability to make moz{Power,Battery,Sms} disappear
completely in a build, but then no page would be able to use those
interfaces. That is, if any page can access mozPower, then for all
pages, |'mozPower' in window.navigator| must return true. Thus if we
wanted |'mozPower' in navigator| to be the way to feature-detect
mozPower, then pages without access to mozPower on B2G would get a
false-positive.

So I think the way to detect these features should be

if ('mozSms' in navigator && navigator.mozSMS)

> Functions and properties reports useless or incorrect information when
> attempt to access them on a Mac.
>
> I understand many of them aren't support to work on desktops, or they are
> incomplete code that will behavior correctly once finished(*2). But for now
> I think they should be removed from DOM, or web developers will be force to
> check (navigator.userAgent.indexOf('B2G') !== -1) to know if they are real
> APIs.
>
> *1 (mozSms === null) on Mac, but attempt to detect it with ('mozSms' in
> window.navigator) will give false positive.
>
> *2 We are certainly not going to enable website to power off my Mac. But
> will we allow websites to check your laptop battery life?
>
>
> Tim
>
> _______________________________________________
> dev-b2g mailing list
> dev...@lists.mozilla.org
> https://lists.mozilla.org/listinfo/dev-b2g

Dean Landolt

unread,
Mar 5, 2012, 9:13:23 AM3/5/12
to Timothy Chien, mozilla...@lists.mozilla.org
On Sun, Mar 4, 2012 at 3:17 PM, Timothy Chien <timd...@gmail.com> wrote:

> Hi,
>
> I was talking with Kanru the other day on how web app authors do feature
> detection: we simply check if the existence of the interface. For example,
> if (!!window.Worker) or ('Worker' in window) evaluates to true, we assume
> the browser supports web workers and it's safe to run code with it.
>
> But then I realize the practice failed on many of our newly created
> mobility APIs.
>
> If you download Nightly/Mac today, fire up Web Console and type
> window.navigator.moz
> , you will find mozPower, mozBattery, mozSms(*1), and mozVibrate.
>
> Functions and properties reports useless or incorrect information when
> attempt to access them on a Mac.
>
> I understand many of them aren't support to work on desktops, or they are
> incomplete code that will behavior correctly once finished(*2). But for now
> I think they should be removed from DOM, or web developers will be force to
> check (navigator.userAgent.indexOf('**B2G') !== -1) to know if they are
> real APIs.
>
> *1 (mozSms === null) on Mac, but attempt to detect it with ('mozSms' in
> window.navigator) will give false positive.
>
> *2 We are certainly not going to enable website to power off my Mac. But
> will we allow websites to check your laptop battery life?
>



Somewhat OT but why shouldn't a website be able to request this capability,
and why shouldn't a user be able to grant it?

ISTM the current approach to feature-detection conflates the availability
of a capability with the ability to request a capability. These two things
are very different.

It would be nice if there were a somewhat consistent way to do either, and
in a more granular fashion than asking whether *mozPower *exists. What if
you want an app to be able to check your power level but not turn off your
device (that device potentially being your desktop or laptop even)?

As more and more sites gain more and more caps the fundamental interactions
around granting, browsing and revoking capabilities will have to be rock
solid and perfectly clear to users anyway. And WRT non-mobile devices, if
users and/or it staff don't like being able to grant certain caps to apps
they should be able to globally disable them via about:config.

Related: is there ever really a need to be able to detect whether a feature
is available but denied vs. completely unavailable on a given device? And
if so, would revealing this be considered a privacy concern? (Apologies if
this has been covered: I'm new here and just catching up -- really excited
about the prospects for b2g!)

Justin Lebar

unread,
Mar 5, 2012, 10:00:06 AM3/5/12
to Dean Landolt, mozilla...@lists.mozilla.org, Timothy Chien
> Somewhat OT but why shouldn't a website be able to request this capability,
> and why shouldn't a user be able to grant it?

There's a whole discussion about the permissions model going on on
this mailing list. You might want to check it out.

> It would be nice if there were a somewhat consistent way to do either, and
> in a more granular fashion than asking whether *mozPower *exists. What if
> you want an app to be able to check your power level but not turn off your
> device (that device potentially being your desktop or laptop even)?

You might want to check out what actually lives on mozPower. The
device's battery level does not live there.

mozPower is a super-user level interface which lets you turn off the
device, turn off the screen, and determine whether other pages/apps
are trying to keep the device/screen alive via wake locks. It doesn't
make any sense for two pages to use mozPower, since they'd conflict
with each other.

But check out the permissions thread for discussion about the general idea.

Dean Landolt

unread,
Mar 5, 2012, 12:29:05 PM3/5/12
to Justin Lebar, mozilla...@lists.mozilla.org, Timothy Chien
On Mon, Mar 5, 2012 at 10:00 AM, Justin Lebar <justin...@gmail.com>wrote:

> > Somewhat OT but why shouldn't a website be able to request this
> capability,
> > and why shouldn't a user be able to grant it?
>
> There's a whole discussion about the permissions model going on on
> this mailing list. You might want to check it out.
>

Yeah, working through all that now.


> > It would be nice if there were a somewhat consistent way to do either,
> and
> > in a more granular fashion than asking whether *mozPower *exists. What if
> > you want an app to be able to check your power level but not turn off
> your
> > device (that device potentially being your desktop or laptop even)?
>
> You might want to check out what actually lives on mozPower. The
> device's battery level does not live there.
>

Yeah, sorry -- again, new here, though I actually did know this, just
easily confused as I haven't really internalized these APIs since I don't
use them yet.


> mozPower is a super-user level interface which lets you turn off the
> device, turn off the screen, and determine whether other pages/apps
> are trying to keep the device/screen alive via wake locks. It doesn't
> make any sense for two pages to use mozPower, since they'd conflict
> with each other.
>

Why are these conflicts on a desktop or laptop and not on a phone? If I'm
reading this [1] correct you draw a distinction between background and
foreground tabs, and go to great pains to ensure sane behavior. You even
suggest the authorization message in c103, equating it to geolocation. Is
that what you mean by a "super-user level interface"? ISTM it's just like
any other capability that could be granted or retracted.

My broader point was that there's more granularity to feature testing
than *does
this environment have a certain API*. Have permission to hold a wake lock
is a lot different than having permission to reboot. That's all I was
trying to say. For instance, I slapped together a little b2g clock app [2]
over the weekend and I'd love to be able to wake lock, but obviously it
doesn't need a shutdown capability. (It *could *use a brightness control
capability though -- has that been proposed yet?).

[1] https://bugzilla.mozilla.org/show_bug.cgi?id=697132
[2] https://github.com/deanlandolt/gorgy-clock


> But check out the permissions thread for discussion about the general idea.
>

Will do. Thanks.

Robert Kaiser

unread,
Mar 5, 2012, 12:54:25 PM3/5/12
to mozilla...@lists.mozilla.org
Timothy Chien schrieb:
> I was talking with Kanru the other day on how web app authors do feature
> detection: we simply check if the existence of the interface. For
> example, if (!!window.Worker) or ('Worker' in window) evaluates to true,
> we assume the browser supports web workers and it's safe to run code
> with it.

Actually, what I mostly read in examples (and used myself a lot) is just
|if (window.Worker)| and similar tests, taking into account that null or
undefined evaluate to false in such expressions in JS, and having an
actual object/value there evaluates to true.

At least AFAIK that's the usually proposed way of feature detection in
JS and has been for some time - and AFAIK, window.mozBattery works fine
with that (haven't checked the others).

Robert Kaiser

Timothy Chien

unread,
Mar 6, 2012, 1:15:42 AM3/6/12
to Robert Kaiser, mozilla...@lists.mozilla.org
Even with detection with |if (window.navigator.mozBattery)|, it would
give false positive on Nightly/Mac. |window.navigator.mozBattery| does
not evalute to falsy value on OSes it does not support.

>
> Robert Kaiser

Timothy Chien

unread,
Mar 6, 2012, 1:15:58 AM3/6/12
to Robert Kaiser, mozilla...@lists.mozilla.org


On 3/6/12 1:54 AM, Robert Kaiser wrote:

Justin Lebar

unread,
Mar 6, 2012, 9:52:44 AM3/6/12
to Timothy Chien, Mounir Lamouri, dev...@lists.mozilla.org
> Even with detection with |if (window.navigator.mozBattery)|, it would give
> false positive on Nightly/Mac. |window.navigator.mozBattery| does not
> evalute to falsy value on OSes it does not support.

Mounir, is this correct?

It looks like mozbattery is not implemented on Mac (it always returns
charging==1, even when my power adapter is unplugged), but I still
have a non-null mozbattery object...

Mounir Lamouri

unread,
Mar 6, 2012, 10:00:14 AM3/6/12
to dev...@lists.mozilla.org
Indeed, there is no backend for Battery API no MacOS X.

--
Mounir

Justin Lebar

unread,
Mar 6, 2012, 10:11:11 AM3/6/12
to Mounir Lamouri, dev...@lists.mozilla.org
> Indeed, there is no backend for Battery API no MacOS X.

So what's the reasoning behind navigator.mozBattery returning a
non-falsey value on MacOS X?

Robert Kaiser

unread,
Mar 6, 2012, 10:42:43 AM3/6/12
to mozilla...@lists.mozilla.org
Timothy Chien schrieb:
> Even with detection with |if (window.navigator.mozBattery)|, it would
> give false positive on Nightly/Mac. |window.navigator.mozBattery| does
> not evalute to falsy value on OSes it does not support.

That's actually an interesting case. If it wasn't implemented in any way
or not activated, we'd get a false-y value. As the interface itself is
implemented, we get a true-y value, but as the backend to the interface
isn't implemented, we get some default values.
I think it might be better to get a null value in the first place, just
if the implementation exists but is deactivated. For devices where we'd
have a backend but the device doesn't have a battery, using those
default values that are detectable as at least "running on non-battery
power", maybe even have some way to detect that there's no battery at
all, is surely the better option.

That's what I think as someone not directly involved with all the work,
at least. ;-)

Robert Kaiser

Mounir Lamouri

unread,
Mar 6, 2012, 11:00:13 AM3/6/12
to Justin Lebar, dev...@lists.mozilla.org
The reason is that the DOM code doesn't know that (though, we could make
it know it).
What we do instead is that when the backend doesn't exist for a specific
platform, a fallback code is used and this fallback returns some
defaults value that should make sure the code will follow the
appropriate path. In other words, when there is no backend, the values
returned are equivalent to the device being plugged and fully charged
(NOTE: we use the same defaults for desktops). That way, the code should
go to the path it would have been using if it didn't know what was the
battery status.

So, returning 'null' or an object for navigator.battery in that case
seems to be a detail. And, in the long term, we will not have to worry
about that.

--
Mounir

Justin Lebar

unread,
Mar 6, 2012, 11:10:28 AM3/6/12
to Mounir Lamouri, dev...@lists.mozilla.org
> What we do instead is that when the backend doesn't exist for a specific
> platform, a fallback code is used and this fallback returns some
> defaults value that should make sure the code will follow the
> appropriate path. In other words, when there is no backend, the values
> returned are equivalent to the device being plugged and fully charged
> (NOTE: we use the same defaults for desktops).

Is this for fingerprinting reasons, or just because it's easy?

If we're not concerned about fingerprinting, then giving pages some
way to tell that "this is not a battery-powered device" seems pretty
reasonable. Then we could, for devices whose batteries we don't
understand (like the Mac) just pretend to be a desktop.

Mounir Lamouri

unread,
Mar 6, 2012, 11:12:54 AM3/6/12
to Justin Lebar, dev...@lists.mozilla.org
On 03/06/2012 05:10 PM, Justin Lebar wrote:
>> What we do instead is that when the backend doesn't exist for a specific
>> platform, a fallback code is used and this fallback returns some
>> defaults value that should make sure the code will follow the
>> appropriate path. In other words, when there is no backend, the values
>> returned are equivalent to the device being plugged and fully charged
>> (NOTE: we use the same defaults for desktops).
>
> Is this for fingerprinting reasons, or just because it's easy?

Indeed, for fingerprinting reasons, we prefer not to tell the page if
the device has or not a battery. There is only one use case where this
is actually needed: for apps that want to show a UI with the battery
status. Though, we will handle that use case later in this same API or
another like a possible Device Capability API.

--
Mounir
0 new messages