2011년 12월 27일 화요일

android ICS 해상도, density에 따른 UI 변화

해상도 중 짧은 쪽이 600pixel 이상 일때 emulator의 화면입니다.




그리고 600pixel 미만일 때 emulator의 화면입니다.



동일한 AVD에서 해상도만 1024 x 600에서 800 x 480으로 변경한 것입니다.

해상도의 짧은 쪽이 600이상 일 때는 tablet의 UI를 보여 주고 600 미만 일 때는 phone의 UI를 보여 줍니다.

그리고 짧은 쪽이 600이상이 되면 자동으로 status bar가 하단에 위치 하고 screen buttons(Navigation Bar로 내부적으로 표현함)이 포함됩니다.

phone의 UI는 기본이 portrait이고 tablet의 UI는 landscape입니다.

600미만인 android에 landscape를 default로 주고 Screen Buttons(Navigation Bar)를 주면 제대로 그려지지 않습니다.

PhoneWindowManager.java를 보면 resolution, dpi를 가지고 판단하는 코드가 있습니다.


 870         // Determine whether the status bar can hide based on the size
 871         // of the screen.  We assume sizes > 600dp are tablets where we
 872         // will use the system bar.
 873         int shortSizeDp = shortSize
 874                 * DisplayMetrics.DENSITY_DEFAULT
 875                 / DisplayMetrics.DENSITY_DEVICE;
 876         mStatusBarCanHide = shortSizeDp < 600;
 877         mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
 878                 mStatusBarCanHide
 879                 ? com.android.internal.R.dimen.status_bar_height
 880                 : com.android.internal.R.dimen.system_bar_height);
 881


결론은 600미만의 device를 만드실 때는 반드시 portrait 타입에 LCD를 사용하시기 바랍니다.

그리고 odroid-7으로 테스트 한 것인데 ro.sf.lcd_density=120으로 주니 tablet UI로 동작은 합니다.





2011년 12월 24일 토요일

ODROID-7 ICS 복구 이미지

ODROID-7 ICS 복구 이미지 배포합니다.

기존 버전에는 kernel framebuffer가 landscape로 되어 있고 android를 270도 회전하여 화면 회전시 또는 멀티태스크 화면에 thumbnail 이미지 회전과 찌부러진 이미지 문제를 해결하였습니다.

터치 및 센서들도 Landscape mode로 수정하였습니다


http://dl.dropbox.com/u/4485660/odroid7_ics.zip





2011년 12월 23일 금요일

android screen button 사용하기

ICS에 Screen button이 가능하도록 수정해 보겠습니다.

frameworks/base/core/res/res/values/config.xml 에 보면 
   



config_showNavigationBar을 true가 되면 아래 보시는 것 처럼 screen button이 나옵니다.

보통 저 파일은 device 밑에 overlay폴더로 관리합니다.

device/hardkernel/odroid7/overlay/frameworks/base/core/res/res/values/config.xml
이 파일을 수정하시면 됩니다.





xda 사이트 참고하였습니다.
http://forum.xda-developers.com/showthread.php?t=1364757


2011년 12월 22일 목요일

android Airplane mode uncheck 안되는 문제...

modem이 없는 android 시스템에서 airplane 모드를 체크하면 다시 uncheck되지 않는 문제가 있습니다.

airplane의 설정이 ril-daemon과 상호 작용하여야 되는지 ril-daemon이 없거나 modem이 없는데 ril-daemon만 동작하면 이런 현상이 있습니다.

