Closed Bug 1107539 Opened 10 years ago Closed 7 years ago

Move Geolocation HAL into system daemon on FxOS

Categories

(Core :: DOM: Geolocation, defect)

All
Gonk (Firefox OS)
defect
Not set
normal

Tracking

()

RESOLVED WONTFIX

People

(Reporter: tzimmermann, Assigned: tzimmermann)

References

Details

Attachments

(13 files, 34 obsolete files)

66 bytes, text/x-github-pull-request
Details | Review
16.06 KB, patch
Details | Diff | Splinter Review
28.56 KB, patch
Details | Diff | Splinter Review
24.07 KB, patch
Details | Diff | Splinter Review
23.46 KB, patch
Details | Diff | Splinter Review
14.17 KB, patch
Details | Diff | Splinter Review
45.48 KB, patch
Details | Diff | Splinter Review
40.44 KB, patch
Details | Diff | Splinter Review
52 bytes, text/x-github-pull-request
Details | Review
49 bytes, text/x-github-pull-request
Details | Review
52 bytes, text/x-github-pull-request
Details | Review
52 bytes, text/x-github-pull-request
Details | Review
61.44 KB, patch
Details | Diff | Splinter Review
QC provides their own implementation for the Geolocation service on FxOS. Constant changes within libxul.so require porting efforts and prevent existing devices from being updated.

A possible solution for these problems is moving the Geolocation code on FxOS to an external daemon that speaks a semi-stable* IPC protocol. Gecko will only implement some IPC stubs.

As a result, QC devs will be able to replace the daemon with their own implementation; Mozilla devs will be able to update devices' Gecko binary without breaking Geolocation support.

This bug is for investigating and discussing the approach.

* Geolocation's API is quite small and stable. We don't expect major changes.
I volunteered to provide a proof-of-concept implementation within the next months.
Blocks: 1097229
have you made any headway on this proof-of-concept?
Flags: needinfo?(tzimmermann)
Not yet, sorry. I've been busy with Bluetooth recently. I'll try to make progress during Q2.

I recently implemented a daemon for Android's Bluetooth driver. My plan is to take its IPC code and replace the Bluetooth operations with Geolocation. Should be straight-forward.
Flags: needinfo?(tzimmermann)
Hi,

I just read through bug 1097229. I'm wondering if we can join forces somehow?

For the Bluetooth daemon, I first wrote a set of interface classes [1] that can be implemented by any driver. In case you're familiar with Bluedroid, you'll recognize the individual methods. Then I added an implementation that calls the Android driver directly. [2] And finally I added support for the daemon. [3] The IPC protocol is defined by BlueZ. [4]

We run the code for the daemon's IPC on the I/O thread. There are several classes for communicating between main thread and I/O thread in [5]. The packing, unpacking and type conversion for the IPC messages is generic [6] and generated by the C++ compiler at build time.

For each version of Android, we pick a fix revision of the IPC protocol. Differences between Android versions are currently handled by ifdef in Gecko's backend code. Gecko's core Bluetooth code is version-agnostic. Some Bluedroid drivers contain vendor extensions. We can work around them in the daemon. In the case of an update of Gecko, the daemon would not be affected. And Bluetooth continues to work because the IPC protocol didn't change.

A similar strategy could be taken for Geolocation. The IPC protocol can be defined by replacing Bluetooth primitives with Geolocation primitives. Most of Bluetooth's IPC code is generic. It can be used for Geolocation as well, as long it's not specific to Bluetooth types.

[1] https://mxr.mozilla.org/mozilla-central/source/dom/bluetooth/BluetoothInterface.h#542
[2] https://mxr.mozilla.org/mozilla-central/source/dom/bluetooth/bluedroid/BluetoothHALInterface.h#15
[3] https://mxr.mozilla.org/mozilla-central/source/dom/bluetooth/bluedroid/BluetoothDaemonInterface.h#22
[4] https://git.kernel.org/cgit/bluetooth/bluez.git/tree/android/hal-ipc-api.txt
[5] https://mxr.mozilla.org/mozilla-central/source/dom/bluetooth/BluetoothInterfaceHelpers.h
[6] https://mxr.mozilla.org/mozilla-central/source/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.h
See Also: → 1097229
Hi Dave

