gps_freerunner.c

今日は出社して mtg な一日。ゲンジツトウヒ気味にソース確認してたり。
しかし標題のソースファイルなんですが、きちんと公開/非公開がソースで明示されていて気持ち良い。公開されている i/f としては以前のエントリでも引用した以下な手続き。

const GpsInterface* gps_get_hardware_interface()
{
    return &freerunnerGpsInterface;
}

戻している freerunnerGpsInterface の定義は直上で以下。

static const GpsInterface  freerunnerGpsInterface = {
    freerunner_gps_init,
    freerunner_gps_start,
    freerunner_gps_stop,
    freerunner_gps_set_fix_frequency,
    freerunner_gps_cleanup,
    freerunner_gps_inject_time,
    freerunner_gps_delete_aiding_data,
    freerunner_gps_set_position_mode,
    freerunner_gps_get_extension,
};

gps_get_hardware 手続きを呼び出すことで、そこから戻ってくる上記にて羅列されている手続きも公開される、という形になりますな。
で、この gps_get_hardware_interface 手続きを呼び出すのは hardware/libhardware_legacy/gps/gps.cpp にて定義されている gps_find_hardware 手続きで、この手続きを呼び出しているのが jni 側との i/f になっている gps_get_interface 手続きになります。
ちなみに gps_get_interface 手続きを呼び出しているのは jni 側の android_location_GpsLocationProvider.cpp からとなってますが、掘削は一旦停止。

GpsInterface 構造体

メンバは関数ポインタのみになってて、定義は hardware/libhardware_lebacy/include/hardware_legacy/gps.h にて以下。

/** Represents the standard GPS interface. */
typedef struct {
    /**
     * Opens the interface and provides the callback routines
     * to the implemenation of this interface.
     */
    int   (*init)( GpsCallbacks* callbacks );

    /** Starts navigating. */
    int   (*start)( void );

    /** Stops navigating. */
    int   (*stop)( void );

    /** Closes the interface. */
    void  (*cleanup)( void );

    /** Injects the current time. */
    int   (*inject_time)(GpsUtcTime time, int64_t timeReference,
                         int uncertainty);

    /** Injects current location from another location provider
     *  (typically cell ID).
     *  latitude and longitude are measured in degrees
     *  expected accuracy is measured in meters
     */
    int  (*inject_location)(double latitude, double longitude, float accuracy);

    /**
     * Specifies that the next call to start will not use the
     * information defined in the flags. GPS_DELETE_ALL is passed for
     * a cold start.
     */
    void  (*delete_aiding_data)(GpsAidingData flags);

    /**
     * fix_frequency represents the time between fixes in seconds.
     * Set fix_frequency to zero for a single-shot fix.
     */
    int   (*set_position_mode)(GpsPositionMode mode, int fix_frequency);

    /** Get a pointer to extension information. */
    const void* (*get_extension)(const char* name);
} GpsInterface;

こっちの名前は基本的には android_location_GpsLocationProvider.cpp 側で使われているはずなので、別途掘削予定という事にしとく。

call graph

とりあえず gps_freerunner.c 内での call graph 作ってみる事に。以下です。

    freerunner_gps_init
       gps_state_init
           sem_init
	   property_get
	   socketpair
	   pthread_create

    freerunner_gps_start
       gps_state_start

    freerunner_gps_stop
       gps_state_stop

    freerunner_gps_set_fix_frequency

    freerunner_gps_cleanup
       gps_state_done
           pthread_join
           sem_destroy

    freerunner_gps_inject_time

    freerunner_gps_delete_aiding_data

    freerunner_gps_set_position_mode

    freerunner_gps_get_extension

ええと、usbserial からの吸い出しになるので、thread を kick して処理する形になっているのかな。以下のコメントの通り、gps_state_thread が主処理になっている模様。

/* this is the main thread, it waits for commands from gps_state_start/stop and,
 * when started, messages from the QEMU GPS daemon. these are simple NMEA sentences
 * that must be parsed to be converted into GPS fixes sent to the framework
 */
static void*
gps_state_thread( void*  arg )

どっちかっつーとこっちをきちんと確認する必要があるみたい。今日はスデに終わってるカンジなので、gps_state_thread 手続きについては別途確認ってコトにさせて下さひ。

おまけ

Android のソースツリーにある LocationManager 関連のソースなパスを以下に控え。

  • android.location.LocationManager
  • com.android.internal.GpsLocationProvider
    • frameworks/base/location/java/com/android/internal/location/GpsLocationProvider.java
  • com.android.server.LocationManagerServer
    • frameworks/base/services/java/com/android/server/LocationManagerServer.java
  • android/location/GpsLocationProvider.cpp
    • frameworks/base/core/jni/android_location_GpsLocationProvider.cpp
  • hardware/libhardware_legacy/gps/gps.cpp