2012년 5월 4일 금요일

Chromium Bug - 82276 (2)

Chromium - Notification Registration/Handler

이 버그를 어떻게 풀어나갈지 고민 중이다.

우선 Find Bar를 언제 Refresh 해야할까? (여기서 Refresh란 다시 find 동작을 수행하는 것이다.)
웹페이지의 Re-Paint 이벤트는 이 상황에서 적당한 이벤트 일까?
Re-Paint 이벤트는 웹페이지 내 커서만 깜빡여도 발생하므로 Refresh 가 쉴새 없이 진행될 것이다.
따라서 Refresh 이벤트로 사용하기에는 부적절한 것 같다.
이 경우에 쓸만할 적당한 이벤트가 무엇이 있을까?
흠... 이 버그를 보이게 한 시작점은 폴딩된 메일의 클릭이므로, 마우스 클릭 이벤트를 Refresh 이벤트로 사용해보자!

소스코드를 뒤진 결과 다음과 같은 이벤트가 있다.
content::NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_INPUT_EVENT_ACK
이 이벤트는 RenderWidgetHostImpl 객체에서 인풋 이벤트 처리가 끝난 후, Notify 하고 있다.
인풋 이벤트 처리 후가 Refresh 시점에 적절한 지는 좀 더 생각을 해봐야하겠지만, 우선은
인풋 관련 해서 현재 Noti 하고있는 이벤트는 이것뿐인 것 같으므로 사용해보자.

그렇다면 이 이벤트는 언제 받아보면 될까?
브라우저가 실행되고 있다고 해서 이 인풋 이벤트를 받아볼 필요는 없다.
Find Bar 가 떠 있는 상태에서만 인풋 이벤트를 받아서 처리하면 될 것이다.
그렇다면 Find Bar의 보이기/사라지기 가 수행되는 시점을 찾아서 보이기 시점에 인풋 이벤트를 구독하고
사라지는 시점에 구독하던 이벤트를 제거하면 될 것 같다.
Find Bar는 FindBarController::Show()에서 FindBar를 보이게 하고, FindBarController::EndFindSession()에서 사라지게 하고 있다.
따라서 인풋 이벤트는 Show() 호출 시 이벤트와 핸들러를 등록하고, EndFindSession() 불릴 때, 제거하면 될 것같다.

그렇다면...
Chromium은 이벤트 등록/핸들러를 어떻게 할까?

원하는 이벤트의 등록을 위해 NotificationRegistrar 클래스를 제공하고 있다.
이 클래스는 content/public/browser/notification_registrar.h 에 정의되어 있다.
이벤트 핸들러구현을 위해서는 NotificationObserver 클래스를 제공하고 있고,
content/public/browser/notification_observer.h 에 정의되어 있다.

원하는 이벤트 등록을 위해서는 NotificationRegistrar 클래스를 사용해야한다.
아래 그림은 content::NotificationRegistrar 클래스 이다.
public 함수들을 보면 Add(), Remove(), RemoveAll() 등등 이벤트 등록에 필요한 함수들이
구현되어 있음을 알 수 있다.



이벤트 핸들러 등록을 처리하는 NotificationObserver 에 대해서 알아보자.
아래 소스를 보면 NotifiationObserver 는 추상클래스 이다.


핸들러 등록을 원하는 클래스에서 이 추상 클래스를 구현하면 등록한 이벤트가 발생했을때,
이 클래스의 Observe() 함수가 호출이 됨으로써 등록한 핸들러가 실행이 된다.

다음 포스트에서는 FindBarController 클래스의 Show()/EndFindSession()에서 이벤트의 등록/핸들러 구현을 해보겠다.

댓글 없음:

댓글 쓰기