본문 바로가기
Android

Native Library 따라가보기

by 와인한잔의여유 2010. 7. 15.
안드로이드에서 GPS 를 enable 시키면, 아래에 나와있는 GpsLocationProvider.java 함수에 있는 enable를 호출하게 된다.
====================================================
cupcake-work/src/frameworks/base/location/java/com/android/internal/location/GpsLocationProvider.java
====================================================
if (Config.LOGD) Log.d(TAG, "enable") {
        if (mEnabled) return;
        mEnabled = native_init();//native_inti?<==이게 어딨는거지?

         if (mEnabled) {
             // run event listener thread while we are enabled
           mEventThread = new GpsEventThread();
            mEventThread.start()

            if (requiresNetwork()) {
                 // run network thread for NTP and XTRA support
                if (mNetworkThread == null) {
                     mNetworkThread = new GpsNetworkThread();
                    mNetworkThread.start();
                 } else {
                    mNetworkThread.signal();
                 }
           }
        } else {
            Log.w(TAG, "Failed to enable location provider");
        }
     }
 
====================================================
그래서 native_init 함수를 찾아보니, 맨 아래쪽 부분을 보니 이렇게 선언이 되어 있다.
private native boolean native_init();
native 는 네이티브 라이브러리에 구현부가 있음을 말한다.

그래서 이번에는 JNI를 구현부, cpp 부분을 모아놓은
/cupcake-work/src/frameworks/base/core/jni
을 가서 android_location_GpsLocationProvider.cpp 을 찾았다.
그리고 함수의 init 부분을 찾았더니, 아래와 같은 함수가 나온다.
====================================================
그래서 이번에는 JNI를 구현부, cpp 부분을 모아놓은
/cupcake-work/src/frameworks/base/core/jni
을 가서 android_location_GpsLocationProvider.cpp 을 찾았다.
그리고 함수의 init 부분을 찾았더니, 아래와 같은 함수가 나온다.
====================================================
static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject obj)
{
    if (!sGpsInterface)
        sGpsInterface = gps_get_interface();
    return (sGpsInterface && sGpsInterface->init(&sGpsCallbacks) == 0);
}
가 나온다.여기서 다시 gps_get_interface 함수를 호출하고 있다.
이 함수는 libhardware_legacy.so (공유 라이브러리) 에 있는 함수라고 나와있다. 그러면 libhardware_legacy라는 이름으로 find를 했더니, 아래위치에 디렉토리가 나왔다.
/cupcake-work/src/hardware/libhardware_legacy/gps
결국 hardware단에 libhardware_legacy 단 안에 gps폴더에 있는 함수를 호출한다.그 안에 들어가봤더니, 아래와 같은 파일 있다.
Android.mk.org  android.mk  gps.cpp  gps_mango64.c  gps_mango64.c.org  gps_qemu.c
위에서 gps_mango64.cpp 파일이 있다.여기에 들어가니, 아래와 같이 interface 파일이 있다. 함수를 보니 mango64GpsInterface 의 주소값을 리턴하네?
====================================================
const GpsInterface* gps_get_hardware_interface()
{
    return &mango64GpsInterface;
}

그렇다면 mango64GpsInterface의 데이터가 뭘까해서 찾아보니 static const로 아래와 같이 선언되어져 있다.
====================================================
static const GpsInterface  mango64GpsInterface = {
    mango64_gps_init,
    mango64_gps_start,
    mango64_gps_stop,
    mango64_gps_set_fix_frequency,
    mango64_gps_cleanup,
    mango64_gps_inject_time,
    mango64_gps_delete_aiding_data,
    mango64_gps_set_position_mode,
    mango64_gps_get_extension,
};

결국 gps 드라이버의 함수들의 이름이 들어있다. const 들이 있으므로, 각 함수의 주소값들이 리턴되는걸로 이해된다. 여기서 함수중에 하나인 mango64_gps_init 를 찾아 들어가면, 또 아래와 같이 선언되어 있다.
====================================================
static int
mango64_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;
}

static 으로 선언되어져 있으며, GpsState 의 s 을 초기화해준다. 이때 _gps_state 가 사용되어져 있는데, 이거또한 찾아가면 상단에 이렇게 선언이 되어져 있다.
====================================================
static GpsState  _gps_state[1];
static GpsState *gps_state = _gps_state;

GpsState 형의 자료형으로 배열을 선언했는데, 그 이름이 _gps_state이다.배열 하나만 썼으니, GpsState*  s = _gps_state 라는 값으로 받을수 있었을것이다.그럼 그 자료형에 해당하는 GpsState 라는 자료형의 내용을 또 찾아보면 바로 위에 있었다.
====================================================
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;

GpsState 라는 이름에서 알수있듯이, 결국 Gps 디바이스의 상태값들을 가지고 있는 구조체였다. GpsCallbacks 에는 콜백함수를 등록할것이며, pthread_t 는 쓰레드, sem_t는 이 디바이스를 묶어두기 위한 세마포어 상태를 뭐 저장하지 않을까.

'Android' 카테고리의 다른 글

_IO , _IOR , _IOW , _IORW  (0) 2010.07.21
안드로이드 디렉토리 구조  (0) 2010.07.19
ubuntu 9.10 에서 android full source 빌드  (0) 2010.07.14
안드로이드 네이티브 라이브러리Ⅰ  (0) 2010.07.14
proc 파일 시스템  (0) 2010.07.13