그래서 android/package/app/settings/src/com/android/settings/AirplaneModeEnabler.java를 아래와 같이 수정 합니다.


 85     private void setAirplaneModeOn(boolean enabling) {
 86         //codewalker
 87         if (SystemProperties.get("init.svc.ril-daemon").equals("running")) {
 88             mCheckBoxPref.setEnabled(false);
 89             mCheckBoxPref.setSummary(enabling ? R.string.airplane_mode_turning_on
 90                 : R.string.airplane_mode_turning_off);
 91         } else {
 92             mCheckBoxPref.setChecked(true);
 93             mCheckBoxPref.setSummary(null);
 94         }

init.svc.ril-daemon property로 ril-daemon 동작 여부를 확인 할 수 있습니다.

그리고 init.rc에 ril-daemon을 제거 합니다.

#service ril-daemon /system/bin/rild -l /system/lib/libreference-ril.so
#    socket rild stream 660 root radio
#    socket rild-debug stream 660 radio system
#    user root
#    group radio cache inet misc audio sdcard_rw



android screen timeout 무한대로 설정하기

아래 링크를 보면 screen timeout를 무한대로 만드는 방법이 있습니다.

http://www.aesop.or.kr/34931
sqlite3 /data/data/com.android.providers.settings/databases/settings.db "INSERT INTO system (name, value) VALUES ('screen_off_timeout', -1);"


settings app를 수정하여 무한대로 설정 할 수 있도록 수정 해 보겠습니다.


android/pacakge/app/Settings/res/values/arrays.xml을 -1 item을 추가 합니다.



 74 
 75    
 76    
 77         15 seconds
 78         30 seconds
 79         1 minute
 80         2 minutes
 81         10 minutes
 82         30 minutes
 83         off
 84    
 85     
 86    
 87    
 88        
 89         15000
 90        
 91         30000
 92        
 93         60000
 94        
 95         120000
 96        
 97         600000
 98        
 99         1800000
100        
101         -1
102    


그럼 아래와 같이 UI 화면이 구성이 되고 off를 선택 하시면 -1 값이 db에 입력 되어 screen timeout이 안 걸립니다.


2011년 12월 1일 목요일

Unable to create netlink socket: Protocol not supported


D/dalvikvm(   55): GC_EXPLICIT freed 27K, 50% free 1044K/2048K, paused 0ms+0ms
I/Netd    (   91): Netd 1.0 starting
E/Netd    (   91): Unable to create netlink socket: Protocol not supported
E/Netd    (   91): Unable to open quota2 logging socket
E/Netd    (   91): Unable to start DnsProxyListener (Protocol not supported)

E/SocketListener(   53): Obtaining file descriptor socket 'dnsproxyd' failed: Protocol not supported



odroid-7에 ICS Porting중인데 위와 같은 메세지가 나오면서 문제가 되는데 해결 방법을 못 찾고 있다.

kernel에 netlink(netfilter)와 IPv6, quota 관련 feature을 켜도 해결이 안되네요.

system/netd/NetlinkManager.cpp를 보면 socket에서 error를 return하고 error message가 
Protocol not supported 면 kernel configure만 맞춰주면 될 듯한데...

 63     nladdr.nl_groups = groups;
 64 
 65     if ((*sock = socket(PF_NETLINK, SOCK_DGRAM, netlinkFamily)) < 0) {
 66         LOGE("Unable to create netlink socket: %s", strerror(errno));
 67         return NULL;
 68     }

하루 종일 googling해도 답이 없고 XDA 역시 위에 문제만 나와 있고 해결 방법이 없어요...


http://www.groupsrv.com/linux/about152575.html

위에 설명에 의하면
16이 af_netlink이고 커널 메세지를 보면 아래와 같다... 그럼 netlink protocol이 등록된 것 아닌지...

0.606927] NET: Registered protocol family 16

검색하다 아래 페이지를 찾았는데 kernel이 3.0 여야되는 것 처럼 보인다.

http://android.modaco.com/topic/330834-advent-vega-kernel-source-code-now-available/page__st__820

부팅 log도 보면 /proc/net/xt_qtaguid/stats 노드를 찾는다.
xt_qtaguid.c는 3.0 커널에 만 존재하는 파일이다.

F/BatteryStatsImpl(  122): Caused by: java.io.FileNotFoundException: /proc/net/xt_qtaguid/stats: open failed: ENOENT (No such file or directory)

2011년 11월 30일 수요일

android OpenJDK vs Sun JDK build

Ubuntu 11.10 업데이트 후 자동으로 설치되었는지 확인은 되지 않지만 OpenJDK가 설치 되어 있습니다.

android build시 gingerbread까지는 OpenJDK로 build하여도 문제가 없는데 ICS build시 아래와 같은 에러가 발생합니다.


error: error reading out/target/common/obj/JAVA_LIBRARIES/core-tests_intermediates/javalib.jar; invalid header field
1 error
make: *** [out/target/common/obj/APPS/FrameworksCoreSystemPropertiesTests_intermediates/classes-full-debug.jar] 오류 41

googling 하여 보니 OpenJDK로 build는 가능하나 Sun JDK를 사용하기를 권장하는 것 같습니다.

synatic에서 OpenJDK를 삭제하시고 Sun JDK로 설치하시고


[~/projects/ICS]$ sudo update-alternatives --config jar
[sudo] password for codewalker:
대체 항목 jar에 대해 (/usr/bin/jar 제공) 2개 선택이 있습니다.

  선택       경로                           우선순  상태
------------------------------------------------------------
* 0            /usr/bin/fastjar                  100       자동 모드
  1            /usr/bin/fastjar                  100       수동 모드
  2            /usr/lib/jvm/java-6-sun/bin/jar   63        수동 모드

기본 사항[*]을 사용하려면 엔터, 다른 것을 사용하려면 번호를 입력하십시오: 2

jar도 위와 같이 java-6-sun/bin/jar를 선택하십시오.



http://groups.google.com/group/android-building/browse_thread/thread/f82cc424d451e409/91e29dac50ee1970?show_docid=91e29dac50ee1970

