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

Hardware enable/disable switch and mozSettings, a complication and solution

59 views
Skip to first unread message

Tim Guan-tin Chien

unread,
Dec 29, 2014, 9:39:38 PM12/29/14
to mozilla...@lists.mozilla.org, dev-w...@lists.mozilla.org, Arthur Chen, Hsinyi Tsai, Vincent Chang, Alive Kuo
TL;DR: I proposed all hardware API switches to not only move out of
mozSettings database, but also have the API taking it's own
responsibility to make the settings persistent, and expose the current
value and changes through the API.

Hi,

I would like to make sure we reach a consensus on we should deal with
hardware switches and it's relations with mozSettings.

Back in FxOS v1.0 we made a mistake moving some hardware switches to
mozSettings, and it's problem to cause a lot of headaches. The boolean
in the settings is proven to be not enough to reflect the status of
API (e.g. is being enabled, or failed to be enabled) and a lot of bugs
was caused by this. People then was mostly agreed we should move the
switches back to the APIs, e.g. mozMobileConnection.setRadioEnabled()
and returns a Promise.

Yet, once the switch has been move out of the API, we have not yet
decided what we should do with mozSettings. The settings is still
needed because we would like to keep the user preference persistent
across reboot (e.g. when the radio is turned on|off, it stay on|off
when the phone reboots). But then we have the problem who is
responsible of setting and getting these settings.

1. If we let the API caller (e.g. Settings app) to set the
mozSettings, we would have to do

(A) in Settings app
mozMobileConnection.setRadioEnabled(val)
.then(function() {
return navigator.mozSettings.createLock().set( ... );
});

and (B) in Systems app when the phone boots.

navigator.mozMobileConnection.createLock().get( ... )
.then(function(value) {
return mozTelephony.setRadioEnabled(value);
});

This is undesirable because

1. Not every API switch caller do (A) has access to mozSettings should
the API become privileged, and even if they do we can never sure they
have indeed updated the settings correctly.
2. (B) currently contributes to phone boot-up time a lot, which is
documented in bug 1095034 ("Too much IndexedDB on startup").

So I talked to Hsinyi, Alive, and Arthur, and I come up with the proposal
and they agree: I propose the responsibility of keep the status should be
moved from Gaia to Gecko, specifically, each of the APIs should keep
their own status in a clean way, and simply remove the mozSettings key
altogether. The API can keep the value in Gecko pref, which we can
make sure the hardware status and the pref is always in sync, and Gaia
will take the value returned from API (a |getRadioEnabled| method for
example, or an |radioEnabled| property?) as a single source of truth.
We would also need the API to send a change event to all document when
the status changes.

Thoughts and comments? Thanks.


Tim

Kevin Grandon

unread,
Dec 29, 2014, 11:18:46 PM12/29/14
to Tim Guan-tin Chien, Arthur Chen, dev-w...@lists.mozilla.org, mozilla...@lists.mozilla.org, Alive Kuo, Vincent Chang, Hsinyi Tsai
Just curious, would this be a non-issue if we stored more information than just a boolean? What if we stored additional information say, in JSON? Have we thought about using datastore?

As we've seen in the past moving stuff into gecko can be a slippery slope, so we should definitely think this out thoroughly. In any case, it seems that this might create a more friendly API for third party developers, so a +1 from me on that front.

It does seem like a *lot* of work though. I think it'd be worth while to do an initial investigation on both a platform fix and a different store in gaia to make sure we invest our time wisely.

Best,
Kevin

_______________________________________________
dev-webapi mailing list
dev-w...@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-webapi

Alive

unread,
Dec 29, 2014, 11:28:33 PM12/29/14
to Tim Guan-tin Chien, Kevin Grandon, Arthur Chen, dev-w...@lists.mozilla.org, Vincent Chang, mozilla...@lists.mozilla.org, Hsinyi Tsai
於 2014年12月30日 於 下午12:18:26, Kevin Grandon (kgra...@mozilla.com) 寫:
Just curious, would this be a non-issue if we stored more information than just a boolean? What if we stored additional information say, in JSON? Have we thought about using datastore?

I think the problem is the race. You won’t know how long the datastore/settings db will callback, and the callback from enabling to enabled really does not mean navigator.HARDWARE.status is ‘enabled’ because the database operation is async and anything could happen during the database observer operation.

But if the hardware API has status change event we could make sure we always have the correct status in the callback.

Shian-Yow Wu

