2012년 4월 29일 일요일

웹 표준으로 만드는 안드로이드 웹앱 (한빛미디어)



이 책의 제목을 처음 접했을 때, 웹 앱을 만드는 방법을 소개하는 책이구나 하는 생각이
들면서, 과연 안드로이드 용 웹앱은 무엇을 말하는 것인가 하는 궁금증이 생겼습니다.
그리고 큰 제목 아래 깨알같이 많은 기술을 나열하고 있습니다.
HTML, CSS, 자바스크립트, 제이쿼리, 제이큐터치, 폰갭 등의 기술들이 제목 아래 쓰여
있는데, 이렇게 200페이지도 안 되는 얇은 책이 이런 기술을 다 커버할 수 있나 하는 의구심이
들었고, 맛보기용 도서일 수도 있겠다 하는 생각이 들었습니다.
책을 읽고 나서 안드로이드 용 웹 앱은 이렇게 만드는 겁니다 라고 쉬운 말로 이야기를
들었다는 느낌이었습니다.

이 책은 웹 앱 중에서도 안드로이드(모바일) 용 웹 앱에 대한 설명을 하고 있습니다.

모바일 환경은 작은 화면, 터치 인터페이스 등등 PC에서의 웹 앱 사용 시나리오와는
많은 차이가 있습니다.
이 책은 이 차이를 어떻게 웹 앱에서 줄여줄 것인가를 가이드하고 있습니다.
물론 책 제목에 쓰인 많은 기술들(HTML, CSS, 자바스크립트, 제이쿼리, 제이큐터치, 폰갭)을
설명하고 있지만 이 기술들은 맛보기로 언급하는 수준일 뿐입니다.
물론 이러한 기술들을 잘 모르는 독자들은 이 책으로 위 기술들이 무엇인가 감을 잡을 수가
있을 것입니다.

이 책은 모바일용 웹앱 제작을 어떻게 하는것인가가 핵심으로써 위의 기술들을 잘
아는 전문가라고 하더라도 모바일 환경에서의 웹 앱 경험이없는 개발자라면 이 책을
추천하고 싶습은니다.

개정판 답게 철자 오류 등도 다른 책에 비해 작고, 번역도 상당히 매끄럽습니다.

모바일용(안드로이드) 웹 앱을 개발하고 싶다면 이 책부터 읽기를 추천드립니다!

2012년 4월 14일 토요일

Chromium Bug - 82276 (1)

소스분석을 하면서 사소한 패치들을 올려왔다.
지금까지 여러개의 패치를 올렸지만 모두 사소한 것들이라 패치라고 하기에도 민망하긴 하다.

이젠 알려진 버그 해결을 시도해볼 계획이다.
지금까진, Chromium의 구조를 다 이해하지 못해서 망설이고 있었지만,
Chromium committer가 목표를 높게 가져보라는 말을 듣고, 시도를 해볼 계획이다.

http://code.google.com/p/chromium/issues 로 가면 현재 Chromium의 버그 리포팅들을 볼 수 있고, 진행 상태를 알 수 있다.

쭈욱 살펴보니 대부분은 내용을 알수없는 버그들이다...
무엇을 골라야할지 고민하다, 그래도 버그 내용이 이해가 되는 것을 골랐다.


브라우저에서 웹페이지 내의 문자열을 찾을때, Ctrl+F 를 통해 찾게된다.
위 버그는 gmail 에서 발견된 버그인데, gmail의 경우 엮인 메일들이 많을경우,
엮인 메일중 특정 메일의 내용을 접을수가 있다.
접힌상태의 메일에 포함된 문자열을 검색하면, 접힌 상태이므로 검색이 안된다.
그런데, 접힌 메일을 풀게되도 Find Bar에 입력된 문자열이 자동으로 강조(highlight)되지 않는다.

이 버그를 잡아보려한다.

어디서 시작해야할지는 전혀 감이 안오지만, 멘땅에 헤딩해보자!

Thank you Peter & Carlos.

2012년 4월 12일 목요일

Content Shell - 분석 방향 고민..

지난 포스트에서는 ShellBrowserMain()에서 content::BrowserMainRunner 객체를 생성하고, 이
객체의 초기화(Initialize()), 실행(Run())을 통해 Content Shell이 구동되는 것을 보았다.
ShellBrowserMain()의 마지막에 실행되는 Run()이고 이 함수가 종료되면 브라우저가 종료된다.
BrowserMainRunnerImpl 객체는 BrowserMainLoop 객체를 통해 실제 브라우저의 구동을 수행하고 있다.

이제 이 단계에서 Content Shell 분석의 방향이 어디로 진행되어야할 지 고민이다.
브라우저의 실행 코드를 따라가며 분석을 해야할 지, 아니면 src/content/shell 아래의 내용에
대한 분석을 이어나가야 할 지 말이다.

고민결과, 브라우저 코드를 따라가면서(BrowserMainLoop) 분석을 하는 것이 맞을 것 같다.
Content Shell만의 내용 분석은 조금 늦어지겠지만, 브라우저 코드를 분석하다보면 브라우저의 전체 실행 흐름에 대해서도 알 수 있을 것이다.
Content Shell 부분은 Content Module에서 ContentClient를 참조하는 부분을 통해 언제 어느 부분에서 Shell이 참조되는지 알게 될 것이다.

따라서 다음 포스트부터 BrowserMainLoop 클래스에 대해 분석을 시작하겠다.

2012년 4월 4일 수요일

Content Shell - ShellBrowserMain()

앞 포스트에서 ContentMainRunner::Run()에 대해 알아보았다.