아직도 ICS AOSP가 빌드가 되지 않고 있습니다.


Preparing output jar [/home/codewalker/projects/ICS/out/target/common/obj/APPS/WAPPushManager_intermediates/proguard.classes.jar]
  Copying resources from program jar [/home/codewalker/projects/ICS/out/target/common/obj/APPS/WAPPushManager_intermediates/classes.jar]
target Java: FrameworksServicesTests (out/target/common/obj/APPS/FrameworksServicesTests_intermediates/classes)
target Dex: android.core.tests.libcore.package.com.no-core-tests-res
target Dex: android.core.tests.libcore.package.dalvik.no-core-tests-res
target Dex: android.core.tests.libcore.package.libcore.no-core-tests-res
target Dex: android.core.tests.libcore.package.org.no-core-tests-res
target Dex: android.core.tests.libcore.package.sun.no-core-tests-res
target Dex: android.core.tests.libcore.package.tests.no-core-tests-res

이 단계에서 top을 해 보면 java가 몇개 돌고 있고 메모리를 거의 다 사용하고 있어서 시스템이 거의 동작하지 않고 build 역시 안되는 것 같습니다. 여기서 해결이 안되네요. ㅡㅡ;

https://groups.google.com/group/android-building/browse_thread/thread/1d01d0cd635c7f9e

여기 설명대로 -j 옵션을 없애니 컴파일이 계속되네요. 이해가 안가네요.

결과 Ubuntu 11.10 최신 버전을 사용하고 있었는데 OS가 문제가 있어서 다시 설치해야 하서 결국 Google에서 recommend하는 10.04로 재설치 하였습니다.

그런데 package/app들 build하다가 아래 링크의 설명 처럼 에러가 발생합니다.


fix "bad class file error" android build error



http://rxwen.blogspot.com/2011/08/fix-bad-class-file-error-android-build.html

eclipse를 설치하고 나면 jar가 fastjar로 바뀝니다.
그래서 결국 android ICS build 하려면 jar를 다시 설정해 주셔야 합니다.

2011년 11월 29일 화요일

2011년 11월 28일 월요일

ubuntu 11.10에서 android(Gingerbread) build error...


ubuntu 11.10으로 업데이트 후 gcc 버전을 확인 해 보면 아래와 같습니다.


[~/projects/ICS/device/samsung]$ gcc --version
gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

그래서 android build 시 두가지 에러가 발생합니다.


In file included from external/oprofile/libpp/arrange_profiles.cpp:24:0:
external/oprofile/libpp/format_output.h:94:22: error: reference ‘counts’ cannot be declared ‘mutable’ [-fpermissive]
make: *** [out/host/linux-x86/obj/STATIC_LIBRARIES/liboprofile_pp_intermediates/arrange_profiles.o] 오류 1
make: *** 끝나지 않은 작업을 기다리고 있습니다....
make: *** [out/host/linux-x86/obj/STATIC_LIBRARIES/liboprofile_pp_intermediates/format_output.o] 오류 1
true


frameworks/base/libs/utils/Android.mk
LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1 $(TOOL_CFLAGS)
LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1 $(TOOL_CFLAGS) -fpermissive





error: "_FORTIFY_SOURCE" redefined [-Werror]



build/core/combo/HOST_linux-x86.mk line 61:

-HOST_GLOBAL_CFLAGS += -D_FORTIFY_SOURCE=0

+HOST_GLOBAL_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0

2011년 11월 24일 목요일

android에서 USB Mass Storage 사용하기

ODROID-7/A에 USB Host가 있습니다.

거기에 USB 저장장치를 연결하여 자동으로 mnt/sdcard/external_storage란 폴더에 자동으로 마운트가 되도록 수정해 보려고 합니다.

ODROID-A에는 두개의 mmc가 있어서 galaxy s처럼 추가 외부 저장장치를 지원합니다.

vold와 MountService.java를 수정하였습니다.

vold.fstab에 bus node를 등록하면 UMS까지 지원하려고 했지만 usb mass 장치를 붙일때 마다 bus node의 인덱싱이 host1, host2 처럼 증가합니다.

vold의 구조가 동적 증가하는 장치를 지원하지 않는 구조 입니다.

fstab에 등록되어 있는 노드 객체를 만들고 등록된 Volume이 NetlinkEvent의 DEVPATH와 동일하면 처리합니다. 따라서 USB Host에 연결하는 장치와 같이 bus 이름이 증가하는 구조에는 적용이 안됩니다.

그리서 vold에서 강제로 mount 하도록 해 봤습니다.

kernel에 USB Mass Storage support를 추가 한다.

     <*>   USB Mass Storage support   



그리고 system/vold/VolumeManager.cpp에 handleBlockEvent() 함수를 다음과 같이 수정합니다.