unread,
Dec 29, 2014, 11:40:57 PM12/29/14
to Tim Guan-tin Chien, Arthur Chen, dev-w...@lists.mozilla.org, mozilla...@lists.mozilla.org, Alive Kuo, Vincent Chang, Hsinyi Tsai
Current:
Gaia app (e.g. Settings app) <--> mozSettings for hardware switch <--> Gecko pref

Proposed solution:
Gaia app (e.g. Settings app) <--> API for hardware switch <--> Gecko pref

Above is my understanding, is it correct?

Maintaining two kinds of configuration for one purpose is an overhead.  If the proposed solution is the right direction, should we consider all conditions than just hardware switches?  For example, we have Gecko pref for proxy server, but they are not configurable by user on Firefox OS.  To allow configuration by Gaia app, we can either: 1) create new API that directly accesses Gecko pref, or 2) create new mozSettings and maintain the mapping to Gecko pref.  In such case, which way do we encourage to use?

--
Shian-Yow

Hsin-Yi Tsai

unread,
Dec 29, 2014, 11:45:00 PM12/29/14
to Alive, Tim Guan-tin Chien, Kevin Grandon, Arthur Chen, dev-w...@lists.mozilla.org, Vincent Chang, mozilla...@lists.mozilla.org
Hi all,

One more question: with this new proposal, how are applications going to display "user preference" instead of a current state, like what we've done in utility tray? Need one more attribute?

Best regards,
Hsinyi


Alive 於 12/30/2014 12:28 PM 寫道:
於 2014年12月30日 於 下午12:18:26, Kevin Grandon (kgra...@mozilla.com) 寫:
Just curious, would this be a non-issue if we stored more information than just a boolean? What if we stored additional information say, in JSON? Have we thought about using datastore?

I think the problem is the race. You won’t know how long the datastore/settings db will callback, and the callback from enabling to enabled really does not mean navigator.HARDWARE.status is ‘enabled’ because the database operation is async and anything could happen during the database observer operation.

But if the hardware API has status change event we could make sure we always have the correct status in the callback.

As we've seen in the past moving stuff into gecko can be a slippery slope, so we should definitely think this out thoroughly. In any case, it seems that this might create a more friendly API for third party developers, so a +1 from me on that front.

It does seem like a *lot* of work though. I think it'd be worth while to do an initial investigation on both a platform fix and a different store in gaia to make sure we invest our time wisely.

Best,
Kevin
On Mon, Dec 29, 2014 at 9:39 PM, Tim Guan-tin Chien <timd...@mozilla.com> wrote:



-- 
Hsin-Yi Tsai 蔡欣宜
Mozilla Taiwan
ht...@mozilla.com

Tim Guan-tin Chien

unread,
Dec 30, 2014, 12:30:26 AM12/30/14
to Shian-Yow Wu, Arthur Chen, dev-w...@lists.mozilla.org, mozilla...@lists.mozilla.org, Alive Kuo, Vincent Chang, Hsinyi Tsai
On Tue, Dec 30, 2014 at 12:40 PM, Shian-Yow Wu <s...@mozilla.com> wrote:
> Current:
> Gaia app (e.g. Settings app) <--> mozSettings for hardware switch <--> Gecko
> pref
>
> Proposed solution:
> Gaia app (e.g. Settings app) <--> API for hardware switch <--> Gecko pref
>
> Above is my understanding, is it correct?

Correct.

> Maintaining two kinds of configuration for one purpose is an overhead. If
> the proposed solution is the right direction, should we consider all
> conditions than just hardware switches? For example, we have Gecko pref for
> proxy server, but they are not configurable by user on Firefox OS. To allow
> configuration by Gaia app, we can either: 1) create new API that directly
> accesses Gecko pref, or 2) create new mozSettings and maintain the mapping
> to Gecko pref. In such case, which way do we encourage to use?

The problem with (1) (or (2), which is the current solution), is that
it is always susceptible to race unless proven otherwise.
With a simple write op to pref or settings, caller do not know when
Gecko will apply that config, or to respond when the setting failed to
apply.

The hardware switches are the most obvious cases, but I suspect almost
every other cases are affected.


On Tue, Dec 30, 2014 at 12:18 PM, Kevin Grandon <kgra...@mozilla.com> wrote:
> Just curious, would this be a non-issue if we stored more information than
> just a boolean? What if we stored additional information say, in JSON? Have
> we thought about using datastore?
>

The other approach, not mentioned on the original e-mail, is to tie
the mozSettings even closer to the API, which allow the API to
participate in the db lock and reject the changes when it fail to
apply. I suspect there will be complex settings that would need this,
but I object enabling mozSettings to do this for all APIs in general.

