안드로이드 Native 코드 분석 : DECLARE_META_INTERFACE()

안드로이드/프레임워크 2015. 3. 28. 02:29

 안드로이드 Binder 부분에 대해 공부를 하시다 보면 다음과 같은 함수를 만나게 되는 경우가 있습니다.

/frameworks/native/include/binder/IServiceManager.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
class IServiceManager : public IInterface
{
public:
    DECLARE_META_INTERFACE(ServiceManager);
 
    /**
     * Retrieve an existing service, blocking for a few seconds
     * if it doesn't yet exist.
     */
    virtual sp<IBinder>         getService( const String16& name) const = 0;
 
    /**
     * Retrieve an existing service, non-blocking.
     */
    virtual sp<IBinder>         checkService( const String16& name) const = 0;
 
    /**
     * Register a service.
     */
    virtual status_t            addService( const String16& name,
                                            const sp<IBinder>& service,
                                            bool allowIsolated = false= 0;
 
    /**
     * Return list of all existing services.
     */
    virtual Vector<String16>    listServices() = 0;
 
    enum {
        GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
        CHECK_SERVICE_TRANSACTION,
        ADD_SERVICE_TRANSACTION,
        LIST_SERVICES_TRANSACTION,
    };
};
cs

 위 함수를 처음 만났을 때 많은 분들께서 처음에는 상당히 의야해 하실 것으로 예상합니다. 사실 저것은 함수가 아니라 #define으로 정의된 매크로 함수입니다.

 해당 부분에서 MACRO 함수를 사용하는 이유는 Native의 System Service들의 Binder를 설계하다 보면 각 서비스 별로 바인더를 설계해야 하는 경우가 발생하게 됩니다. 즉, 위에 사용된 매크로 함수는 해당 서비스들의 코드를 작성하기엔 양이 많기 때문에 위와 같은 방법을 사용하여 코드 용량을 줄인 것이라고 이해하셔도 될 듯 합니다.

 이와 같은 용도로 IMPLEMENT_META_INTERFACE() 함수도 안드로이드에서는 쓰이고 있습니다. 그렇다면 DECLARE_META_INTERFACE() 함수가 어떻게 선언되어 있는지 살펴보도록 하겠습니다.


/frameworks/native/include/binder/IInterface.h

1
2
3
4
5
6
7
#define DECLARE_META_INTERFACE(INTERFACE)                               \
    static const android::String16 descriptor;                          \
    static android::sp<I##INTERFACE> asInterface(                       \
            const android::sp<android::IBinder>& obj);                  \
    virtual const android::String16& getInterfaceDescriptor() const;    \
    I##INTERFACE();                                                     \
    virtual ~I##INTERFACE();                                            \
cs


위 Macro 코드가 위 코드에서는 다음과 같이 적용됨을 알 수 있습니다.

/frameworks/native/include/binder/IServiceManager.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
class IServiceManager : public IInterface
{
public:
    static const android::String16 descriptor;                         
    static android::sp<IServiceManager> asInterface(                      
            const android::sp<android::IBinder>& obj);                 
    virtual const android::String16& getInterfaceDescriptor() const;   
    IServiceManager();                                                    
    virtual ~IServiceManager();                                          
 
    /**
     * Retrieve an existing service, blocking for a few seconds
     * if it doesn't yet exist.
     */
    virtual sp<IBinder>         getService( const String16& name) const = 0;
 
    /**
     * Retrieve an existing service, non-blocking.
     */
    virtual sp<IBinder>         checkService( const String16& name) const = 0;
 
    /**
     * Register a service.
     */
    virtual status_t            addService( const String16& name,
                                            const sp<IBinder>& service,
                                            bool allowIsolated = false= 0;
 
    /**
     * Return list of all existing services.
     */
    virtual Vector<String16>    listServices() = 0;
 
    enum {
        GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
        CHECK_SERVICE_TRANSACTION,
        ADD_SERVICE_TRANSACTION,
        LIST_SERVICES_TRANSACTION,
    };
};
cs


 위와 같은 원리로 안드로이드 Binder 관련 MACRO 함수로 IMPLEMENT_META_INTERFACE() 함수가 있습니다. 해당 매크로함수에 대한 정리는 아래 포스팅을 확인해주시기 바랍니다.

http://elecs.tistory.com/87

300x250