안드로이드 프레임워크 프로그래밍(12) [IServiceManager 등록과정]

안드로이드/프레임워크 2015. 3. 23. 01:43

 처음 안드로이드 프레임워크를 분석하게 되었을 때엔 적어도 Java Framework 단계에서 모든 작업을 해결할 수 있을 듯해 보였습니다만 최근 연구하는 Camera의 경우 안드로이드 내 리눅스 커널 단계까지 연구하고 있는 제 모습을 보고 있습니다...


 이번 포스팅에서는 CameraService와 같이 Hardware Service들을 IServiceManager에 등록되는 과정에 대해 샅샅히 살펴보고자 합니다. 본 포스팅에서는 CameraService.cpp를 예로 들어볼 것입니다.


 카메라 작동과 관련된 동작을 관리하는 CameraService는 main_mediaserver.cpp에 의해 안드로이드 시스템 내에 등록이 되어집니다.

/frameworks/av/media/mediaserver/Android.mk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
LOCAL_PATH:= $(call my-dir)
 
ifneq ($(BOARD_USE_CUSTOM_MEDIASERVEREXTENSIONS),true)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := register.cpp
LOCAL_MODULE := libregistermsext
LOCAL_MODULE_TAGS := optional
include $(BUILD_STATIC_LIBRARY)
endif
 
include $(CLEAR_VARS)
 
LOCAL_SRC_FILES:= \
    main_mediaserver.cpp 
 
LOCAL_SHARED_LIBRARIES := \
    libaudioflinger \
    libcameraservice \
    libmedialogservice \
    libcutils \
    libnbaio \
    libmedia \
    libmediaplayerservice \
    libutils \
    liblog \
    libbinder
 
LOCAL_STATIC_LIBRARIES := \
    libregistermsext
 
LOCAL_C_INCLUDES := \
    frameworks/av/media/libmediaplayerservice \
    frameworks/av/services/medialog \
    frameworks/av/services/audioflinger \
    frameworks/av/services/camera/libcameraservice
 
LOCAL_MODULE:= mediaserver
 
include $(BUILD_EXECUTABLE)
 
cs


/frameworks/av/media/mediaserver/main_mediaserver.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#define LOG_TAG "mediaserver"
....
#include <binder/IServiceManager.h>
....
#include "CameraService.h"
 
using namespace android;
 
int main(int argc, char** argv)
{
    signal(SIGPIPE, SIG_IGN);
    char value[PROPERTY_VALUE_MAX];
    bool doLog = (property_get("ro.test_harness", value, "0"> 0) && (atoi(value) == 1);
    pid_t childPid;
    if (doLog && (childPid = fork()) != 0) {
        ....
    } else {
        // all other services
        if (doLog) {
            prctl(PR_SET_PDEATHSIG, SIGKILL);   // if parent media.log dies before me, kill me also
            setpgid(00);                      // but if I die first, don't kill my parent
        }
    ....
        CameraService::instantiate();
    ....
    }
}
cs


 위의 소스코드에서 보시는 바와 같이 CameraService::instantiate() 함수가 실행됨으로서 ServiceManager에 등록되는 과정이 진행됩니다. 그런데 막상 CameraService.cpp 내에서 imstantiate() 함수는 눈을 씻고 보아도 어디에도 보이지 않습니다. 이는 즉 다른 클래스에서 상속되었다는 뜻으로 볼 수 있을텐데요. 그렇다면 이를 직접 찾아보도록 하겠습니다.


/frameworks/av/services/camera/libcameraservice/CameraService.h

1
2
3
4
5
6
7
8
9
10
11
12
....
#include <binder/BinderService.h>
....
class CameraService :
    public BinderService<CameraService>,
    public BnCameraService,
    public IBinder::DeathRecipient,
    public camera_module_callbacks_t
{
    friend class BinderService<CameraService>;
....
}
cs

/frameworks/native/include/binder/BinderService.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#ifndef ANDROID_BINDER_SERVICE_H
#define ANDROID_BINDER_SERVICE_H
 
#include <stdint.h>
 
#include <utils/Errors.h>
#include <utils/String16.h>
 
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
 
// ---------------------------------------------------------------------------
namespace android {
 
template<typename SERVICE>
class BinderService
{
public:
    static status_t publish(bool allowIsolated = false) {
        sp<IServiceManager> sm(defaultServiceManager());
        return sm->addService(
                String16(SERVICE::getServiceName()),
                new SERVICE(), allowIsolated);
    }
 
    static void publishAndJoinThreadPool(bool allowIsolated = false) {
        publish(allowIsolated);
        joinThreadPool();
    }
 
    static void instantiate() { publish(); }
 
    static status_t shutdown() { return NO_ERROR; }
 
private:
    static void joinThreadPool() {
        sp<ProcessState> ps(ProcessState::self());
        ps->startThreadPool();
        ps->giveThreadPoolName();
        IPCThreadState::self()->joinThreadPool();
    }
};
 
 
}; // namespace android
// ---------------------------------------------------------------------------
#endif // ANDROID_BINDER_SERVICE_H
 
 
cs


 위의 코드에서 보시는 바와 같이 instantiate() 함수는 BinderService 클래스에서 이루어지고 있는 모습을 보실 수 있습니다. 그리고 그 안에는 publish() 함수가 실행되고 있으며 publish() 함수는 CameraService를 IServiceManager에 등록하고 있는 과정을 보이고 있습니다.


return sm->addService(

                String16(SERVICE::getServiceName()),
                new SERVICE(), allowIsolated);


static char const* getServiceName() { return "media.camera"; }



 위 코드를 통해 CameraService는 IServiceManager에 등록됩니다.

/frameworks/native/libs/binder/IServiceManager.cpp

1
2
3
4
5
6
7
8
9
10
11
12
    virtual status_t addService(const String16& name, const sp<IBinder>& service,
            bool allowIsolated)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
        data.writeString16(name);
        data.writeStrongBinder(service);
        data.writeInt32(allowIsolated ? 1 : 0);
        status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
        return err == NO_ERROR ? reply.readExceptionCode() : err;
    }
 
cs






300x250