Content Shell의 main()에서 ShellMainDelegate 객체를 생성하고, ContentMain()은 파라미터로
전달된 이 객체 레퍼런스를 이용해서 Content Module의 핵심 클래스인 ContentMainRunner 객체를
생성한다.
ContentMainRunner::Initialize()에서 Content Module의 초기화가 진행되고, ContentMainRunner::Run()에서는 process_type을 ContentMainRunner::RunNamedProcessTypeMain()에 전달을 한다.


이 RunNamedProcessTypeMain()에는 전달받은 type에 맞는 함수를 호출하게되는데,  호출 전에 delegate(ShellMainDelegate) 가 있으면 delegate의 RunProcess()를 먼저 호출하고,
delegate의 RunProcess()에서 에러를 리턴하면 process_type에 매칭되는 함수를 Content Module에서 kMainFunctions[]에서 매칭되는 함수를 호출한다.

이 번 포스트에서는 delegate(ShellMainDelegate)의 RunProcess()의 동작에 대해 살펴보자.

ShellMainDelegate::RunProcess()는 type이 빈 문자열("")인 경우에만 ShellBrowseMain()을 호출한다. ShellBrowseMain()은 src/content/shell/shell_browser_main.cc 에 구현되어 있다.

이 함수는 크게 세 부분으로 나뉜다.
content::BrowserMainRunner 객체 생성(Create()), 객체 초기화(Initialize()), 객체 실행(Run()).
ContentMain()에서의 ContentMainRunner 객체와 비슷한 동일한 패턴으로 실행이 된다.
클래스 이름을 보니 ContentMainRunner 클래스가 주 Runner이고 BrowserMainRunner 가 서브 Runner 인 것같다.

BrowserMainRunner 객체 생성할 때는 delegate(ShellMainDelegate)가 전달되지는 않는다.
그렇다면 BrowserMainRunner 에서는 ShellMainDelegate를 전혀 참조하지 않을까?

ShellMainDelegate::PreSandboxStartup()에서 content::SetContentClient()를 통해 Content Module에 process_type에 해당되는 Client 를 셋팅하였다. 지금의 process_type은 빈 문자열 이므로 Content Module의 browser client 에 ShellContentBrowserClient 가 셋팅되어 있다.

BrowserMainRunner 객체가 Client(Content Shell)의 참조가 필요할 때, ShellContentBrowserClient 객체 포인터가 참조가 될 것이다.

그렇다면 언제 참조가 될까?

먼저 ShellContentBrowserClient 객체에 대해 살펴보면 이 Client 객체가 Content Module에서 어떤일을 할 것인지 알 수 있을것이다.

다음 포스트에서는 ShellContentBrowserClient 에 대해 알아보자.

2012년 4월 3일 화요일

ContentMain - ContentMainRunner (2)


지난 포스트에서는 ContentMain()에서 ShellMainDelegate 가 처음 참조되어 사용도는 부분인
ContentMainRunner 의 Initialize()를 살펴보았다.

이번 포스트에서는 ContentMain()의 핵심 호출인 ContentMainRunner::Run()에 대해 살펴보자.

아래의 ContentMain()를 보면 Run()은 Chromium 브라우저가 실행되는 동안 호출되는 함수이다.
Run()이 리턴되면 Chromium도 종료가 된다.


Run() 구현부분을 보자. 아래 소스코드에서 처럼 process type 값과, 생성한 content::MainFunctionParams 객체, 그리고 delegate_ (ShellMainDelegate)를 RunNamedProcessTypeMain()의 매개변수로 전달한다. Run()이 하는일은 이것이 전부다.


process type이 무엇일까? CommandLine(src/base/command_line.cc) 객체에서 가져오는것을 보니 command line에서 전달되는 값인것 같 Initialize()다. switches::kProcessType(src/content/public/common/content_switches.cc)은 "type" 문자열이다.
content_shell을 실행시키고 ps 를 통해 content_shell 관련 정보를 보면 다음과 같다.


총 다섯개의 프로세스가 떠있고, 두개는 type이 없으며 나머지 세개의 프로세스의 type은 각각 zygote, renderer, gpu-process 이다.

Run()에서 가져오는 type이 위의 type switch의 값이다.
사용자가 content_shell을 실행할 때는 파리미터 전달없이 실행시키므로 아래의 복잡한 파라미터들이 설정되어 실행되는 content_shell 프로세스들은 런타임이 fork()가 된것들일 것이다.

이렇게 process type이 설정이 된다음, MainFunctionParams 객체가 생성이 되는데, 이 객체는 Platform 의존적인 부분이 포함된 ComandLine의 Wrapper 객체이다.

이제 Run()에서 마지막으로 호출되는 RunNamedProcessTypeMain()에 대해 살펴보자.


RunNamedProcessTypeMain()은 process_type 으로 전달된 문자열을 가지고 kMainFunctions 배열에서 실행시킬 함수포인터를 찾는다. 지금은 빈 문자열("")이 전달되었기때문에 BrowserMain이 실행될 함수포인터에 해당된다.
이 함수가 실행되기전!!! 드디어 우리의 관심사인 delegate(ShellMainDelegate)가 참조되고 있는 것을 볼수 있다.
ShellMainDelegate::RunProcess()이 호출되고 kMainFunction[] 배열에서 process_type("")에 해당하는 BrowserMain이 호출이됨으로써 content_shell 이 실행이 되고 있다.

이번 포스트에서는 ContentMainRunner::Run() 에 대해 살펴보았다.
다음 포스트에서는 ShellMainDelegate::RunProcess()가 호출하는 ShellBrowserMain()에 대해 알아보자.