• 서비스 프레임워크 


    : 안드로이드 플랫폼에서 동작하는 서비스를 개발하기 위한 클래스의 집합
    : 서비스의 설계와 구현을 재사용 가능한 형태로 제공

     서비스 인터페이스 : 서비스 인터페이스는 서비스가 제공하는 기능을 함수 형태로 선언하여 이를 상속받은 서비스와 서비스 프록시가 모두 동일한 인터페이스로 서비스를 제공하고 사용할 수 있는 구조를 제공한다.
     서비스 생성 : 서비스 생성 기능은 서비스와 서비스 프록시의 생성을 지원한다. 서비스에서는 서비스 인터페이스에 정의된 함수를 구현(서비스 스텁 함수)하고 서비스 프록시에서는 서비스 스텁 함수를 원격 호출(서비스 프록시 함수)할 수 있게 구현해준다. 서비스 프레임워크에서는 서비스 프록시가 서비스를 요청할 수 있게 서비스의 위치 정보(서비스 핸들)를 제공하고, 서비스가 서비스 요청을 수신할 수 있는 방법을 제공한다.
     바인더 IPC 처리 : 서비스 프레임워크는 서비스와 서비스 사용자 사이에 바인더 IPC를 지원하기 위해 바인더 IPC 데이터를 생성하고 바인더 드라이버와 통신할 수 있는 기능을 제공한다.
     서비스 매니저 : 서비스 매니저는 시스템에 서비스를 등록하고 검색할 수 있는 기능을 제공한다.
     

  • 네이티브 서비스 프레임워크
    : C++로 작성되어 있으며, library layer에서 동작


    - 레이어
     

     1. 서비스 사용자가 foo() 함수를 호출하면, BpFooService의 foo() 프록시 함수가 호출 된다.
     2. BpFooService의 foo() 프록시 함수는 TRANSACTION_FOO RPC 코드와 인자값을 RPC 데이터로 변환한 후, BpBinder 클래스의 transact() 함수를 호출해서 RPC 코드와 데이터를 전달한다.
     3. BpBinder의 transact() 함수는 전달받은 RPC 코드와 데이터에 FooService 서비스의 서비스 핸들 정보를 추가한 후 IPCThreadState 클래스의 transact() 함수에 인자로 전달한다.
     4. IPCThreadState 클래스의 transact() 함수는 전달받은 데이터에 BC_TRANSACTION 바인더 프로토콜을 추가하여 바인더 IPC 데이터를 생성하고 이것을 바인더 드라이버에 전달한다.

     4. 바인더 드라이버는 IPCThreadState에게 바인더 IPC 데이터 정보를 전달한다. 그러면 IPCThreadState의 executeCommand() 함수에서 데이터를 분석하여 BR_TRANSACTION 바인더 프로토콜인 경우에 BBinder 클래스의 transact() 함수를 호출한다. 이때 transact() 함수의 인자로 서비스 클라이언트로부터 수신된 RPC 코드와 데이터가 전달된다.
     3. BBinder는 RPC 코드를 분석하여 기본적으로 제공하는 서비스 함수가 아닌 경우에 onTransact() 함수를 호출한다. 그런데 BnFooService가 BBinder를 상속하여 onTransact() 함수를 재정의했으므로 BnFooService 서비스 스텁의 onTransact() 함수가 호출된다. BBinder로 부터 전달받은 데이터는 다시 onTransact()의 인자로 전달한다.
     2. BnFooService의 onTransact()에서는 전달받은 RPC 데이터를 분석하여 TRANSACTION_FOO RPC 코드가 의미하는 FooService의 foo() 스텁 함수를 호출한다. 일반적으로 스텁 함수 호출시 RPC 데이터에 대한 언마샬링이 수행되어 인자로 전달되지만, foo() 스텁 함수는 인자가 없으므로 언마샬링이 수행되지 않는다.
     1. FooService의 foo() 서비스 스텁 함수가 실행된다.


    - 프록시


    - 스텁


    - 바인더 연결


  • 클래스 구조


    -
     IBinder, BBinder, BpBinder 
     : IBinder 클래스는 안드로이드 바인더를 추상화한 것이며 자식 클래스로 BBinder, BpBinder 클래스가 있다.
      BBinder 클래스는 RPC 코드와 데이터를 수신하는 역할과 바인더 드라이버 내부에 바인더 노드를 생성할 때 이용하는 바인더 객체로서의 역할을 담당.
      BpBinder 클래스는 목적지 서비스의 핸들 정보를 저장하고 바인더 드라이버가 서비스 서버의 바인더 노드를 찾을 때 이용하는 바인더 객체로서의 역할을 담당.  
    - IInterface, BnInterface, BpInterface
     : IInterface 클래스는 서비스나 서비스 프록시 클래스를 IBinder 타입으로 형변환하는 기능을 제공한다. 실제로 형변환은 BnInterface 클래스와 BpInterface 클래스에서 일어나며, BnInterface는 서비스 클래스를 BpInterface는 서비스 프록시 클래스를 IBinder 타입으로 형변환한다. 형변환이 필요한 이유는 바인더 객체를 바인더 드라이버를 통해 전송해야 하기 때문이다. 예를 들어, 서비스를 시스템에 등록하는 경우 서비스 클래스를 IBinder 타입으로 형변환해서 컨텍스트 매니저에 전달해야한다.
    - ProcessState, IPCThreadState
     : ProcessState  클래스는 바인더 드라이버를 관리하며 IPCThreadState 클래스는 서비스 클라이언트 및 서비스 서버와 바인더 드라이버 간의 바인더 IPC를 위한 통신을 지원한다.
    - Parcel
     : Parcel 클래스는 서비스와 서비스 프록시 사이에서 바인더 IPC가 진행되는 동안 바인더 IPC 데이터를 저장하는 역할을 담당한다. Parcel 클래스가 처리할 수 있는 데이터는 C언어의 기본 자료형 및 기본 자료형의 배열, 바인더 객체, 파일 디스크립터 등이 있다.
    - 서비스 레이어
     : IInterface, BnInterface, BpInterface, BpRefBase, 서비스 인터페이스, 서비스 클래스
    - RPC 레이어
     : 서비스 프록시 클래스, 서비스 스텁 클래스
    - IPC 레이어
     : BBinder, BpBinder, IPCThreadState, ProcessState, Parcel

  • 네이티브 서비스 매니저
    : 안드로이드 플랫폼에는 오디오 디바이스를 관리하는 Audio Flinger, 화면으로 보이는 프레임 버퍼 디바이스를 관리하는 Surface Flinger, 카메라 디바이스를 관리하는 카메라 서비스 등 각종 서비스가 있고, 이러한 서비스의 정보와 목록을 컨텍스트 매니저가 관리, 서비스는 자신의 이름으로 컨텍스트 매니저에 서비스 등록을 요청하고, 서비스 사용자는 접근하고자 하는 서비스의 이름으로 컨텍스트 매니저로부터 서비스의 정보를 획득.
    : 서비스 프레임워크에서는 서비스 사용자가 Audio Flinger, Surface Flinger, 카메라 서비스와 같은 각 서비스에서 제공하는 기능을 사용할 수 있게 바인더 RPC를 처리해 주는 서비스 프록시(Service Proxy)를 제공, 서비스 사용자는 서비스 프록시를 통해 해당 서비스의 기능을 사용하며, 서비스 프록시와 서비스 간의 복잡한 바인더 RPC는 하위 수준의 서비스 프레임워크에서 이뤄지므로 상위 수준의 서비스 사용자는 마치 동일한 프로세스에서 서비스를 이용하는 것처럼 느끼게 된다. 즉 서비스 프록시를 서비스라 생각하게 되는 것
    : 서비스 매니저는 컨텍스트 매니저의 서비스 프록시에 해당
     


    : 네이티브 서비스 매니저는 (2)에 해당한다.
    : 자바 시스템 서비스는 (3)의 자바 레이어의 서비스 매니저를 통해 서비스를 등록하고,
    네이티브 시스템 서비스는 (2)의 C/C++ 레이어의 서비스 매니저를 통해 서비스를 등록한다.
    (3)의 자바 레이어의 서비스 매니저는 JNI를 통해 (2)의 C/C++ 레이어의 서비스 매니저와 연결되고, C/C++ 레이어의 서비스 매니저는 바인더 드라이버를 통해 (1)의 컨텍스트 매니저와 바인더 RPC를 수행한다.

    - 서비스 매니저의 클래스 계층 구조와 바인더 RPC 과정


    - 서비스 매니저의 동작
    1. 서비스 매니저 초기화
     

    2. 서비스 등록
     
    3. 서비스 획득
     

    - 바인더 RPC 데이터와 코드, 바인더 IPC 데이터의 처리 과정



