Bug 105993

Summary: Base ModemManager GPS rate on TimeThreshold property
Product: GeoClue Reporter: Zeeshan Ali <zeenix>
Component: Modem sourceAssignee: Geoclue Bugs <geoclue-bugs>
Status: RESOLVED FIXED QA Contact: Geoclue Bugs <geoclue-bugs>
Severity: normal    
Priority: medium    
Version: unspecified   
Hardware: Other   
OS: All   
i915 platform: i915 features:

Description Zeeshan Ali 2018-04-11 21:22:57 UTC
In bug#101975, we hardcoded the GPS refresh rate on ModemManager-based GPS to 0 (always report update as soon as available), which takes us back to the original behaviour before ModemManager added the API to set it and made the default to 30s.

However, we already have a property that should be dictating this: https://www.freedesktop.org/software/geoclue/docs/gdbus-org.freedesktop.GeoClue2.Client.html#gdbus-property-org-freedesktop-GeoClue2-Client.TimeThreshold

I looked into solving this issue but with current architecture of allowing different clients to set different threshold and our sources being singletons, this is not as simple as simply forwarding the value to the sources. I've a rough plan on how to solve this though:

  * WIP work in `wip/mm-time-threshold` branch
  * LocationSource
    * time-threshold property
    * priv hashtable<uint ID, threshold value>
    * request_time_threshold() -> uint ID
    * cancel_time_threshold(uint ID)
    * Set threshold property to lowest of requests
      * Keep in sync
      * Set to 0 when no requests
  * Modem
    * time-threshold property
  * ModemManager
    *  property
    * keep Modem.time-threshold in sync with MM's
  * ModemGPS
    * time-threshold property
      * keep in sync with it's ModemManager
  * Locator
    * Forward the set threshold as request to all sources
    * Drop request on unref'ing a source
  * ServiceClient just forwards the set threshold to it's Locator instance

Quite a bit of chaining and syncing I know but maybe it shows weakness in the current architecture or maybe we just need some sort of API that simplifies this  aggregation of data from clients to the actual sources.
Comment 1 Zeeshan Ali 2018-04-13 12:11:20 UTC
I think I got a better plan, that doesn't involve so much syncing:

  * New MinUINT class
    * private values_hashtable<value, num_users>
    * min-value property
      * calculated dynamically on read
      * 0 when hash_table is empty
    * add_value(uint value)
      * add value if not already in the hashtable
      * num_users++ if value already exists
      * notify min-value prop
    * drop_value(uint value)
      * num_users--
      * delete value from hashtable on num_users == 0                                                                                                        
      * notify min-value prop
  * LocationSource
    * time-threshold property: MinUINT
  * Modem
    * time-threshold property: MinUINT
  * ModemManager
    * keep Modem.time-threshold.min-value in sync with MM
  * ModemGPS
    * time-threshold property
  * Locator
    * Add the set threshold to time-threshold prop of all sources
    * On destroy, drop the set threshold from time-threshold prop of all sources
  * ServiceClient just forwards the set threshold to it's Locator instance
Comment 2 Zeeshan Ali 2018-04-18 22:31:15 UTC
Right, after several days of fighting with the C compiler and gobject, I finally pushed the changes that in my limited testing solve this issue (in chronological order):

commit 71f12492e89b86f948015c927da4d4d59c9a076b

    Add GClueMinUINT class
    This is a helper class that keeps a list of guint values and the minimum
    value from this list. In the following patches, it will be used by
    location sources to use the minimum time-threshold (location update rate)
    from all the time-thresholds requested by different applications.

commit d26392ead0cd8ca35e896cbbcd00dc4dcbfb9163

    location-source: Add 'time-threshold' property
    In the following patches, this property will be used to set the GPS
    refresh rate on the ModemManager, based on the D-Bus TimeThreshold

commit 30d3984001eb4ea66fd7c003b6229d3d24f475e9

    modem: Add 'time-threshold' property
    Add 'time-threshold' property of type guint, not GClueMinUINT to Modem
    interface. In a following patch, ModemManager implementation will
    translate this to ModemLocation::gps-refresh-rate property of
    ModemManager service.
    There is no reason to use the more complex GClueMinUINT type here since
    the Modem implementations are at the last end of the time-threshold users
    and hence just needs one specific value to be set on them.
commit 6e4a99333d3eeeaaa77c16d2fe6621a0932aa433

    modem-manager: Implement 'time-threshold' property
    Implement the 'time-threshold' property of Modem interface. This
    implementation translates this to ModemLocation::gps-refresh-rate property
    of ModemManager service.

commit db47f58dbe9922dca4abb929ca0262e7e4a21221

    modem-gps: Forward time-threshold to modem

commit 08a92d82bbfcc6f705d2be6150ff925195369b28

    locator: Aggregate time-threshold for sources
    Unlike other (real) location sources, Locator instances are unique for each
    client application. Which means we only need just one time-threshold value
    so we now provide getter and setter for time-threshold as guint, which
    is what will be set by the clients, instead of the time-threshold property
    of the parent class LocationSource (they can still do that if they wish

commit c000e895687b489040cf2023124de93bd1236319

    service-client: Forward TimeThreshold to sources
    Some sources will be able to make use of this to reduce battery life so we
    should forward this information to them, via the Locator class. Currently,
    only ModemManager can do that but that's also where it makes most sense
    since GPS is the only source that can continuously fetch location updates
    and hence drain the most power.
commit 6fce3b84963b796a165c93beb75340db10104b5f (HEAD -> master, origin/master, origin/HEAD)

    demo: Add '--time-threshold' CLI option
    Add an option to set the TimeThreshold.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.