날마다 새롭게 또 날마다 새롭게

안드로이드의 모든 것 분석과 포팅 - 4장 안드로이드 Input Device 요약 본문

프로그래밍/Android

안드로이드의 모든 것 분석과 포팅 - 4장 안드로이드 Input Device 요약

아무유 2013. 1. 14. 15:56

1. Input Device 개요

1.1 리눅스 2.6에서 Input Device Driver 특징

커털 2.4에서 사용하던 카테고리별 입력장치를 표준화하여 하나의 인터페이스로 통일화했다.

1.2 Input Device Driver 구조

- Device Driver : 하드웨어의 입력을 처리

- Event Handler : 입력 정보를 애플리케이션에게 전달



1.3 Device Driver가 응용프로그램으로 데이터를 올리는 방법 (Event Handler)

- include/linux/input.h

struct input_event : 이 구조체를 이용해서 데이터를 응용프로그램으로 전달함

1.4 Input Device Driver에 등록된 event interface와 디바이스 정보 확인

- proc 파일시스템 이용

/proc/bus/input/devices : 현재 시스템에 연결되어 있는 디바이스.

/dev/input/* : event interface 장치

응용프로그램에서 event 디바이스 파일을 열어서 디바이스의 특성을 ioctl로 파악한 후, 적절한 입력장치로부터 데이터를 입력받는다.

1.5 Input Device가 적절하게 데이터를 전달하는지 확인하는 코드 aesopev.c

- key input test : ./aesopev key

- touch test : ./aesopev touch

2. 안드로이드 Input Device Driver

2.1 안드로이드 Input Device 예

- keyboard : /dev/input/event0

- Touchscreen : /dev/input/event1

- Switch driver : /dev/input/event2

2.2 안드로이드 Key Driver

2.2.1 안드로이드는 커널에서 올라오는 입력장치를 EventHub에서 처리하고, 안드로이드의 key layout file과 비교한 후, 애플리케이션 Framework 쪽으로 해당 키 값을 올려준다.

-키보드의 키에 할당되어 있는 key scancode 값 확인

- include/linux/input.h

- drivers/input/keyboard/s3c-keypad.c

- 안드로이드로 올라가는 keycode 값 확인

- 안드로이드 Rootfs/system/usr/keylayout/qwerty.kl

- keycode와 flag 선언 : 안드로이드/frameworks/base/include/ui/KeycodeLabels.h

- KeyLatoutMap 클래스 : 안드로이드/frameworks/base/libs/ui/KeyLayoutMap.h와 KeyLayoutMap.cpp에 정의됨.

2.3 안드로이드 Touchscreen Driver

2.3.1 Touch Panel Device Driver 동작 절차

- X-Window : Touch Device > ADC > Device Driver > TS Lib > X-Windows

- 안드로이드 : Touch Device > ADC > Device Driver > Android

안드로이드는 device driver에서 안드로이드 시스템으로 직접 리포팅하여 터치스크린 입력을 처리한다.

2.4 안드로이드 Switch Event Device Driver 등록 방법

Input Device Driver 중 EV_SW(Switch Event) 타입을 갖는 device driver로 작성해야 함.

- include/linux/input.h

- SW_LID 이벤트가 발생할 수 있도록 적절하게 코드를 작성해야 한다.

interrupt 처리 함수

input device driver 등록 함수

- 최종적으로 PhoneWindowManager.java로 올라가 필요 동작을 하도록 코드를 작성한다.

3. 안드로이드 Input Manager

3.1 안드로이드 Input Device 처리 구조

Kernel > EventHub > NativeInputManager - JNI > InputManager > WindowManager > PhoneWindowManager

 frameworks/base/services/java/com/android/server/WindowManagerService.java - Framework

 frameworks/base/services/java/com/android/server/InputManager.java - Framework

 frameworks/base/services/jni/com_android_server_InputManager.cpp - JNI

 frameworks/base/libs/ui/InputManager.cpp - Native

- InputManager ~ Native 함수까지 시작 호출 과정정

① WindowManagerService.jave


② InputManager.java


 com_android_server_InputManager.cpp


 InputManager.cpp


3.3 InputReader 클래스와 InputDispatcher 클래스



3.3.1 InputReader 클래스 처리 순서

Input Device에 의해 들어온 데이터를 읽어와서 처리하는 클래스다.

1) InputManger.cpp - start()에서 run()함수 호출

2)  InputReader.cpp - InputReaderThread에서 loopOnce()함수 수행

3) InputReader.cpp - loopOnce에서 mEventHub 객체를 통해 getEvent() 함수를 호출하여 이벤트 데이터를 가져오고 process() 함수를 호출한다.

4) InputReader.cpp - process - prcoess함수는 EventHub를 통해 받아온 이벤트를 처리한다. 처리되는 이벤트는 4종류로 분류된다. ( DEVICE_ADDED, DEVICE_REMOVED, FINISHED_DEVICE_SCAN, 기타)

① DEVICE_ADDED - addDevice()함수 - createDevice()를 호출하여 InputDevice 클래스를 생성하고 InputDevice의 configure() 함수를 호출함


② DEVICE_REMOVED - removeDevice() - 인자로 넘어온 deviceId를 가지고 deviceIndex를 구해서 해당 InputDevice 클래스를 삭제한다.


③ FINISHED_DEVICE_SCAN - handleConfigurationChanged() - InputDevice의 configuration을 업데이트한다.


④ 나머지 - consumeEvent() - deviceId로 deviceIndex를 찾아서 InputDevice 클래스 정보를 가지고 온다. 그 다음 process() 함수를 호출한다.

InputReader.cpp - InputDevice::process()

InputReader.cpp - KeyboardInputMapper::process() - key 이벤트인 경우만 처리되고, processKey()함수를 호출한다.

InputReader.cpp - KeyboardInputMapper::processKey() - key 이벤트를 처리하고  InputDispatcher의 notifyKey()함수를 호출한다.


3.3.2 InputDispatcher 클래스 처리 순서

InputReader 클래스에서 처리된 이벤트 데이터를 저장하고 처리한다.

1) InputDispatcher.cpp - notifyKey() - 발생한 이벤트가 유효한지 validateKeyEvent()로 확인한 다음 - KeyEntry를 생성하고 - enqueueInboundEventLocked() 함수를 호출한다.



Comments