(In reply to Dave Huseby [:huseby] from comment #2)
> have you made any headway on this proof-of-concept?

I pushed some (untested) code to [1]. It contains support for basic GPS functionality. I'll more features over the next weeks.

[1] https://github.com/tdz/platform_system_geolocationd
Assignee: nobody → tzimmermann
Status: NEW → ASSIGNED
Comment on attachment 8585534 [details]
https://github.com/tdz/platform_system_geolocationd

Updated Github repository:

  - added AGPS module
  - some refactoring
Comment on attachment 8585534 [details]
https://github.com/tdz/platform_system_geolocationd

Updated Github repository

  - added AGPS-RIL module
  - minor fixes
Will the location providers be affected? Concretely, will GonkGPSGeolocationProvider or NetworkGeolocationProvider be affected by this change? If so, this may affect future work that MLS has planned (not in a bad way, just that we should know to follow this work closely).
Flags: needinfo?(tzimmermann)
Hi Garvan,

Yes, I'm currently rewriting |GonkGPSGeolocationProvider| to work with the daemon. I hope to have the patches ready soon. The change is that |GonkGPSGeolocationProvider| will call the daemon instead of the HAL API. But the overall logic in that class will remain the same.
Flags: needinfo?(tzimmermann)
Adding :scravag because he was interested in the topic.
Attachment #8590834 - Attachment description: [05] Added AGPS-RIL module → [05] WIP: Added AGPS-RIL module
Attachment #8590835 - Attachment description: [06] Added Geolocation protocol class → [06] WIP: Added Geolocation protocol class
Attachment #8590836 - Attachment description: [07] Added GPS interface → [07] WIP: Added GPS interface
The WIP patch set is mostly complete, but still needs a lot of testing and debugging.
For which release is this change coming up ?
None yet, it's just a prototype.
Attached patch [01] WIP: Added helpers (obsolete) — Splinter Review
Attachment #8590830 - Attachment is obsolete: true
Attached patch [02] WIP: Added Registry module (obsolete) — Splinter Review
Attachment #8590831 - Attachment is obsolete: true
Attached patch [03] WIP: Added GPS module (obsolete) — Splinter Review
Attachment #8590832 - Attachment is obsolete: true
Attached patch [04] WIP: Added AGPS module (obsolete) — Splinter Review
Attachment #8590833 - Attachment is obsolete: true
Attached patch [05] WIP: Added AGPS-RIL module (obsolete) — Splinter Review
Attachment #8590834 - Attachment is obsolete: true
Attachment #8590835 - Attachment is obsolete: true
Attached patch [07] WIP: Added GPS interface (obsolete) — Splinter Review
Attachment #8590836 - Attachment is obsolete: true
Attached patch [08] WIP: Added AGPS interface (obsolete) — Splinter Review
Attachment #8590837 - Attachment is obsolete: true
Attachment #8590838 - Attachment is obsolete: true
Comment on attachment 8585534 [details]
https://github.com/tdz/platform_system_geolocationd

Updated Github tree:

  - documented IPC protocol
  - many code fixes
Comment on attachment 8585534 [details]
https://github.com/tdz/platform_system_geolocationd

Updated Github repository

  - fixed nmea notification
Attached patch [02] WIP: Added Registry module (obsolete) — Splinter Review
Attachment #8592219 - Attachment is obsolete: true
Attached patch [03] WIP: Added GPS module (obsolete) — Splinter Review
Attachment #8592220 - Attachment is obsolete: true
Attached patch [04] WIP: Added AGPS module (obsolete) — Splinter Review
Attachment #8592221 - Attachment is obsolete: true
Attached patch [05] WIP: Added AGPS-RIL module (obsolete) — Splinter Review
Attachment #8592222 - Attachment is obsolete: true
Overall, I am happy to see someone think about this problem.  Not being able to update FirefoxOS is upsetting.  As for the set of changes, these patches do a lot more than switch over the geolocation provider to use something else!  I will not be able to review in the near term, however I think Kanru would be the best person to review the FFOS stuff.

Have you spoken to mvines (or anyone at QC) about this and will they move this this new framework?  Without commitment, I am not sure that this work is that important.

Another, simpler, approach would be to build a API/ABI that can be frozen between our location provider and whatever they need.  I suspect they would have to drive this effort as only they know what their provider does.
Hi,

Thanks for taking a look at the current patch set.

This bug report actually resulted from a discussion with mvines in Portland. I didn't change any of the internal interfaces within Gecko. So if QC is not interested, nothing would change for them.

For our implementation, the patch set improves the code's security and reliability, and reduces Gecko's hardware dependencies. These seem worthwhile goals for B2G's overall architecture.
Comment on attachment 8592218 [details] [diff] [review]
[01] WIP: Added helpers

Review of attachment 8592218 [details] [diff] [review]:
-----------------------------------------------------------------

The Convert functions in the GeolocationHelpers.cpp file should probably be moved to a header file so you can rewrite it as an inline function template and then specialize where needed.  There's lots of implementations where the only difference is the type of the first parameter.  That's a sign that a template can reduce the LOC.
Attachment #8592218 - Flags: feedback-
Summary: Investigate separate Geolocation daemon on FxOS → Move Geolocation HAL into system daemon on FxOS
No longer blocks: fxos-updates
Depends on: 1187225
Flags: needinfo?(dougt)
Attachment #8592218 - Attachment is obsolete: true
Attachment #8596410 - Attachment is obsolete: true
Attachment #8592224 - Attachment is obsolete: true
Attachment #8596412 - Attachment is obsolete: true
Attachment #8592225 - Attachment is obsolete: true
Attachment #8596413 - Attachment is obsolete: true
Attachment #8592226 - Attachment is obsolete: true
Attachment #8596414 - Attachment is obsolete: true
Attachment #8596415 - Attachment is obsolete: true
I think if we could remove some hardware dependency then it's great! However,

I skimmed through the patches and had some questions noted:

* Why is this more secure? Could you elaborate?
* What's the benefit if no more chipset vendor needs it?
* Could the protocol handling code be shared with other part of HAL?
  Why are we writing these new protocol handling code instead of reusing other serializer we already have in code base like IPDL or protobuf? If it's using json then the provider could potentially be implemented in js.
* GonkGeolocationProvider.cpp looks very similar to GonkGPSGeolocationProvider.cpp, it will be easier to review it as a patch instead of a complete rewrite.
* Looks like most of the controlling logic is still in gecko and it highly depends on the behavior of the hardware library. I don't think this improves the porting or update issue very much.

Some nits:

* nsAutoPtr should be UniquePtr
* use LazyLogModule instead of __android_log_print in gecko
Flags: needinfo?(tzimmermann)
Hi

Thanks for looking at the patches.

(In reply to Kan-Ru Chen [:kanru] (UTC+8) from comment #53)
> I think if we could remove some hardware dependency then it's great! However,
> 
> I skimmed through the patches and had some questions noted:
> 
> * Why is this more secure? Could you elaborate?

Besides the address-space separation, the daemon can run without root privileges and with a custom SELinux context. We already do this for Bluetooth and Sensors.


> * What's the benefit if no more chipset vendor needs it?

Security, as mentioned above. The system also becomes more reliable. The driver can crash without taking down the entire system. Gecko would see a disconnect of the IPC socket, and can clean up it's internal resources. In Bluetooth, we even restart the driver after a crash and continue operation. Implementing this in Geolocation should be considerably easier, as it has almost no state (compared to BT).


> * Could the protocol handling code be shared with other part of HAL?
>   Why are we writing these new protocol handling code instead of reusing
> other serializer we already have in code base like IPDL or protobuf? If it's
> using json then the provider could potentially be implemented in js.

It's already shared with other HAL components. Most of the IPC and protocol code is located in ipc/hal. It was originally merged for Bluetooth, which has to be compatible with BlueZ's IPC. (So the code is there anyway.) It was then generalized and re-used for Sensors, and now for Geolocation. What is added here are only a few additional helper functions for this IPC framework.


> * GonkGeolocationProvider.cpp looks very similar to
> GonkGPSGeolocationProvider.cpp, it will be easier to review it as a patch
> instead of a complete rewrite.

That's how where the code started. Trust me, it was not more readable. ;)

If you insist, I'll merge it into GonkGpsGeolocationProvider.cpp, but it's still a complete rewrite.


> * Looks like most of the controlling logic is still in gecko and it highly
> depends on the behavior of the hardware library. I don't think this improves
> the porting or update issue very much.

It's not intended to ease porting to something else than HAL drivers.

For different version of the HAL interface, the protocol can be adapted. The daemon implements a specific version and Gecko can handle different versions of the protocol. This is intentional! We use this design for Bluetooth, where we support all versions of the HAL driver up to L with a single implementation of Gecko.

The daemon is supposed to be dumb. It's highly system dependent and hard to update (FOTA). Gecko fixes are a lot easier to distribute. Again, we made a good experience with this design in Bluetooth.


> Some nits:
> 
> * nsAutoPtr should be UniquePtr
> * use LazyLogModule instead of __android_log_print in gecko

Sure.
Flags: needinfo?(tzimmermann)
Changes since v1:

  - use |UniquePtr<>|
  - changed logging to use |LogModule|
Attachment #8721256 - Attachment is obsolete: true
Changes since v1:

  - use |UniquePtr|
  - update logging
Attachment #8721257 - Attachment is obsolete: true
Changes since v1:

  - use |UniquePtr<>|
  - update logging
Attachment #8721258 - Attachment is obsolete: true
Changes since v1:

  - use |UniquePtr<>|
  - update logging
Attachment #8721259 - Attachment is obsolete: true
Changes since v1:

  - update logging
Attachment #8721260 - Attachment is obsolete: true
Changes since v1:

  - update logging
Attachment #8721261 - Attachment is obsolete: true
Changes since v1:

  - rebased onto bug 1253159
Attachment #8721255 - Attachment is obsolete: true
Changes since v2:

  - rebased onto bug 1253159
Attachment #8726659 - Attachment is obsolete: true
Attachment #8721254 - Flags: review?(kchen)
Attachment #8726653 - Flags: review?(kchen)
Attachment #8726654 - Flags: review?(kchen)
Attachment #8726656 - Flags: review?(kchen)
Attachment #8726657 - Flags: review?(kchen)
Attachment #8726658 - Flags: review?(kchen)
Attachment #8730594 - Flags: review?(kchen)
Attachment #8730595 - Flags: review?(kchen)
Attachment #8736316 - Flags: review?(kchen)
Attachment #8736319 - Flags: review?(kchen)
Attachment #8736324 - Flags: review?(kchen)
Attachment #8736674 - Flags: review?(kchen)
Kan-Ru, Patch [07b] is an alternative to [07]. [07b] implements the new daemon provider on top of the old one; as you asked for in the feedback.
Attachment #8736679 - Flags: review?(kchen)
I'll try to review this by Friday.
Comment on attachment 8726653 [details] [diff] [review]
[02] Bug 1107539: Add registry module for Gonk Geolocation daemon (v2)

Review of attachment 8726653 [details] [diff] [review]:
-----------------------------------------------------------------

::: dom/system/gonk/GonkGeolocationInterface.cpp
@@ +37,5 @@
> +    OPCODE_UNREGISTER_MODULE = 0x02
> +  };
> +
> +  virtual nsresult Send(DaemonSocketPDU* aPDU,
> +                        DaemonSocketResultHandler* aUserData) = 0;

I guess this function will be defined in latter patch? And note the return type could be a bool.

@@ +48,5 @@
> +                    GeolocationRegistryResultHandler* aRes)
> +  {
> +    UniquePtr<DaemonSocketPDU> pdu =
> +      MakeUnique<DaemonSocketPDU>(SERVICE_ID, OPCODE_REGISTER_MODULE,
> +                                  1); // Service id

Maybe use a self-explanatory name like pduServiceId instead of a comment like this.

nit: weird line breaking.

@@ +50,5 @@
> +    UniquePtr<DaemonSocketPDU> pdu =
> +      MakeUnique<DaemonSocketPDU>(SERVICE_ID, OPCODE_REGISTER_MODULE,
> +                                  1); // Service id
> +
> +    nsresult rv = PackPDU(aServiceId, *pdu);

I guess the interface of PackPDU was introduced by other patches but note that out parameters should be pointers instead of references.

@@ +58,5 @@
> +    rv = Send(pdu.get(), aRes);
> +    if (NS_FAILED(rv)) {
> +      return rv;
> +    }
> +    Unused << pdu.release();

Do you really mean to intentionally leak the pointer?

@@ +59,5 @@
> +    if (NS_FAILED(rv)) {
> +      return rv;
> +    }
> +    Unused << pdu.release();
> +    return rv;

Instead of return rv here, explicitly return NS_OK;

@@ +68,5 @@
> +                      GeolocationRegistryResultHandler* aRes)
> +  {
> +    UniquePtr<DaemonSocketPDU> pdu =
> +      MakeUnique<DaemonSocketPDU>(SERVICE_ID, OPCODE_UNREGISTER_MODULE,
> +                                  1); // Service id

ditto

@@ +70,5 @@
> +    UniquePtr<DaemonSocketPDU> pdu =
> +      MakeUnique<DaemonSocketPDU>(SERVICE_ID, OPCODE_UNREGISTER_MODULE,
> +                                  1); // Service id
> +
> +    nsresult rv = PackPDU(aServiceId, *pdu);

ditto

@@ +78,5 @@
> +    rv = Send(pdu.get(), aRes);
> +    if (NS_FAILED(rv)) {
> +      return rv;
> +    }
> +    Unused << pdu.release();

ditto

@@ +79,5 @@
> +    if (NS_FAILED(rv)) {
> +      return rv;
> +    }
> +    Unused << pdu.release();
> +    return rv;

ditto

::: dom/system/gonk/GonkGeolocationInterface.h
@@ +66,5 @@
> +                     GeolocationError aError);
> +  void DispatchError(GeolocationRegistryResultHandler* aRes,
> +                     nsresult aRv);
> +
> +  GeolocationRegistryModule* mModule;