> As we've seen in the past moving stuff into gecko can be a slippery slope,
> so we should definitely think this out thoroughly. In any case, it seems
> that this might create a more friendly API for third party developers, so a
> +1 from me on that front.
>
> It does seem like a *lot* of work though. I think it'd be worth while to do
> an initial investigation on both a platform fix and a different store in
> gaia to make sure we invest our time wisely.
>

Yes, the efforts are non-trival. But this is one of the underlining
issues preventing FxOS to be a stable platform.
I am all ears for solutions to the problem that could solve this
cheaply -- and I want to make sure new API does not repeat the mistake
we already made.

Tim Guan-tin Chien

unread,
Dec 30, 2014, 12:34:51 AM12/30/14
to Hsin-Yi Tsai, Arthur Chen, dev-w...@lists.mozilla.org, mozilla...@lists.mozilla.org, Alive, Vincent Chang, Kevin Grandon
On Tue, Dec 30, 2014 at 12:44 PM, Hsin-Yi Tsai <ht...@mozilla.com> wrote:
> Hi all,
>
> One more question: with this new proposal, how are applications going to
> display "user preference" instead of a current state, like what we've done
> in utility tray? Need one more attribute?
>

Most of the time, interfaces are designed to be a both read and write
interface for user (e.g. checkbox).
I am not entirely sure what you mean by utility tray. The quick
settings buttons exhibits the same behavior.

If the user are allowed to change things and only apply when they say
so, I would imaging such UI be placed in a dialog with Back/OK buttons
(and with OK means apply now)

Tim Guan-tin Chien

unread,
Dec 30, 2014, 1:10:18 AM12/30/14
to Shian-Yow Wu, Arthur Chen, dev-w...@lists.mozilla.org, mozilla...@lists.mozilla.org, Alive Kuo, Vincent Chang, Hsinyi Tsai
On Tue, Dec 30, 2014 at 1:29 PM, Tim Guan-tin Chien
<timd...@mozilla.com> wrote:
> On Tue, Dec 30, 2014 at 12:40 PM, Shian-Yow Wu <s...@mozilla.com> wrote:
>> Current:
>> Gaia app (e.g. Settings app) <--> mozSettings for hardware switch <--> Gecko
>> pref
>>
>> Proposed solution:
>> Gaia app (e.g. Settings app) <--> API for hardware switch <--> Gecko pref
>>
>> Above is my understanding, is it correct?
>
> Correct.
>

Sorry, I should correct this one. I am not saying we should have a
dedicated API for hardware switches, I am saying the given hardware
API should provide the method to turn on/off given hardware, and the
API should also keep the on/off state persistent by, for example,
keeping the state in Gecko pref.

Tim Guan-tin Chien

unread,
Dec 30, 2014, 2:43:21 AM12/30/14
to Hsin-Yi Tsai, Arthur Chen, dev-w...@lists.mozilla.org, mozilla...@lists.mozilla.org, Alive, Vincent Chang, Kevin Grandon
Hi all,

I just talk to Hsin-Yi offline and I would like to make some
clarification here, by means of describing steps to run when the said
method is called:

A. Steps to do when setFooEnabled(false) is called:

1. If the state is not "enabled", reject the promise and stop.
2. If not, switch the property to "disabling".
2. Dispatch a property change event.
3. Submit the disable request to the relevant hardware.
4. If the request is fulfilled by the hardware,
4.1 Switch the property to "disabled".
4.2 Set the persistent state to "disabled".
4.3 Dispatch a property change event.
4.4 Resolve the promise.
5. If the request is rejected by the hardware,
5.1 Switch the property back to "enabled".
5.2 Dispatch a property change event.
5.3 Reject the promise.

B. Steps to do when the phone boots:

1. The state should start with "disabled".
2. If the persistent state is "enabled", run steps as if
|setFooEnabled(true)| is called.

The important thing to clarify is section A point 4.2: Persistent
state (e.g. Gecko pref) should not change if the request to hardware
is rejected -- therefore, a failed setFooEnabled() call should not
result any side effect.

Also, the switch state has no requirement to bind the hardware state
-- such as network state of the WIFI or RIL. It's up to the API or the
hardware to define the requirement to fulfill the hardware request
(e.g. the already connected network must be disconnect before we
fulfilled the hardware-disable request). The only requirement here is
section A point 1: to prevent race (to the hardware or the UI), we
should reject the API call when the state machine is "working" (i.e.
"enabling" or "disabling") or when the operation is simply invalid
(i.e. the state is already "disabled").

