안드로이드 소스내 DPI변경
현재까지 받은 에뮬레이터에서는 240DPI설정이 안되는 문제가 있다.
(2011년 5월 23일 현재까지는 그랬다. 이후는 초밀도? 단말이 많이 나오면 나오겠지만..)
소스(?)를 바꾼 부분에 대해서 우여곡절을 정리한 글이다.
에뮬레이터쪽만 관심둔 부분이나, 실제 단말도 비슷하지 않을까.. (생각만 한다.)
DPI설정은 왜 바꾸길래?
개발 오더가 떨어진게 240DPI를 상회하는 단말이란다.
디자인쪽이야 포토샵으로 작업을 하니까 DPI가 어떻게 되었던, 작업을 하면서 좌표값을 DPI에 맞추서 dip로 값 변환하면 그만이다.
개발쪽은 유사환경으로 맞춰놔야 제대로 된 UI가 나올 수 있고, (간혹 DPI 관계없이 이미지를 weight를 1로 주면 배치된 갯수에 따라서 가로는 정해지지만, 세로는 dip로 좌표를 주면 어쩌라고.. -_-a) 그래야 최종 결과물이 단말에서 잘 되는지를 알 수 있다.
모든 시작이 이렇게 시작된거였다.
코드는 어떻게?
이 글 바로전에 포스팅한 Android 소스 build 하는게 먼저 코드를 받고 설치해야 해서 작업하다가 작성한 문서다.
혹시 궁금하면 빌드 포스팅한 문서를 참고.
실마리
DPI를 바꾸기 위해서 이 부분을 해결할 수 있는 방법을 찾아봤다.
(이미 단말쪽 H/W LCD단을 하고 있는 분들이라면 "피식~~"거리면서 웃고 말겠지만..)
구글신에서 수십번 문의한 결과 실마리는 다음에서 얻기 시작했다.
----------------------------
frameworks/base/libs/usrbaceflinger/DisplayHardware/DisplayHardware.cpp 를 수정하였습니다.
Displayhardware::init()의 mDpiX, mDpiX 를 수정하였습니다.
저의 LCD는 800*480 , 7inch LCD 입니다.
----------------------------
칸드로이드 기술 QnA에 2009년 2월 11일에 올라온 글이다.
우선 소스의 시작을 찾았으니..1) 여기서 부터 시작한다.
위 경로와는 다르게 현재 소스(진저브레드로 태깅된것을 받은 것 기준)으로는 DisplayHardware.cpp는 frameworks/base/services/sufaceflinger/DisplayHardware 디렉토리에 있다.
어쨌든 이 소스에서 중요한 키는 mDpiX, mDpiY에 대한 값이다.
설마 하드웨어 기준값이 C파일에서 고친다는건 좀 말이 안되고, 헤더 파일 위주로 찾아봤다. 둘어볼 만한 헤더는 DisplayHardware.h 이긴 하나, 역시 여기서도 private으로 멤버 변수로 정의.
다시 DisplayHardware.cpp에 해상도 관련한 부분을 찾아 보니, property_get() 으로 환경값을 가지고 오는 것을 볼 수 있다.
이 부분은 역시 앞에 설명된 DisplayHardware 클래스의 init 시키는 부분인데, 값을 조회하는 부분이 qemu.sf.lcd_density, ro.sf.lcd_density 이다. 소스상으로는 qemu.sf.lcd_density 값을 조회하고 값이 0이하이면, ro.sf.lcd_density 값을 보도록 되어 있다.
ro.sf.lcd_density 값이 정의되어 있는 부분은 system.prop 파일인데, 이 파일들은 단말제조사 장치별로 되어 있어서 우선은 우리가 확인할 값은 아니다, 게다가 우리는 에뮬레이터를 보는거니, qemu.sf.lcd_density가 정의되어 있는 곳을 찾아야 한다. 2)
결국 찾은 곳은?
결국 찾는 소스는.. hw-lcd.c파일이다.
정리하자면 아래와 같다. (서론이 너무 길다)
external/qemu/android/hw-lcd.c :
에뮬레이터인 qemu내 가상적인(?) LCD H/W 초기설정하는 부분.
hwLcd_setBootProperty()함수를 보면, density 설정시에 define 상수값을 매칭하는 부분을 찾을 수 있다.
external/qemu/android/hw-lcd.h : 에뮬코드인 qemu 상에서 정의된 소스.
여기에 보면..
#define LCD_DENSITY_MIN 120
#define LCD_DENSITY_DEFAULT 160
#define LCD_DENSITY_MAX 240
로 최대 LCD Density를 240으로 fix된것을 볼 수 있다. 아.. 안습!! 이걸 겨우 찾아냈다.
이 부분에서 #define LCD_DENSITY_MAX를 240을 바꾸고자 하는 값으로 바꾸면 된다. (될까? 지금 빌드를 해봐야 해서.)
물론 설정하려는 값이 240DPI이하면 별 의미는 없을꺼다. 그건 어쨌든 되니까..
글수정
2011.05.24
아쉽게도 앞서 설정한 방법으로는 성공하지 못했다. 분명 값을 받아오는 쪽에서 240을 초과하는 값이면 설정된 최대값(아직 내가 바꾸지 못한!!)인 240으로 변경을 하는것 같다. 이 부분은 숙제로 놔두자.
우선 방법으로는.. 맨 처음 참조했던 내용대로 DisplayHardware.cpp에서 dpi설정하고자 하는 값을 대입을 한다.
-------------------------------------------
/* EDIT : Hong, SeongChan */
#if 0
if (property_get("qemu.sf.lcd_density", property, NULL) <= 0) {
if (property_get("ro.sf.lcd_density", property, NULL) <= 0) {
LOGW("ro.sf.lcd_density not defined, using 160 dpi by default.");
strcpy(property, "160");
}
} else {
/* for the emulator case, reset the dpi values too */
mDpiX = mDpiY = atoi(property);
}
mDensity = atoi(property) * (1.0f/160.0f);
#else
mDpiX=mDpiY=320.0f;
mDensity = 320.0f * (1.0f/160.0f);
#endif
-------------------------------------------
이렇게 수정한 후에 SDK를 빌드하고 나서 나온 이미지 디렉토리 (SDK내 platform 디렉토리에 android-2.3.X 과 같이 버전명이 명시된 경로)를 가져다가 원래 작업하고 있는 안드로이드 SDK내 platform 디렉토리에 복사한다.
새로 만든거랑 이전에 있던거랑 구분이 필요할테니, 이미지 디렉토리내에 있는 build.prop 파일을 열어서 다음의 항목필드의 값을 구분할 수 있는 값으로 구분한다.
ro.build.version.release=2.3.4 (Custom)
위에는 검붉은색 부분만 추가했다. (이 부분은 새로 AVD를 만들때에 target 목록에 노출되기 때문에 새로 만든 이미지를 구분하기 편하다.)
이후 AVD를 만들면 되나, 중요한건 Abstarcted LCD Density를 아무리 설정해봐도 하드코딩되어 있어서 무조건 320 DPI로만 된다는 것. (어차피 320DPI전용으로 쓰기 위해서 빌드한 거니!!!!)
주석
1) 누군가는 웃을게 뻔하다. 시작점은 소스를 좀 찾아봤으면 대충 어느 스타일의 이름에서 찾을 수 있을거라는 추측은 했을 수도 있을테니까.. 하지만. 난 예전처럼 폰쪽 소스(사실 그때라고 해봤자. 마찬가지일지도..)를 뒤적거릴 생각을 덜하게 된다. 안드로이드 소스빌드도 마찬가지로 기본 문서를 좀 먼저 봤으면 덜 헤맸을거다.
2) qemu 는 버츄얼 에뮬레이터(?)로 보면 된다.
자세한건 다음백과 사전 참고 (http://enc.daum.net/dic100/contents.do?query1=10XX140977)
보다 자세한 내용은 qemu 사이트를 참고하길. (http://wiki.qemu.org/Main_Page)