bool usb_storage_mounted = false;
bool second_netlinkevent = false;


void VolumeManager::handleBlockEvent(NetlinkEvent *evt) {
    const char *devpath = evt->findParam("DEVPATH");

    /* Lookup a volume to handle this device */
    VolumeCollection::iterator it;
    bool hit = false;
    for (it = mVolumes->begin(); it != mVolumes->end(); ++it) {
        if (!(*it)->handleBlockEvent(evt)) {
#ifdef NETLINK_DEBUG
            SLOGD("Device '%s' event handled by volume %s\n", devpath, (*it)->getLabel());
#endif
            hit = true;
            break;
        }
    }

    if (!hit) {
#ifdef NETLINK_DEBUG
        SLOGW("No volumes handled block event for '%s'", devpath);
#endif


        if (second_netlinkevent) {
            second_netlinkevent = false;
            return;
        }

        char *usb_mass_node = "/devices/platform/s5p-ehci/usb";
        if (usb_storage_mounted) {
            umount("/mnt/sdcard/external_storage");
            usb_storage_mounted = false;
            SLOGE("unmounted USB Mass Storage");
        } else {
            int len = strlen(usb_mass_node);
            if (strncmp(devpath, usb_mass_node, len) == 0) {
                usleep(5000);
                if (Fat::doMount("/dev/block/sda1", "/mnt/sdcard/external_storage", false, false, false,
                 1000, 1015, 0702, true)) {
                    SLOGE("%s failed to mount via VFAT (%s)\n", devpath, strerror(errno));
                } else {
                    SLOGE("mounted USB Mass Storage");
                    usb_storage_mounted = true;
                }
            } else {
                SLOGE("not USB Mass Storage");
            }
        }

        second_netlinkevent = true;
    }

코드를 조금 설명 드리면 USB Mass는 event가 두번 발생하여 second_netlinkevent를 통해 한번만 처리되도록 하였습니다.

usleep은 event가 발생시점에는 node가 없을 수 있기 때문에 대기 하였다 mount 시킵니다.

devpath가 "/devices/platform/s5p-ehci/usb" 까지 동일하고 usb1,2,3... 이렇게 증가 하기 때문에 여기까지 같다면 usb mass storage 장치가 연결된 걸로 처리 합니다.

물론 init.rc에 external_storage 노드를 처리하여야 합니다.

 40 # create mountpoints
 41     mkdir /mnt 0775 root system
 42     mkdir /mnt/sdcard 0000 system system
 43     mkdir /mnt/sdcard/external_storage 0000 system system
 44 
 45 # Create cgroup mount point for cpu accounting
 46     mkdir /acct
 47     mount cgroup none /acct cpuacct
 48     mkdir /acct/uid
 49 
 50 # Backwards Compat - XXX: Going away in G*
 51     symlink /mnt/sdcard /sdcard
 52     symlink /mnt/sdcard/external_storage /sdcard1

그리고 vold에서 external_storage를 만드는 코드를 추가 합니다.

int CommandListener::VolumeCmd::runCommand(SocketClient *cli,
                                                      int argc, char **argv) {
    dumpArgs(argc, argv, -1);

    if (argc < 2) {
        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
        return 0;
    }

    VolumeManager *vm = VolumeManager::Instance();
    int rc = 0;

    if (!strcmp(argv[1], "list")) {
        return vm->listVolumes(cli);
    } else if (!strcmp(argv[1], "debug")) {
        if (argc != 3 || (argc == 3 && (strcmp(argv[2], "off") && strcmp(argv[2], "on")))) {
            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume debug ", false);
            return 0;
        }
        vm->setDebug(!strcmp(argv[2], "on") ? true : false);
    } else if (!strcmp(argv[1], "mount")) {
        if (argc != 3) {
            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume mount ", false);
            return 0;
        }
        rc = vm->mountVolume(argv[2]);
        //codewalker
        mkdir("/mnt/sdcard/external_storage", 0777);
    } else if (!strcmp(argv[1], "unmount")) {
        if (argc < 3 || argc > 4 || (argc == 4 && strcmp(argv[3], "force"))) {
            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume unmount [force]", false);
            return 0;
        }

        bool force = false;
        if (argc >= 4 && !strcmp(argv[3], "force")) {



이렇게 하면 Media Scan이 안되는 문제와 UMS가 안되는 문제가 있습니다.
Astro FileManager 같은데서 직접 폴더를 열어서 사용하는 상황에 맞겠죠.

그리고 여럿 예외 처리가 필요할 걸로 판단됩니다.

2011년 11월 23일 수요일

ODROID-7에 android ICS(4.0.3_r1, IML74K) 올리기



odroid7 kernel을 준비 한다.


http://com.odroid.com/sigong/nf_file_board/nfile_board_view.php?keyword=&bid=41

아래 경로에서 kernel 소스를 다운 받는다.

https://github.com/Kwiboo/kernel_samsung_crespo/tree/master/drivers/gpu

drivers/gpu 폴더을 odroid7 kernel에 덮어쓴다.

git로 부터 최신 android 소스를 받는다.


repo init -u https://android.googlesource.com/platform/manifest -b android-4.0.1_r1.2


repo sync





아래 링크에서 odroid7으로 빌드가 가능한도록 수정한 폴더들을 받아 device와 vendor를 덮어쓴다.


http://dl.dropbox.com/u/4485660/ICS.tar.gz




vendor의 파일들은 아래 링크에서 받은 Nexus S의 ICS ROM에서 얻은 것 들이다.


http://www.multiupload.com/F0F156G363

crespo project를 지운다.

rm -rf device/samsung/crespo*

chmod u+x device/hardkerenl/odroid7/build_android.sh


안드로이드를 빌드한다.


device/hardkerenl/odroid7/build_android.sh


build가 완료되면 odroid-7 처럼 f-flash에 복사하고 zImage와 ramdisk-uboot.img를 fastboot로 write한다.














아래 소스를 고치면 마우스 없이 touch까지 가능합니다.

kernel/drivers/input/touchscreen/odroid7_MT_touch_portrait.c


169                 input_sync(hkc1xx_touch.driver);
170 
171 //codewalker
172                 input_mt_sync(hkc1xx_touch.driver);
173 
174                 input_sync(hkc1xx_touch.driver);
175 176 177 #if defined(DEBUG_HKC1XX_TOUCH_MSG) 178 printk("%s : Penup event send[x = %d, y = %d]\n", __FUNCTION__, hkc1xx_touch.x, hkc1xx_touch.y); 179 #endif




소리가 나오게 하는 방법은 ICS ROM에서 두 파일을 odroid7으로 이름을 바꿔서 넣어 주시면 됩니다.


/system/lib/hw/audio.primary.herring.so 를 audio.primary.odroid7.so
/system/lib/hw/audio_policy.herring.so 를 audio_policy.odroid7.so














wifi 가능 하도록 수정 방법



device/hardkernel/odroid7/BoardConfigCommon.mk


71 #WIFI_DRIVER_MODULE_ARG := "firmware_path=/vendor/firmware/fw_bcm4329.bin nvram_path=/vendor/firmware/nvram_net.txt iface_name=wlan" 72 WIFI_DRIVER_MODULE_ARG := "iface_name=wlan firmware_path=/vendor/firmware/fw_bcm4329.bin nvram_path=/vendor/firmware/nvram"

WIFI_DRIVER_MODULE_ARG를 수정하고 odroid7dml fw_bcm4329.bin, nvram을 해당 위치에 복사합니다.




hardware/libhardware_legacy/wifi/wifi.c


102 103 #define WIFI_WAKEUP_CTL_FP "/sys/devices/platform/hkc1xx-sysfs/wifi_wakeup" // 1 -> wakeup on 104 #define WIFI_REG_CTL_FP "/sys/devices/platform/hkc1xx-sysfs/wifi_reg" // 1 -> reg on 105 #define WIFI_RESET_CTL_FP "/sys/devices/platform/hkc1xx-sysfs/wifi_reset" // 1 -> reset on 106 107 int wifi_set_module_status (char *ctl_fp, unsigned char status); 108 int wifi_get_module_status (char *ctl_fp); 109 110 111 static int insmod(const char *filename, const char *args) 112 {





206 int wifi_load_driver() 207 { 208 #ifdef WIFI_DRIVER_MODULE_PATH 209 char driver_status[PROPERTY_VALUE_MAX]; 210 int count = 100; /* wait at most 20 seconds for completion */ 211 212 if (is_wifi_driver_loaded()) { 213 return 0; 214 } 215 216 // Wifi power control & wakeup enable 217 wifi_set_module_status(WIFI_WAKEUP_CTL_FP, 1); usleep(10000); 218 wifi_set_module_status(WIFI_REG_CTL_FP, 1); usleep(10000); 219 wifi_set_module_status(WIFI_RESET_CTL_FP, 1); sleep(1); sync(); 220 221 222 if (insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0) { 223 LOGE("insmod(DRIVER_MODULE_PATH = %s, DRIVER_MODULE_ARG = %s) FAIL!!!", DRIVER_MODULE_PATH, DRIVER_MODULE_ARG); 224 wifi_set_module_status(WIFI_WAKEUP_CTL_FP, 0); usleep(10000); 225 wifi_set_module_status(WIFI_REG_CTL_FP, 0); usleep(10000); 226 wifi_set_module_status(WIFI_RESET_CTL_FP, 0); sleep(1); sync(); 227 return -1; 228 } 229 230 if (strcmp(FIRMWARE_LOADER,"") == 0) {




259 int wifi_unload_driver() 260 { 261 usleep(200000); /* allow to finish interface down */ 262 #ifdef WIFI_DRIVER_MODULE_PATH 263 if (rmmod(DRIVER_MODULE_NAME) == 0) { 264 int count = 20; /* wait at most 10 seconds for completion */ 265 while (count-- > 0) { 266 if (!is_wifi_driver_loaded()) 267 break; 268 usleep(500000); 269 } 270 271 wifi_set_module_status(WIFI_WAKEUP_CTL_FP, 0); usleep(10000); 272 wifi_set_module_status(WIFI_REG_CTL_FP, 0); usleep(10000); 273 wifi_set_module_status(WIFI_RESET_CTL_FP, 0); sleep(1); sync(); 274 275 276 usleep(500000); /* allow card removal */ 277 if (count) { 278 return 0;


int wifi_set_module_status(char *ctl_fp, unsigned char status) { int fd, ret, nwr; char buf[10]; if((fd = open(ctl_fp, O_RDWR)) < 0) { LOGE("%s(%s) : Cannot access \"%s\"", __FILE__, __FUNCTION__, ctl_fp); return -1; // fd open fail } memset((void *)buf, 0x00, sizeof(buf)); if(status) nwr = sprintf(buf, "%d\n", 1); else nwr = sprintf(buf, "%d\n", 0); ret = write(fd, buf, nwr); close(fd); if(ret == nwr) { LOGI("%s : write success (on = %d)", ctl_fp, status); return 0; } else { LOGE("%s : write fail (on = %d)", ctl_fp, status); return -1; } } //---------------------------------------------------------------------------------------------------------------- int wifi_get_module_status(char *ctl_fp) { int fd, ret, nrd; char buf[10]; if((fd = open(ctl_fp, O_RDONLY)) < 0) { LOGE("%s(%s) : Cannot access \"%s\"", __FILE__, __FUNCTION__, ctl_fp); return -1; // fd open fail } memset((void *)buf, 0x00, sizeof(buf)); nrd = read(fd, buf, sizeof(buf)); close(fd); // read ok if(nrd) { if(!strncmp(buf, "1", 1)) { LOGI("%s : status == 1", ctl_fp); return 1; // wakeup } else { LOGI("%s : status == 0", ctl_fp); return 0; // suspend } } LOGI("%s(%s) : module status == unknown", __FILE__, __FUNCTION__); return -1; } //---------------------------------------------------------------------------------------------------------------- int wifi_module_wakeup_status() { int fd, ret, nrd; char buf[10]; if((fd = open(WIFI_WAKEUP_CTL_FP, O_RDONLY)) < 0) { LOGE("%s(%s) : Cannot access \"%s\"", __FILE__, __FUNCTION__, WIFI_WAKEUP_CTL_FP); return -1; // fd open fail } memset((void *)buf, 0x00, sizeof(buf)); nrd = read(fd, buf, sizeof(buf)); close(fd); // read ok if(nrd) { if(!strncmp(buf, "1", 1)) { LOGI("%s(%s) : module status == wakeup", __FILE__, __FUNCTION__); return 1; // wakeup } else { LOGI("%s(%s) : module status == suspend", __FILE__, __FUNCTION__); return 0; // suspend } } LOGI("%s(%s) : module status == unknown", __FILE__, __FUNCTION__); return -1; } //---------------------------------------------------------------------------------------------------------------- int wifi_module_wait_time(int waitTime) { LOGI("%s(%s) : module wait time = %d sec", __FILE__, __FUNCTION__, waitTime); sleep(waitTime); sync(); return 0; }



위와 같이 수정 하고 libhardware_legacy.so를 넣습니다.

bcm4329.ko는 kernel에서 make modules로 만들어 넣습니다.










market 사용




gapps는 아래 파일에서 받았습니다.

위에 system을 adb push로 밀어 넣으면 몇개 중복되는 apk가 존재하여 문제가 발생합니다.

그래서 중복되는 apk를 삭제하여 묶었습니다.

http://dl.dropbox.com/u/4485660/gapps-ics-20111122-full-blade_codewalker.tar.gz



android-4.0.3_r1(IML74k) 올려 봤습니다.


gps

odroid-7 gingerbread의 gps library를 드대로 사용하니 gps도 동작하네요.
int.rc에 gps 노드만 바꾸면 됩니다.

 29     chown gps root /sys/class/sec/gps/GPS_PWR_EN/value
 30     chmod 660 /sys/class/sec/gps/GPS_PWR_EN/value
 31                                                   
 32     #===================================================================
 33     #                                         
 34     # Odroid GPS Device name Setting                         
 35     #                                                       
 36     #===================================================================
 37     setprop ro.kernel.android.gps s3c2410_serial1            
 38     chmod 0666  /dev/s3c2410_serial1
 39                    
 40            
 41 on fs                
 42     mkdir /efs 0775 radio radio




가속 센서 역시 odroid7의 orientationd, geomagneticd, sensors.odroid7.so를 그대로 사용하니 동작 합니다.

지자기 센서는 역시 동작하지 않네요.









앞에서 추가적으로 수정된 내용은 ICS.tar.gz에 계속 반영 됩니다.

2011년 11월 21일 월요일

ZigBee VS. BLE(Bluetooth 4.0)

2011/11/18에 COEX에서 하는 RFID/USN Korea 2011을 참관하였습니다.

RFID는 들어 봤지만 USN은 뭔지도 모르고 갔는데 ubiquitous sensor network 이더군요.


RFID야 매우 오래된 분야이고 물류쪽에 적용하여 많이 활성화된 기술입니다.




아래 사진은 RFID를 통해서 물류쪽에 적용할 수 있는지 시물레이션하는 모형인데 모형이 참 인상적이 었습니다. 




모형 제작에 상당한 시간과 돈이 들었을 것 같은데 마치 박물관이나 전시회에서나 볼 정도의 완성도였습니다.


이제는 Nexus S, Galaxy S2에 NFC가 기본 탑재되어 있어서 산업/물류 뿐만 아니라 실생활에 어떻게 활용 될지에 대한 내용이 흥미로 왔습니다.


쿠폰을 문자로 받고 화면에 바코드나 번호를 보여 주는 방식에서 NFC를 통해 쿠폰을 받고 결재하는 방식으로 NFC를 이용함으로써 직관적이라는 느낌이 들었습니다. 


CGV에서 쿠폰 및 결재를 NFC가 있는 핸드폰에서 곧 서비스 계획에 있으며 데모를 시현하고 있었습니다.


그리고 기존에 NFC가 없는 핸드폰이나 특수 사용을 목적으로 NFC 외부 모듈 형식에 제품도 많이 보였습니다.




주류 마개에 RFID tag를 넣고 RFID 리더기로 읽고 Bluetooth과 연결된 핸드폰으로 tag 값을 전달 후 인터넷을 통해 진품확인하는 시스템입니다.


그리고 저의 관심 분야인 USN입니다.


아래 사진은 휴인스에서 USN 개발킷입니다.
http://www.huins.com/m16.php?m=rd&no=77#bimg




안드로이드 단말기에서 현관문도 열 수 있고 전구도 on/off가 가능합니다.


여기에 사용된 방식이 ZigBee입니다.


BLE(Bluetooth 4.0)과 ZigBee 어느 쪽이 USN에서 승자가 될까요?


둘다 저전력을 목표로 제작된 것입니다.


하지만 iPhone 4S에 BLE가 적용된 칩이 들어갔고 차후 안드로이드 역시 BLE가 적용된 Wi-Fi/Bluetooth 가 적용된 칩이 적용되겠죠.
broadcom의 bcm4330이 나와 있습니다.


BLE가 전망이 더 밝은 이유가 안드로이 Open Accessory Development Kit에서 채용되지 않을까 예상해 봅니다.


현재 adk는 USB 통신인데 이로 인해 말이 안되는 accessory가 되었죠. 
Google에서 다음 버전은 Bluetooth 무선 accessory가 될것이라 했기 때문에 BLE가 ZigBee 보다는 더 전망이 밝다고 보입니다.



2011년 11월 18일 금요일

foursquare를 이용한 Googl Calendar 관리

Google Calendar를 이용하여 일정관리를 많이 하실겁니다.

스마트폰으로 calendar 어플을 띄워서 시간 장소를 입력하기가 막상 귀찮아서 몇번 하다가 말죠.

foursquare를 이용하여 google calendar에 일정관리 하는 간단한 방법이 있습니다.

일단 스마트폰에서 foursquare를 이용하여 check-ins을 하시고

자신의 foursquare 계정에서 아래의 주소를 들어가시게 되면 URL 주소를 확인 하실 수 있습니다.

https://ko.foursquare.com/feeds/

그리고 Google Calendar에서 다른 캘린더 -> URL 추가에 위에서 ics 링크를 넣어주면 foursquare에서 check-in한 장소들이 Google Calendar에 추가됩니다.

2011년 11월 13일 일요일

android LockScreen 사용 안 하기

android는 Lock Screen을 풀어야 사용할 수 있는 컨셉입니다.

당연히 handheld 제품이라면 필요한 UI입니다.

제가 작업하는 android에는 필요없는 UI 컨셉인 관계로 부팅 후 바로 Home Screen이 나오도록  수정하여 보겠습니다.

framework/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java 에서


public int finishAnimationLw() {
    int changes = 0;

finishAnimationLw() 함수가 있습니다.

        // Hide the key guard if a visible window explicitly specifies that it wants to be displayed
        // when the screen is locked
        if (mKeyguard != null) {
            if (localLOGV) Log.v(TAG, "finishLayoutLw::mHideKeyguard="+mHideLockScreen);
                /*
                if (mDismissKeyguard && !mKeyguardMediator.isSecure()) {
                    if (mKeyguard.hideLw(true)) {
                        changes |= FINISH_LAYOUT_REDO_LAYOUT
                                | FINISH_LAYOUT_REDO_CONFIG
                                | FINISH_LAYOUT_REDO_WALLPAPER;
                    }    
                    if (mKeyguardMediator.isShowing()) {
                        mHandler.post(new Runnable() {
                            public void run() {
                                mKeyguardMediator.keyguardDone(false, false);
                            }    
                        });  
                    }    
                } else if (mHideLockScreen) {
                */
                    if (mKeyguard.hideLw(true)) {
                        changes |= FINISH_LAYOUT_REDO_LAYOUT
                                | FINISH_LAYOUT_REDO_CONFIG
                                | FINISH_LAYOUT_REDO_WALLPAPER;
                    }    
                    mKeyguardMediator.setHidden(true);
                /*
                } else {
                    if (mKeyguard.showLw(true)) {
                        changes |= FINISH_LAYOUT_REDO_LAYOUT
                                | FINISH_LAYOUT_REDO_CONFIG
                                | FINISH_LAYOUT_REDO_WALLPAPER;
                    }    
                    mKeyguardMediator.setHidden(false);
                } 
                */

위과 같이 처리하면 부팅 후 바로 Home Screen이 나옵니다.


------------------------------------------------------------------------------------------------------------------------------------------------------------


이 글을 작성 후 USB keyboard를 연결 하고 Home key가 동작하지 않는 버그를 발견했다.


W/KeyguardViewMediator( 2181): verifyUnlock called when not externally disabled

이와 같은 메세지를 출력하는데 이유는 아직 Lock Screen이 있는 상태로 인식 되기 때문인 것 같습니다,

그래서 위에서 제시한 코드를 rollback하고 다른 방법을 찾아 보았습니다.

의외로 간단하게 해결되었습니다.

framework/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java


    /** {@inheritDoc} */
    public void beginAnimationLw(int displayWidth, int displayHeight) {
        mTopFullscreenOpaqueWindowState = null;
        mForceStatusBar = false;
        mHideLockScreen = true;
        //mHideLockScreen = false;
        mAllowLockscreenWhenOn = false;
        mDismissKeyguard = false;
    }   

mHideLockScreen을 true로 만들면 LockScreen도 안 보이고 Keyboard의 Home키가 동작하지 않는 두가지 문제가 동시에 해결됩니다.




2011년 11월 10일 목요일

touch screen이 없는 android에서 app이 죽는 상황

touch screen이 없는 android에서는 Music, Contacts, Phone app이 동작하지 않습니다.

이전 froyo에서는 android 자체가 켜지지 않았지만 gingerbread 부터는 android는 정상 부팅하도록 변경되었습니다.

아래의 메세지와 같이 resource index가 맞지 않아서 죽습니다.

android.content.res.Resources$NotFoundException: Resource contacts

googling 하다가 아래 페이지를 찾았고

https://bugs.launchpad.net/linaro-android/+bug/772528

git log를 보면 fake-ts에 관한 내용이 있습니다.

http://git.linaro.org/gitweb?p=android/device/linaro/common.git;a=commit;h=89a3940ca2ad04a54e4a8aa315f0089ce4621d17

[LINARO] Add fake touchscreen 'driver' to avoid Android activity crash

Some Android activities like 'Music' expect the presence of touchscreen
device, otherwise they would crash due to lacking of corresponding
system resources.

To fix the crash, a fake touchscreen 'driver' is added, which utilizes
uinput to register a touchscreen device in kernel.


touch screen이 없더라도 kernel 드라이버에 fake또는 dummy touch screen driver가 반드시 있어야 합니다.

정확하게는 상황이 이해가 가지 않지만 Music app에서 touch screen을 resource로 관리하고 ts가 없기 때문에 resource index가 문제가 되는 것 처럼 보입니다.

2011년 11월 1일 화요일

android open GL ES 2.0 sample

단말기에서 Open GL ES 2.0이 동작하는 확인 할 수 있는 app

http://code.google.com/p/gdc2011-android-opengl/


svn checkout http://gdc2011-android-opengl.googlecode.com/svn/trunk/ gdc2011-android-opengl-read-only


동작하면 open GL ES 2.0 compatibility 하다고 할 수 있겠죠.


ODROID-A에서 동작하는 모습