'Programing > Android' 카테고리의 다른 글

Parcelable vs. Serializable  (0) 2016.03.22
안드로이드 - 자바 시스템 프레임워크  (0) 2016.01.26
안드로이드 - 바인더  (0) 2016.01.08
안드로이드 - 서비스  (0) 2016.01.08
안드로이드 - Zygote  (0) 2016.01.06
  • 바인더?
    : 원래 IPC(Inter Process Communication) 도구이지만 안드로이드에서는 다른 프로세스에 있는 함수를 마치 현재 프로세스에 존재하는 함수처럼 사용할 수 있게 해주는 RPC(Remote Procedure Call)를 지원하는 데 주로 이용
    - 안드로이드에서 바인더 드라이버를 추가해서 프로세스 간 통신을 수행하는 이유? 
     : 리눅스의 뛰어난 메모리 관리 기법을 그대로 채용함으로써 커널 공간을 통한 데이터 전달시 데이터의 신뢰성을 확보
     : 사용자 공간에서 접근할 수 없는 공간인 커널 공간을 이용해 데이터를 주고 받기 때문에 IPC 간의 보안 문제도 동시에 해결

      


  • 리눅스 메모리 공간과 바인더 드라이버
    : 안드로이드의 프로세스는 리눅스와 마찬가지로 프로세스만의 고유한 가상 주소 공간에서 실행
    : 총 4GB에 달하는 가상 주소 공간은 3GB의 사용자 공간과 1GB의 커널 공간으로 나뉜다(커널 설정으로 변경 가능함)
    : 사용자 코드와 관련 라이브러리는 사용자 공간의 코드 영역, 데이터 영역, 스택 영역에서 동작하고, 커널 공간에서 동작해야 할 코드는 커널 공간의 각 영역에서 동작
    : 서로 다른 프로세스들은 커널 공간에서 실행하는 태스크와 데이터, 코드는 서로 공유
    : 바인더 드라이버에 존재하는 다양한 구조체는 대부분 레드 블랙 트리로 관리


  • 안드로이드 바인더 모델
    : 핸들은 서비스를 구별하는 번호, 어떤 서비스에 바인더 IPC 데이터를 전달해야 하는지를 결정
    : RPC 코드 RPC 데이터는 서비스에 호출할 함수와 함수의 인자
    : 바인더 프로토콜은 IPC 데이터의 처리 방법



    - 바인더 IPC 데이터의 전달
     : 바인더를 통해 RPC를 시도하는 응용 프로그램은 open() 시스템 콜을 통해 바인더 드라이버의 파일 디스크립터를 얻는다.
     : mmap() 시스템콜을 통해 커널 내에서 IPC 데이터를 수신하기 위한 공유 공간을 확보한다.
     : ioctl() 함수의 인자로 바인더 드라이브에 IPC 데이터를 전달한다.



    - 바인더 IPC 데이터의 흐름
     ■ 서비스 계층: 특정 기능을 수행하는 서비스의 함수가 존재하는 계층이다. 서비스 클라이언트는 이 계층에서 사용하고자 하는 서비스의 함수를 가상으로 호출하고, 서비스 서버는 서비스 클라이언트가 요청한 서비스의 함수를 실제로 호출한다.
     ■ RPC 계층: 서비스 클라이언트는 이 계층에서 서비스의 함수를 호출하기 위한 RPC 코드와 RPC 데이터를 생성한다. 서비스 서버는 전달받은 RPC 코드를 토대로 함수를 찾고 RPC 데이터를 전달한다.
     ■ IPC 계층: RPC 계층에서 만든 RPC 코드와 RPC 데이터를 바인더 드라이버에 전달하기위한 바인더 IPC 데이터로 캡슐화하는 역할을 한다. 실제로 서비스 클라이언트는 서비스 서버에 존재하는 서비스의 함수를 사용하기 위해 각 함수에 해당하는 식별자를 바인더 IPC 데이터에 담아 전달하는데, 이를 RPC 코드라 하며 함수의 인자 역시 IPC 데이터에 담아 전달하는데, 이것은 RPC 데이터라고 한다.
     ■ 바인더 드라이버 계층: IPC 계층으로부터 전달받은 바인더 IPC 데이터를 통해 서비스를 가진 서비스서버를 찾은 후 IPC 데이터를 전달한다.


    - 바인더 어드레싱
     : 바인더 드라이버는 IPC 데이터의 핸들을 가지고 서비스 서버를 찾는데, 이러한 과정을 바인더 어드레싱(Binder Addressing)이라고 정의
     : 다양한 서비스를 모두 목록화해서 관리하는 컨텍스트 매니저라는 특별한 프로세스가 서비스마다 핸들(바인더 IPC의 목적지 주소로 사용)라는 번호 값을 할당하고, 서비스 추가/검색 등의 관리 기능을 수행

     ■ 서비스 등록
      : 바인더 어드레싱을 위해 서비스 서버는 자신이 가진 서비스에 대한 접근 정보를 컨텍스트 매니저에 등록해야 한다.
      : 안드로이드 부팅 단계에서 끝나고, 등록이 끝나면 컨텍스트 매니저의 서비스 목록, 바인더 드라이버의 바인더 노드, 그리고 서비스 서버들의 서비스가 연결되어 다른 프로세스가 사용가능한 상태가 된다.
      : 서비스 서버와 컨텍스트 매니저 사이의 IPC

     
     ■ 서비스 검색
      : 서비스 클라이언트와 컨텍스트 매니저 사이의 IPC


     ■ 서비스 사용
      : 서비스 클라이언트와 서비스 서버 사이의 IPC


    mmap
     
      : 일반적으로 커널 공간에서 사용자 공간으로 데이터를 전달하기 위해서는 copy_to_user() 함수를 이용해서 사용자 공간으로 데이터를 복사한다.
      : but, 대용량의 데이터를 응용 프로그램과 주고 받아야 하는 상황에서 read, write, ioctl 같은 시스템 콜 함수를 쓴다면 매우 비효율적이며, 커널 공간이 부족할수 있다. -> 문제점을 해결하기 위해 mmap을 사용, 응용 프로그램이 커널의 물리 메모리에 직접 접근 가능하도록 해 준다.
      : 바인더를 이용하는 프로세스는 바인더 드라이버의 mmap() 함수를 통해 사용자 공간과 매핑된 바인더 mmap 영역을 만든다. 그리고 바인더 드라이버는 커널 공간의 데이터 수신영역에 데이터를 저장만하고, 사용자 공간에 mmap 된 영역의 정보만 알려준다. 따라서 프로세스는 사용자 공간의 mmap 된 영역의 주소만 알고 있어도 커널 공간에 존재하는 데이터를 참조 할 수 있다.
      : 이 함수의 주요 목적은 사용자 프로세스가 전달한 크기만큼 커널 공간에 IPC 데이터 수신 버퍼를 확보하는 것이다.

  • 정리
     : 바인더는 안드로이드의 서비스를 보유한 서비스 서버, 서비스를 사용하고자 하는 서비스 클라이언트, 서비스의 위치를 알려주는 컨텍스트 매니저, 그리고 이들 모두를 중재하는 바인더 드라이버로 구성된다.



  • 서비스?
    : UI 없이 주기적으로 특정한 일을 수행하는 백그라운드 프로세스

    - 서비스 분류


  • 안드로이드 애플리케이션 서비스
    : 안드로이드 SDK의 Service 클래스를 확장한 클래스의 인스턴스로 UI 없이 주기적으로 특정한 일을 수행하는 백그라운드 프로세스
    : 애플리케이션단에서 서비스 시작, 종료, 바인딩을 통한 서비스 원격 제어 가능
     

    - 애플리케이션 서비스 분류


  • 안드로이드 시스템 서비스
    : init 프로세스에 의해 안드로이드의 부팅 과정에서 미리 실행
    : getSystemService()를 이용해서 바로 이용 가능
    : Media Server, System Server 두 시스템 프로세스에 의해 실행

    - 시스템 서비스 분류


     ■ 네이티브 서비스

      : C++로 작성
      : 여러 안드로이드 애플리케이션의 오디오 데이터를 믹싱해서 오디오 출력 장치로 내보내는 역할, 안드로이드 장치에서 모든 오디오 데이터는 Audio Flinger를 거쳐 출력.
      : Surface Flinger는 다양한 애플리케이션에서 사용중인 Surface를 조합해 프레임 버퍼 장치로 렌더링해주는 서비스 


     ■ 자바 시스템 서비스
      : 안드로이드 부팅 시 SystemServer라는 시스템 프로세스에 의해 일괄적으로 실행
      : 안드로이드 애플리케이션과 직접 상호작용은 하지 않지만 안드로이드 프레임워크가 동작하는 데 필수적인 코어 플랫폼 서비스
      : 저수준 하드웨어 제어를 위한 API를 제공하는 하드웨어 서비스

    - Layer Interaction
     : There are 3 main flavors of Android layer cake
     1. App -> Runtime Service -> lib
      
     2. App -> Runtime Service -> Native Service -> lib
      
     3. App -> 
    Runtime Service -> Native Deamon -> lib
      

    - Media Server / System Server

      ■ Media Server
      
      ■ System Server
      
      ■ Context Manager
        : 서비스 관련 요청을 수행하기 위해서는 IPC 데이터를 수신 대기하는 상태에 들어 있어야 하기 때문에 다른 서비스 서버나 서비스 클리이언트 이전에 미리 실행돼야한다.
        : init.rc 내용을 살펴보면 서비스 서버인 미디어 서버 프로세스나 시스템 서버 프로세스가 실행되기 이전에 실행(servicemanager) 됨


      

  • 안드로이드 시스템 전체 요약
    - 용어 정리
      ■ 서비스 서버 : 시스템 서비스를 실행하는 프로세스로서 앞에서 설명한 시스템 서버나 미디어 서버
      ■ 서비스 클라이언트 : 시스템 서비스를 사용하는 프로세스
      ■ 컨텍스트 매니저 : 시스템 서비스를 관리하는 안드로이드 시스템 프로세스로서 시스템에 설치돼 있는 각종 시스템 서비스의 위치 정보인 핸들을 관리. 이러한 핸들은 바인더 IPC의 목적지 주소를 지정하는 데 사용한다.
      ■ 서비스 프레임워크 : 앞에서 언급한 서비스 매니저를 포함해서 서비스 사용자와 시스템 서비스간의 RPC 동작에 필요한 공통적인 클래스가 정의
      ■ 서비스 인터페이스 : 서비스 사용자와 시스템 서비스 간에 미리 정해진 인터페이스로서 시스템 서비스는 해당 인터페이스에 맞게 스텁 함수를 구현해서 해당 서비스를 제공해야 하고, 반대로 서비스 사용자 역시 해당 인터페이스에 맞게 서비스를 호출해야 한다.
      ■ 서비스 사용자 : 서비스 클라이언트 프로세스 내에서 실제 서비스를 이용하는 모듈이다.
      ■ 서비스 : 서비스 인터페이스에 정의된 기능을 서비스 스텁 함수로 구현해서 실제 서비스의 기능을 제공하는 모듈을 의미한다.
      ■ 서비스 프록시 : RPC 수행 시 데이터 마샬링을 수행하는 객체이며 서비스 인터페이스별로 존재한다. 서비스 인터페이스에 정의된 함수별로 각각 데이터 마샬링을 수행하는 서비스 프록시 함수를 제공한다.
      ■ 서비스 스텁 : RPC 수행 시 데이터 언먀실링을 수행하는 객체이며, 이 객체 역시 서비스 인터페이스별로 존재한다. 수신된 데이터를 언마샬링해서 연관된 서비스 스텁 함수를 호출한다.
      ■ 바인더 드라이버 : 바인더는 안드로이드에서 IPC를 지원하는 데 사용되는 메커니즘으로 안드로이드 리눅스 커널의 디바이스 드라이버 형태로 포함돼 있다.
      ■ 바인더 IPC : 안드로이드에서 바인더 드라이버를 통한 프로세스간의 데이터 전달 방식을 말한다.
      ■ 바인더 IPC 데이터 : 서비스 프레임워크와 바인더 드라이버 사이에 사용되는 데이터 포맷
      ■ 바인더 RPC : 서비스 사용자가 서비스에서 제공하는 특정 서비스 인터페이스 기반의 함수를 마치 자신의 로컬 함수 호출하듯이 원격으로 처리하는 동작을 말한다. 바인더 RPC는 내부적으로는 바인더 IPC 메커니즘 기반으로 동작한다.
      ■ 바인더 RPC 데이터 : 서비스 사용자와 서비스 간의 바인더 RPC를 수행하는 데 사용되는 데이터

    - 서비스 동작 구조



     : 서비스 사용자는 foo() 프록시 함수를 호출해서 Foo 서비스를 이용하기 위한 인자로 구성된 바인더 RPC 데이터를 전달
     : 바인더 RPC 데이터는 마샬링을 거쳐 서비스 프레임워크를 통해 바인더 IPC 데이터로 생성된 다음, 바인더 드라이브를 통해 서비스 서버 측에 전송
     : 서비스 서버 측에서 수신된 바인더 IPC 데이터는 서비스 프레임워크를 거치면서 언마샬링된 다음, 서비스 스텁의 OnTransact() 함수에 전송
     : 서비스 스텁은 해당 바인더 IPC 데이터 안에 포함된 RPC 코드를 통해 Foo 서비스의 foo() 서비스 스텁 함수에 대한 바인더 RPC임을 판단
     : 수신된 바인더 IPC 데이터에 포함된 바인더 RPC 데이터를 인자로 해서 foo() 서비스 스텁 함수를 호출




'Programing > Android' 카테고리의 다른 글

안드로이드 - 네이티브 서비스 프레임워크  (0) 2016.01.13
안드로이드 - 바인더  (0) 2016.01.08
안드로이드 - Zygote  (0) 2016.01.06
안드로이드 - JNI  (0) 2015.12.23
안드로이드 - Init 프로세스  (0) 2015.12.21

+ Recent posts