Thanks,

Tim

Yoshi Huang

unread,
Dec 30, 2014, 6:14:14 AM12/30/14
to Tim Guan-tin Chien, Arthur Chen, dev-w...@lists.mozilla.org, mozilla...@lists.mozilla.org, Alive, Vincent Chang, Hsin-Yi Tsai, Kevin Grandon
Hi Tim
Will `make reset-gaia` also clear the prefs in Gecko back to original settings?
If it couldn't, how does Gecko know it should go to the 'Default' state instead of the previous state before rebooting?
If it could, that will surpise me because it *resets* not only gaia but also some gecko bits.

Also the enabling/disabling states should be left to API implementation.
For example, In NFC it has different power states, the state used in P2P sharing and in Card Emulation mode are different.
Adding many 'ING' states, IMO, could make the API difficult to use.

Thanks


Tim

_______________________________________________
dev-webapi mailing list
dev-w...@lists.mozilla.org

Jonas Sicking

unread,
Dec 30, 2014, 9:48:32 PM12/30/14
to Tim Guan-tin Chien, Arthur Chen, dev-w...@lists.mozilla.org, mozilla...@lists.mozilla.org, Alive, Vincent Chang, Hsin-Yi Tsai, Kevin Grandon
As a user, I'm not sure that this is the behavior that I want.

The most simple scenario is if I turn off wifi, but the phone crashes
before the wifi radio has been fully shut down, I think I'd prefer
that the wifi was off after bootup.

A slightly more complex scenario is if I turn on wifi, but for some
reason wifi fails to turn on, do I really want the phone to give up
rather than try again? Especially after a reboot which might actually
fix some broken state in the wifi driver? This scenario is a more
complex though since I don't know under what circumstances wifi would
actually fail to turn on?

One possible solution is to separate "desired state" from "hardware
state". So when setFooEnabled(true) is called, we'd immediately save
the new value in prefs, and then reflect "enabled" in a "desired
state" property. But the "hardware state" property would behave as you
describe above and would switch to "enabling". If turning the hardware
on fails, the "hardware state" would switch back to "disabled".
However the "desired state" would still reflect "enabled". The API
could then retry to turn on the hardware if that's appropriate.

If we did this we could technically still use mozSettings to track the
"desired state", and the individual API to track the "hardware state".
But that might just make for a more complex API. But might mean
smaller changes compared to what we have now.

I do agree that this is a more complex system though. And one that
requires UI authors to deal with more state and more complexity.

So I'm happy to go with what you are proposing if people think that
makes everyone's life simpler.

/ Jonas

Tim Guan-tin Chien

unread,
Dec 30, 2014, 10:00:18 PM12/30/14
to Yoshi Huang, Arthur Chen, dev-w...@lists.mozilla.org, mozilla...@lists.mozilla.org, Alive, Vincent Chang, Hsin-Yi Tsai, Kevin Grandon
Hi Yoshi,

On Tue, Dec 30, 2014 at 7:14 PM, Yoshi Huang <allsta...@mozilla.com> wrote:
> Hi Tim
> Will `make reset-gaia` also clear the prefs in Gecko back to original
> settings?
> If it couldn't, how does Gecko know it should go to the 'Default' state
> instead of the previous state before rebooting?

|make reset-gaia| purges the profile, which includes prefs.js -- so
the only state should reset to the pref default.

> If it could, that will surpise me because it *resets* not only gaia but also
> some gecko bits.
>
> Also the enabling/disabling states should be left to API implementation.
> For example, In NFC it has different power states, the state used in P2P
> sharing and in Card Emulation mode are different.
> Adding many 'ING' states, IMO, could make the API difficult to use.

So it sounds like the NFC hardware are duo-purposed -- it can be
disabled, enable-to-card-emulation-mode, or enable-to-p2p-mode.

I agree it can be complex if we want to put all the states in one
|setFooEnabled(enum)| -- therefore in this example I don't think we
should, nor we most.

You can always keep the switch 2-state and introduce another 2-state
switch to switch between two enable-* states.

Tim Guan-tin Chien

unread,
Dec 30, 2014, 10:56:28 PM12/30/14
to Jonas Sicking, Arthur Chen, dev-w...@lists.mozilla.org, mozilla...@lists.mozilla.org, Alive, Vincent Chang, Hsin-Yi Tsai, Kevin Grandon
This can be solved if we write the pref to disk before calling the
hardware, and revert it if the hardware fail to fulfill the request.
The behavior can be kept internally to API implementations.

