On Sun, 2011-04-17 at 08:49 -0700, Eckhart Wörner wrote: > Hi everybody, > > when I first encountered GeoClue some time ago, I immediately liked the idea > of > it. However, I was somehow never really satisfied with its design. Therefore, > in the last few days I tried to write down my vision of how its D-Bus API > should look like, and now present it here for discussion. I'll start with the > problems the old API has in my eyes, and then present a new API that hopefully > overcomes these problems.
You beat me to the punch. I was about to write a similar email discussing a geoclue redesign. ;) > I'll call the old API GeoClue and my API GeoClue2 only to differentiate > between > them, not because I think that my API is perfect (it probably isn't). It also > probably helps my subject getting some attention. ;-) > > > == Problems == > > The GeoClue API is incomplete: GeoClue Position and Velocity provide the > coordinates of a point (which normally represents a device so close to the > user's coordinates that we define them to be the user's coordinates) in a > three-dimensional room (Latitude, Longitude, Altitude), and the first > derivative (Speed, Direction, Climb). However, we still don't know the > orientation of the device in this room. > Why may this information be useful? E.g. a routing application for pedestrians > can rotate the map it displays according to the heading of the device. > > The GeoClue API defines several providers and puts arbitrary borders between > them: Latitude, Longitude and Altitude share the same provider, while Speed, > Direction and Climb share a different provider, however, e.g. an altimeter > only > provides Altitude and Climb. > > The GeoClue API is overly complex in some places: to get latitude, longitude > and speed, one has to traverse two objects, and then use two different > providers. > > The GeoClue API exposes too much information to an application that uses it: > an application that relies on the *type* of the underlying provider clearly > does something wrong. An application should not decide which provider to use, > instead GeoClue2 should. An application should not configure providers, a > dedicated interface should do that. > > The GeoClue API does not differentiate between an application that needs some > piece of information to work properly, and a piece of information that is > nice-to-have, but not necessary. E.g. an application for navigation clearly > needs coordinates to work properly, while a weather applet that works fine > without coordinates might still use them when they are available. > > Applications may be interested in the last known value for some piece of > information, even though it is not valid anymore. > > The GeoClue API does not cope well with unexpected application behavior like > crashes. E.g. AddReference and RemoveReference are just asking for problems. > > The GeoClue API does not play well with D-Bus: Long-running methods will break > as D-Bus puts a timeout on method calls. The GeoClue API/design is not terribly efficient. One ends up with several round-trips around DBUS for any position information. Additionally, using DBUS in this way leaks information all over the place. Most of the next round of criticism focuses on getting GeoClue more tightly integrated with positioning mechanisms. This isn't how it is presently designed, but as positioning mechanisms in the mobile space are becoming more advanced and interrelated, having GeoClue be more entwined with the mechanics of positioning will likely be required. Actually, I'm mostly focused on positioning, as geocoding/reverse geocoding are basically just turning around to a web service typically. The GeoClue design of providers makes it such that making hybrid positioning methods is difficult if not impossible. This makes things like dead-reckoning between position fixes nearly impossible to implement without enabling each provider below the geoclue level. The decision making powers and inputs to the Master Provider are too simple to give optimal results. The master provider has no concept of latency or power consumption, providers have no basis to specify them, and clients have no basis to input their requirements for either. Furthermore the resources that providers may request are too course grained and rigid. For example, a satellite position provider might not require network access to give information, but having it might enable assistance that greatly reduces latency or increases accuracy. The abstraction of providers also hides provider details. This sounds like the facts of life and a non-problem, but it actually is a problem. There are my applications out there that want to display some detailed status of their position fix but also want to be able to support several positioning methods. For example, an application might want to report the satellites in view if it's getting a GPS signal, but display the access points it sees for a wifi based position method. This sounds contrived, but consider how MeeGo's qt-mobility back-end is currently written. It talks to both GeoClue and Gypsy to report satellite data for GPS fixes as well as supporting non-satellite methods. > == Proposal == > > The GeoClue2 service is the only access point to information; there's no > documented way of communicating with individual providers for information > retrieval. > > The main interface allows to create objects for individual applications. Any > object created through the main interface is said to be owned by the > respective application and should not be used by any other application. > > This is the main interface: > > <node> > <interface name="org.freedesktop.Geoclue2"> > > <method name="CreateProvider"> > <arg name="path" type="o" direction="out" /> > </method> > > <method name="CreateAddressResolver"> > <arg name="path" type="o" direction="out" /> > </method> > > <method name="CreateCoordinatesResolver"> > <arg name="path" type="o" direction="out" /> > </method> How do you specify accuracy, latency, or power requirements? When creating the objects? When querying them? > > </interface> > </node> > > The CoordinatesResolver is responsible for resolving coordinates to an > address. It is used by (optionally) first setting the TargetAccuracy and then > calling Resolve with the coordinates. > If the resolving succeeds, the Result signal is emitted. If there is a > permanent error resolving the coordinates, Error is emitted. An error is not > signalled when it's only temporary. Applications which want a fixed timeout > have to take care of this for themselves. > Destroy cancels the ongoing operation and destroys the object; an application > must be prepared to handle the Result and Error signals after Destroy has been > called due to the asynchronous nature of D-Bus. > Destroy is implicitly called when the application that created the resolver > leaves the bus. > > <node> > <interface name="org.freedesktop.Geoclue2.CoordinatesResolver"> > > <method name="Resolve"> > <arg name="latitude" type="d" direction="in" /> > <arg name="longitude" type="d" direction="in" /> > <arg name="altitude" type="d" direction="in" /> > <arg name="targetAccuracy" type="s" direction="in" /> > </method> > > <signal name="Result"> > <arg name="countryCode" type="s" /> > <arg name="country" type="s" /> > <arg name="region" type="s" /> > <arg name="locality" type="s" /> > <arg name="area" type="s" /> > <arg name="postalCode" type="s" /> > <arg name="street" type="s" /> > </signal> > > <signal name="Error" /> > > <method name="Destroy" /> > > </interface> > </node> I assume street is a freely encoded house number and street? Also, how do you disambiguate ambiguous replies? > > The AddressResolver is responsible for resolving an address to coordinates. It > is used by (optionally) first setting the TargetAccuracy and then calling > Resolve with the address. > If the resolving succeeds, the Result signal is emitted. If there is a > permanent error resolving the address, Error is emitted. An error is not > signalled when it's only temporary. Applications which want a fixed timeout > have to take care of this for themselves. > Destroy cancels the ongoing operation and destroys the object; an application > must be prepared to handle the Result and Error signals after Destroy has been > called due to the asynchronous nature of D-Bus. > Destroy is implicitly called when the application that created the resolver > leaves the bus. > > <node> > <interface name="org.freedesktop.Geoclue2.AddressResolver"> > > <method name="Resolve"> > <arg name="countryCode" type="s" direction="in" /> > <arg name="country" type="s" direction="in" /> > <arg name="region" type="s" direction="in" /> > <arg name="locality" type="s" direction="in" /> > <arg name="area" type="s" direction="in" /> > <arg name="postalCode" type="s" direction="in" /> > <arg name="street" type="s" direction="in" /> > <arg name="targetAccuracy" type="s" direction="in" /> > </method> > > <signal name="Result"> > <arg name="Latitude" type="s" /> > <arg name="Longitude" type="s" /> > <arg name="Altitude" type="s" /> > </signal> > > <signal name="Error" /> > > <method name="Destroy" /> > > </interface> > </node> > > The Provider (yes, I know this is not the best name) is responsible for > providing information about aspects of the position of the device. These > include: > - CountryCode, Country, Region, Locality, Area, PostalCode, Street > - Latitude, Longitude as WGS84 coordinates > - Altitude in meters above the reference surface of the WGS84 ellipsoid > - Heading as the angle between the projection of the main direction of the > device on a tangential plane and true north, in degrees > - Elevation as the arc between the main direction of the device and a > tangential plane, in degrees > - Bank as the rotation on the plane defined by heading and elevation, in > degrees > - Speed and Direction as vector length and vector direction of the first > derivative of (Latitude, Longitude), in km/h (?) and degrees, respectively > - Climb as first derivative of Altitude, in m/s > > The above properties are considered as not set if they contain a value that is > not in the allowed range of values, these ranges are to be defined. If they > are > set, they contain the last valid value. One can check whether the value is > valid via the corresponding …Valid property. > > An application indicates that it needs one or more properties to function > correctly by setting ActiveProperties to the corresponding property names. > > An application indicates that one or more properties may enhance the > application's functionality without being needed to function correctly by > setting PassiveProperties to the corresponding property names. GeoClue2 > ensures that PassiveProperties is always a superset of ActiveProperties by > extending PassiveProperties as needed. > > GeoClue2 may try to fill properties that are only in the PassiveProperties set > at its own discretion; it is suggested that GeoClue2 provides those values iff > they are in the ActiveProperties of another Provider. > > Communication of changes is done via the standardized PropertiesChanged > signal. What if I'm not interested if some of the properties change? I don't want to be woken up if the compass changes and I don't care about the compass. Might I suggest a more fine-grained approach of specifying requirements for change notification as well? > Destroy destroys the object; an application must be prepared to handle the > PropertiesChanged signal after Destroy has been called due to the asynchronous > nature of D-Bus. > Destroy is implicitly called when the application that created the provider > leaves the bus. > > <node> > <interface name="org.freedesktop.Geoclue2.Provider"> > > <property name="TargetAccuracy" type="s" access="readwrite" /> > > <property name="ActiveProperties" type="as" > access="readwrite" /> > <property name="PassiveProperties" type="as" > access="readwrite" /> > > <!-- Aspects of position (and first derivative) in 3d --> > <property name="Latitude" type="d" access="read" /> > <property name="Longitude" type="d" access="read" /> > <property name="Altitude" type="d" access="read" /> > <property name="Heading" type="d" access="read" /> > <property name="Elevation" type="d" access="read" /> > <property name="Bank" type="d" access="read" /> > > <property name="Speed" type="d" access="read" /> > <property name="Direction" type="d" access="read" /> > <property name="Climb" type="d" access="read" /> > > <property name="CountryCode" type="s" access="read" /> > <property name="Country" type="s" access="read" /> > <property name="Region" type="s" access="read" /> > <property name="Locality" type="s" access="read" /> > <property name="Area" type="s" access="read" /> > <property name="PostalCode" type="s" access="read" /> > <property name="Street" type="s" access="read" /> > > <property name="LatitudeValid" type="b" access="read" /> > <property name="LongitudeValid" type="b" access="read" /> > <property name="AltitudeValid" type="b" access="read" /> > <property name="HeadingValid" type="b" access="read" /> > <property name="ElevationValid" type="b" access="read" /> > <property name="BankValid" type="b" access="read" /> > > <property name="SpeedValid" type="b" access="read" /> > <property name="DirectionValid" type="b" access="read" /> > <property name="ClimbValid" type="b" access="read" /> > > <property name="CountryCodeValid" type="b" access="read" /> > <property name="CountryValid" type="b" access="read" /> > <property name="RegionValid" type="b" access="read" /> > <property name="LocalityValid" type="b" access="read" /> > <property name="AreaValid" type="b" access="read" /> > <property name="PostalCodeValid" type="b" access="read" /> > <property name="StreetValid" type="b" access="read" /> > > <method name="Destroy" /> > > <annotation > name="org.freedesktop.DBus.Property.EmitsChangedSignal" > value="true" /> > > </interface> > </node> I think that making position providers as plugins or at least defining a plugin interface should be a goal. The ability to provide high-bandwidth data between different providers to support hybrid positioning information will more or less require this ability in order for it to be efficient. > Configuration is separated from the main functionality. It should not be used > by an application, but only by a configuration tool. The interface is yet to > be > defined. What is to be configured? > As said, this API is only a draft for a redesign, and I'd therefore like to > see tons of comments, criticism, flames, whatever ;-) > > Eckhart Cheers -- Michael Leibowitz <[email protected]> _______________________________________________ GeoClue mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/geoclue