UniquePtr<GeolocationRegistryModule>
Attachment #8726653 - Flags: review?(kchen)
Hi!

(In reply to Kan-Ru Chen [:kanru] (UTC+8) from comment #69)
> Comment on attachment 8726653 [details] [diff] [review]
> [02] Bug 1107539: Add registry module for Gonk Geolocation daemon (v2)
> 
> Review of attachment 8726653 [details] [diff] [review]:
> -----------------------------------------------------------------
> 
> ::: dom/system/gonk/GonkGeolocationInterface.cpp
> @@ +37,5 @@
> > +    OPCODE_UNREGISTER_MODULE = 0x02
> > +  };
> > +
> > +  virtual nsresult Send(DaemonSocketPDU* aPDU,
> > +                        DaemonSocketResultHandler* aUserData) = 0;
> 
> I guess this function will be defined in latter patch? And note the return
> type could be a bool.

Yep, that's patch [06]. Each module class uses |Send| for sending PDUs to the daemon. Since all modules share the same connection, |Send| is implemented in a class that inherits form all module classes. That class also maintains the connection state.

> @@ +48,5 @@
> > +                    GeolocationRegistryResultHandler* aRes)
> > +  {
> > +    UniquePtr<DaemonSocketPDU> pdu =
> > +      MakeUnique<DaemonSocketPDU>(SERVICE_ID, OPCODE_REGISTER_MODULE,
> > +                                  1); // Service id
> 
> Maybe use a self-explanatory name like pduServiceId instead of a comment
> like this.

Not sure if that's worth it. These values are the size of the PDU's arguments. But it's just a hint to reduct the number of calls to the allocator. If the overall sum is incorrect, the PDU class will allocate more memory as required.

> nit: weird line breaking.

What do you suggest instead?

> @@ +50,5 @@
> > +    UniquePtr<DaemonSocketPDU> pdu =
> > +      MakeUnique<DaemonSocketPDU>(SERVICE_ID, OPCODE_REGISTER_MODULE,
> > +                                  1); // Service id
> > +
> > +    nsresult rv = PackPDU(aServiceId, *pdu);
> 
> I guess the interface of PackPDU was introduced by other patches but note
> that out parameters should be pointers instead of references.

True. I would not want to change this interface, because it is also used a lot by HAL and Bluetooth.

> @@ +58,5 @@
> > +    rv = Send(pdu.get(), aRes);
> > +    if (NS_FAILED(rv)) {
> > +      return rv;
> > +    }
> > +    Unused << pdu.release();
> 
> Do you really mean to intentionally leak the pointer?

Oh, that surely deserves a comment in the code. The PDU (here and in similar places) is handed over to the I/O thread, which then maintains the reference.

> @@ +59,5 @@
> > +    if (NS_FAILED(rv)) {
> > +      return rv;
> > +    }
> > +    Unused << pdu.release();
> > +    return rv;
> 
> Instead of return rv here, explicitly return NS_OK;

Ok.
I'd like to review a patch if this work is picked up again.  For now, clearing review flag.
Flags: needinfo?(dougt)
Attachment #8721254 - Flags: review?(kchen)
Attachment #8726654 - Flags: review?(kchen)
Attachment #8726656 - Flags: review?(kchen)
Attachment #8726657 - Flags: review?(kchen)
Attachment #8726658 - Flags: review?(kchen)
Attachment #8730594 - Flags: review?(kchen)
Attachment #8730595 - Flags: review?(kchen)
Attachment #8736316 - Flags: review?(kchen)
Attachment #8736319 - Flags: review?(kchen)
Attachment #8736324 - Flags: review?(kchen)
Attachment #8736674 - Flags: review?(kchen)
Attachment #8736679 - Flags: review?(kchen)
Status: ASSIGNED → RESOLVED
Closed: 7 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: