안드로이드에서 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는 이 디바이스를 묶어두기 위한 세마포어 상태를 뭐 저장하지 않을까.