> A slightly more complex scenario is if I turn on wifi, but for some
> reason wifi fails to turn on, do I really want the phone to give up
> rather than try again? Especially after a reboot which might actually
> fix some broken state in the wifi driver? This scenario is a more
> complex though since I don't know under what circumstances wifi would
> actually fail to turn on?

This proposal is deliberately flawed to work with broken hardware.
Instead of quietly trying to call the hardware for the user (before
and after the reboot), the proposal is trying to be explicit to user
when hardware fail to fulfill the request(s).

> One possible solution is to separate "desired state" from "hardware
> state". So when setFooEnabled(true) is called, we'd immediately save
> the new value in prefs, and then reflect "enabled" in a "desired
> state" property. But the "hardware state" property would behave as you
> describe above and would switch to "enabling". If turning the hardware
> on fails, the "hardware state" would switch back to "disabled".
> However the "desired state" would still reflect "enabled". The API
> could then retry to turn on the hardware if that's appropriate.
>
> If we did this we could technically still use mozSettings to track the
> "desired state", and the individual API to track the "hardware state".
> But that might just make for a more complex API. But might mean
> smaller changes compared to what we have now.
>

The proposal is designed such that "desired state" and "hardware
state" is kept in sync as closely as possible, streamlining the
interfaces between three. What you are describing is what we are doing
right now -- keeping the desired state in mozSettings and have the API
to track the changes and try to achieve the described hardware state.

It's proven to be complex for both Gecko and Gaia, when the user
attempt to toggle many times in a short interval -- something fairly
common being tried by QA forks.

I) For Gecko, since there is no way to deny changes in desired state,
it would always have to "catch up" with the changes, presumably by
queue the state change and send the requests to hardware one-by-one.
II) For Gaia, we would have hard time to find the right timing for
disabling/re-enabling the UI (to express the "working" state and
provide a "cool down" period). Oh, and doing that on all toggles of
the same setting on different apps.

> I do agree that this is a more complex system though. And one that
> requires UI authors to deal with more state and more complexity.
>

Exactly.

There is one even simpler alternative: We drop the UI requirement of
(II) and ensure every Gecko API have (I) properly implemented. But
then we will get bugs like "I am able to toggle 'airplane mode' 5
times in 1 sec but the icon only shows up after 1 minute." and we
would have to argue that it's not a bug :)

Jonas Sicking

unread,
Jan 5, 2015, 8:50:08 PM1/5/15
to Tim Guan-tin Chien, Arthur Chen, dev-w...@lists.mozilla.org, mozilla...@lists.mozilla.org, Alive, Vincent Chang, Hsin-Yi Tsai, Kevin Grandon
On Tue, Dec 30, 2014 at 7:56 PM, Tim Guan-tin Chien
I guess what I'm saying is that I'm not convinced that this makes for
a good UX. I know that it's quite annoying when I accidentally turn on
or off some piece of hardware, and have to wait a few seconds before I
can "undo" it.

I'd rather be able to flick the switch as much as I want, and have a
status indicator next to the switch indicating if the hardware is
currently on/off/switching.

But if the complexity to make that work is really too hard, then I
agree that we might have more important things to work on.

> It's proven to be complex for both Gecko and Gaia, when the user
> attempt to toggle many times in a short interval -- something fairly
> common being tried by QA forks.
>
> I) For Gecko, since there is no way to deny changes in desired state,
> it would always have to "catch up" with the changes, presumably by
> queue the state change and send the requests to hardware one-by-one.
> II) For Gaia, we would have hard time to find the right timing for
> disabling/re-enabling the UI (to express the "working" state and
> provide a "cool down" period). Oh, and doing that on all toggles of
> the same setting on different apps.
>
>> I do agree that this is a more complex system though. And one that
>> requires UI authors to deal with more state and more complexity.
>>
>
> Exactly.
>
> There is one even simpler alternative: We drop the UI requirement of
> (II) and ensure every Gecko API have (I) properly implemented. But
> then we will get bugs like "I am able to toggle 'airplane mode' 5
> times in 1 sec but the icon only shows up after 1 minute." and we
> would have to argue that it's not a bug :)

We don't really have to queue up all changes. I.e. if the user
switches airplane mode on/off 5 times while gecko is still in the
process of turning airplane mode on for the first time, we don't need
to turn it on/off 4 more times. We'll just check the current state
compared to the desired state, and if they are not in sync change one
more time.

/ Jonas
0 new messages