gps_freerunner.c (2)

とりあえず、エントリポイントは gps_state_init 手続きである事が判明。呼び出しな sequence を確認してみた所、とりあえず gps_get_hardware_interface 手続きを呼び出しているのは間接的にですが、hardware/libhardware_legacy/gps/gps.cpp の gps_get_interface 手続きになってます。
で、これを呼び出しているのは framework/base/core/jni/android_location_GpsLocationProvider.cpp の android_location_GpsLocationProvider_init 手続きで以下。

static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject obj)
{   
    if (!sGpsInterface)
        sGpsInterface = gps_get_interface();
    if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0)
        return false;

ここで freerunner_gps_init なポインタが格納されている init メンバな手続きが呼び出されているはず。
がしかし、sGpsCallbacks とは何だ。

とほほ

あ、違うや。freerunner_gps_init 手続きは以下な定義。

static int
freerunner_gps_init(GpsCallbacks* callbacks)
{
    GpsState*  s = _gps_state;

    if (!s->init)
        gps_state_init(s);

    if (s->fd < 0)
        return -1;

    s->callbacks = *callbacks;

    return 0;
}

_gps_state の定義ですが、以下。

typedef struct {
    int                     init;
    int                     fd;
    GpsCallbacks            callbacks;
    pthread_t               thread;
    pthread_t               tmr_thread;
    int                     control[2];
    int                     fix_freq;
    sem_t                   fix_sem;
    int                     first_fix;
    NmeaReader              reader;

} GpsState;

static GpsState  _gps_state[1];
static GpsState *gps_state = _gps_state;

なんでこんな定義なのかは別途確認の必要あり。あと、callbacks メンバに格納される GpsCallbacks 構造体なんですが、呼び出し元である framework/base/core/jni/android_location_GpsLocationProvider.cpp での定義が以下。

GpsCallbacks sGpsCallbacks = {
    location_callback,
    status_callback,
    sv_status_callback,
    nmea_callback
};

このあたりもきっちり整理しとかないと微妙。

とりあえず

エントリポイントな

    if (!s->init)
        gps_state_init(s);

android_location_GpsLocationProvider_init 手続きから呼び出されております。この手続きの呼び出し元は別途整理が必要。

gps_state_init 手続き

引数で渡される GpsState 構造体 (freerunner 的には _gps_state[0]) の初期設定をした後で thread を kick している形です。なんとなくなソレを以下に。
# そーゆー意味では GpsState 構造体なソレって freerunner に閉じてるの?

  • init メンバに STATE_INIT をセット
  • fix_sem メンバ初期化
  • fd メンバに gps なシリアルデバイスのファイルディスクリプタをセット
    • シリアルデバイスの再設定含む
  • control メンバは socketpair 使って云々
    • このメンバを何に使っているのか確認必要

で上記初期設定が済んだら gps_state_thread 手続きに 初期設定した GpsState 構造体を渡す形で thread として kick する形。

control メンバ

上記で GpsState 構造体は freerunnuer に閉じてる、と書いたんですが、socketpair してるのは何故か。とりあえず grep してみた所では
sdk/emulator/gps/gps_qemu.c とか hardware/libhardware_legacy/gps/gps_qemu.c とかで定義されているのを確認してます。
あ、あと packages/apps/Settings/src/com/android/settings/widget/SettingsAppWidgetProvider.java にも宣言がありますな。なんとなく謎というか微妙な感触。