2012년 3월 27일 화요일

ODROID(ICS) screenshot 찍기

android Honeycomb부터 iOS 처럼 screenshot이 가능합니다.

Volume Down + Power Key 조합입니다.

하지만 ODROID는 Volume Up/Down키와 Power Key가 동시에 눌러지지 않는 형태입니다.



Screenshot으로 검색해 보면 PhoneWindowManager.java에 관련 코드가 찾아 집니다.

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


public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn) {
...


    switch (keyCode) {
            case KeyEvent.KEYCODE_VOLUME_DOWN:
            case KeyEvent.KEYCODE_VOLUME_UP:
            case KeyEvent.KEYCODE_VOLUME_MUTE: {
                if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
                    if (down) {
                        if (isScreenOn && !mVolumeDownKeyTriggered
                                && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
                            mVolumeDownKeyTriggered = true;
                            mVolumeDownKeyTime = event.getDownTime();
                            mVolumeDownKeyConsumedByScreenshotChord = false;
                            cancelPendingPowerKeyAction();
                            interceptScreenshotChord();
                        }
                    } else {

여기서 KEYCODE_VOLUME_DOWN -> KEYCODE_SEARCH으로 바꿉니다.



    switch (keyCode) {
            case KeyEvent.KEYCODE_SEARCH:
            case KeyEvent.KEYCODE_VOLUME_UP:
            case KeyEvent.KEYCODE_VOLUME_MUTE: {
                if (keyCode == KeyEvent.KEYCODE_SEARCH) {
                    if (down) {
                        if (isScreenOn && !mVolumeDownKeyTriggered
                                && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
                            mVolumeDownKeyTriggered = true;
                            mVolumeDownKeyTime = event.getDownTime();
                            mVolumeDownKeyConsumedByScreenshotChord = false;
                            cancelPendingPowerKeyAction();
                            interceptScreenshotChord();
                        }
                    } else {

그럼 Power Key와 Search Key를 동시에 1초 누르면 screenshot이 찍힙니다.





2012년 3월 26일 월요일

Android Build되지 않거나 killed될 때...


gingerbread까지는 android build시 종료되거나 build가 끝나지 않는 문제가 없었는데 ICS부터는 아래와 같이 killed되거나 끝나지 않는 문제가 발생합니다.

make: *** [out/target/common/obj/APPS/android.core.tests.libcore.package.com.no-core-tests-res_intermediates/noproguard.classes-with-local.dex] Killed

그래서 googling해보니 swap이 문제인것 같습니다.

Ubuntu 설치 시 partition을 자동으로 지정하면 swap이 1G로 잡히는 것 같습니다.
그런데 android build하기 위해서는 swap이 더 켜저야 하는 것 같습니다.

아래와 같이 하여 4G로 swap을 잡으니 문제가 없습니다. 참고하세요.


$sudo dd if=/dev/zero of=/boot/swapfile bs=1024 count=4194304

$sudo mkswap -v1 /boot/swapfile  

$sudo swapon /boot/swapfile 

$free
             total       used       free     shared    buffers     cached
Mem:       4041052    3717680     323372          0     724304    1923656
-/+ buffers/cache:    1069720    2971332
Swap:      4194296          0    4194296

4G swap을 확인

$sudo vi /etc/fstab

아래 줄 추가
/boot/swapfile swap swap defaults 1 1

2012년 3월 6일 화요일

android(ICS,JB)에서 Lock Screen 설정 None으로 만들기

JB에서부터는 아래 코드를 적용해서 default가 none으로 설정되지 않습니다.

def_lockscreen_disabled 값을 true로 주시면 코드 수정없이 됩니다.

overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml


<?xml version="1.0" encoding="utf-8"?>
<!--
/**
 * Copyright (c) 2009, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-->
<resources>
    <bool name="def_accelerometer_rotation">false</bool>
    <bool name="def_lockscreen_disabled">true</bool>
    <integer name="def_screen_off_timeout">604800000</integer>
    <bool name="def_install_non_market_apps">true</bool>
</resources>

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


http://codewalkerster.blogspot.com/2011/11/android-lockscreen.html

gingerbread에서는 Screen lock을 PhoneWindowManager.java를 직접 수정하여 없앨 수 있었습니다.

ICS 부터는 아래와 같이 Screen lock - None이란 항목이 있습니다.



그런데 첫 부팅 후 default가 None으로 설정하려고 합니다.

framework/base/core/java/com/android/internal/widget/LockPatternUtils.java

    public boolean isLockScreenDisabled() {
        return !isSecure() && getLong(DISABLE_LOCKSCREEN_KEY, 1) != 0;
        //return !isSecure() && getLong(DISABLE_LOCKSCREEN_KEY, 0) != 0;
    }


    public int getKeyguardStoredPasswordQuality() {
        int quality =
                (int) getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
                //(int) getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
        // If the user has chosen to use weak biometric sensor, then return the backup locking
        // method and treat biometric as a special case.
        if (quality == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK) {
            quality =
                (int) getLong(PASSWORD_TYPE_ALTERNATE_KEY,
                        DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
        }    
        return quality;
    }



2012년 2월 13일 월요일

android tablet ICS에서 Mass Storage UI가 나오지 않는 문제 해결

android tablet의 최초 OS는 Honeycomb이 였습니다.
Honeycomb은 MTP가 default입니다.
그래서 이전에 Mass Storage로 변경해도 USB Mass Storage connection Notification이 오지 않습니다.

그래서 Tablet인 경우 Mass Storage로 변경 시 PC와 연결하는 UMS를 사용할 수 없는 문제가 발생합니다.

원인을 찾아 보니 phone UI만 com.android.systemui.usb.StorageNotification에 대한 listener가 등록되어 있어서 tablet UI에서는 event를 받지 못하는 상황이 였습니다.

framework/base/packages/SystemUI/src/com/android/systemui/statusbar 폴더를 보시면
phone, tablet이란 폴더가 있습니다.

여기서 grep -nr mStorageManager를 검색하여 보시면 PhoneStatusBarPolicy class에서만 listener를 등록해 주도록 되어 있습니다.

tablet에서 적절한 위치에 mStorageManager.registerListener()를 추가해 주셔야 합니다.

아래 capture를 보시면 ui가 설렁합니다.
tablet UI에서 Mass Storage 연결에 대해 고민하지 않는 듯한 인상입니다.


2012년 2월 9일 목요일

android MTP <-> Mass Storage

android ICS부터 MTP를 지원합니다.
Gingerbread의 Mass Storage 방식으로 수정해 보겠습니다.


overlay/frameworks/base/core/res/xml/storage_list.xml 입니다.


<StorageList xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- removable is not set in nosdcard product -->
    <storage android:mountPoint="/mnt/sdcard"
        android:storageDescription="@string/storage_usb"
        android:primary="true"
        android:emulated="true"
        android:mtpReserve="100" />
</StorageList>

아래와 같이 바꿉니다.



<StorageList xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- removable is not set in nosdcard product -->
    <storage android:mountPoint="/mnt/sdcard"
        android:storageDescription="@string/storage_internal"
        android:primary="true"
        android:emulated="false"
        android:allowMassStorage="true" />
</StorageList>

init.[PRODUCT_NAME].rc

fuse 관련된 부분 삭제 합니다.


on post-fs-data
    # we will remap this as /mnt/sdcard with the sdcard fuse tool
    mkdir /data/media 0775 media_rw media_rw
    chown media_rw media_rw /data/media


on fs
    mount ext4 ...
    mount ext4 ...
    mount ext4 ...
    setprop ro.crypto.fuse_sdcard true

#/sdcard

    export EXTERNAL_STORAGE /mnt/sdcard
    mkdir /mnt/sdcard 0000 system system
    symlink /mnt/sdcard /sdcard



# create virtual SD card at /mnt/sdcard, based on the /data/media directory
# daemon will drop to user/group system/media_rw after initializing
# underlying files in /data/media will be created with user and group media_rw (1023)
service sdcard /system/bin/sdcard /data/media 1023 1023
    class late_start

init.[PRODUCT_NAME].usb.rc


on property:sys.usb.config=mtp
    write /sys/class/android_usb/android0/enable 0
    ...
    ...
    setprop sys.usb.state $sys.usb.config

on property:sys.usb.config=mtp,adb
    ...
    ...
    start adbd

mtp를 mass_storage로 바꿉니다.

그리고 vold.fstab을 만듭니다.


## Vold 2.0 Generic fstab
## - San Mehat (san@android.com)
##

#######################
## Regular device mount
##
## Format: dev_mount <label> <mount_point> <part> <sysfs_path1...>
## label        - Label for the volume
## mount_point  - Where the volume will be mounted
## part         - Partition # (1 based), or 'auto' for first usable partition.
## <sysfs_path> - List of sysfs paths to source devices, must start with '/' character
## flags        - (optional) Comma separated list of flags, must not contain '/' character
######################


dev_mount sdcard /mnt/sdcard auto [vfat mount 할 node] nonremovable,encryptable

그리고 BoardCongig.mk 또는 device.mk에 vold.fstab를 복사하는 문장 추가합니다.

PRODUCT_COPY_FILES += \
device/hardkernel/odroida4/vold.fstab:system/etc/vold.fstab \
        ...

persist.sys.usb.config=mtp를 mass_storage로 변경...


# Set default USB interface
PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
    persist.sys.usb.config=mass_storage


이렇게 수정하면 ICS에서도 Gingerbread의 화면을 보실 수 있습니다.








http://source.android.com/devices/tech/storage/config-example.html

2012년 2월 5일 일요일

android와 MTP 그리고 Ubuntu

android Honeycomb부터 USB Mass Storage 방식에서 MTP(PTP)로 PC와 연결 방식이 바뀌었습니다.


android는 Froyo에서는 External Storage를 지원 하였습니다.
Nexus One의 경우 t-flash slot이 존재 합니다.



따라서 system partition은 /system와 /data /cache로 이루어져 있고 /mnt/sdcard란 폴더에 external storage를 mount하는 방식이 였습니다.

그래서 아래와 같이 sdcard를 android에서 umount후 PC로 mount하는 방식이였습니다.




Gingerbread(Nexus S)부터는 external storage를 지원하지 않고 iPhone 처럼 내부 nand에 system와 user data를 하나의 nand에 partition을 나누는 방식으로 바뀌었습니다.

/data partition이 고정 크기이고 작기 때문에 여러 문제점이 발생합니다.
/data를 크게 주면 한정된 nand에서 user data 영역이 줄어들기 때문에 제조사에서는 무조건 /data를 크게 잡지 못합니다.

Nexus One과 Motoroi의 경우 /data가 200Mbyte도 안되기 때문에 기본 설치된 app을 포함하면 사용자가 설치할 수 있는 공간의 더 작아 집니다.

그래서 app을 설치하고 /sdcard로 옮기기가 Gingerbread부터 지원하지만 보안 문제와 app 전체를 /sdcard로 설치하는 것이 아니라 일부 데이터만 /sdcard로 옮기기 때문에 이 역시 해결책이 아니였습니다.

그래서 Honeycomb부터 /sdcard를 /data 영역의 한 폴더로 지정하고 /data와 /sdcard를 통합하였습니다.

그런데 이렇게 하니 다른 문제가 발생합니다.

android는 linux 시스템이기 때문에 /data partition이 ext4란 linux에서 지원하는 file system을 사용합니다.

Window에서 지원하지 않는 file system이기 때문에 Window 사용자들은 볼 수가 없습니다.

그래서 MTP(PTP)를 통해 서로 다른 file system을 사용가능하도록 하것 입니다.

간단하게 설명 드리면 ftp나 samba를 이용하면 Window에서 linux의 file을 볼 수 있는 것과 같이 서로 다른 file system을 emulate하는 것이 MTP(PTP)입니다.

Apple은 iTune를 통해 위에 설명한 것과 같이 동작합니다.

여기서 android가 iPhone의 방식을 쫓아 간다고 볼 수 있겠죠.
Apple에서는 iTune를 통해 file sync를 하는지 알 수 있습니다.



그런데 MTP는 Microsoft에서 PTP를 이용하여 Window Media에서 사용하기 위해 만들 protocol입니다. 그래서 UbuntuMac에서 사용하기 위해서는 설정을 해줘아 합니다.

http://www.omgubuntu.co.uk/2011/12/how-to-connect-your-android-ice-cream-sandwich-phone-to-ubuntu-for-file-access/

위에 링크에 Ubuntu에서 MTP를 사용하는 방법이 설명되어 있습니다.

하지만 mtpfs에 버그가 있어서 저의 경우에도 두대의 Ubuntu(11.04와 10.04LTS)에서 완벽하게 동작하지 않습니다.

https://bugs.launchpad.net/ubuntu/+source/mtpfs/+bug/573524

그런데 PTP로 연결하지 문제가 없이 잘 됩니다.

Google에 Window Media를 계속 빌려 쓸지 iTune와 같이 sync Manager 프로그램을 만들지 궁금해집니다.



2012년 1월 16일 월요일

linux cp2104 driver

CP2104 USB to Serial를 사용하는데 ubuntu에서 minicom이 안되는 문제가 있다.

찾아 보니 CP210x driver에 baudrate 초기화 버그가 있는 듯...

http://www.spinics.net/lists/linux-usb/msg56969.html

그래서 driver patch를 적용하여 보겠습니다.

자신이 사용하는 kernel 버전을 확인한다.

커널 버전 확인
$uname -a
Linux codewalker-desktop 2.6.32-38-generic #83-Ubuntu SMP Wed Jan 4 11:12:07 UTC 2012 x86_64 GNU/Linux


synaptic에서 desktop kernel source를 받는다.

linux-source, linux-source-2.6.32

아래 path로 소스 파일이 받아 진다.

/usr/src/linux-source-2.6.32.tar.bz2

/usr/src/linux-source-2.6.32/drivers/usb/serial/cp210x.c 수정한다.

 diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 3835106..dcba930 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -201,6 +201,8 @@ static struct usb_serial_driver cp210x_device = {
 #define CP210X_EMBED_EVENTS 0x15
 #define CP210X_GET_EVENTSTATE 0x16
 #define CP210X_SET_CHARS 0x19
+#define CP210X_GET_BAUDRATE 0x1d
+#define CP210X_SET_BAUDRATE 0x1e
 
 /* CP210X_IFC_ENABLE */
 #define UART_ENABLE  0x0001
@@ -459,16 +461,12 @@ static void cp210x_get_termios_port(struct usb_serial_port *port,
  unsigned int *cflagp, unsigned int *baudp)
 {
  unsigned int cflag, modem_ctl[4];
- unsigned int baud;
+ u32 baud;
  unsigned int bits;
 
  dbg("%s - port %d", __func__, port->number);
 
- cp210x_get_config(port, CP210X_GET_BAUDDIV, &baud, 2);
- /* Convert to baudrate */
- if (baud)
-  baud = cp210x_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud);
-
+ cp210x_get_config(port, CP210X_GET_BAUDRATE, &baud, sizeof(baud));
  dbg("%s - baud rate = %d", __func__, baud);
  *baudp = baud;
 
@@ -580,7 +578,8 @@ static void cp210x_set_termios(struct tty_struct *tty,
   struct usb_serial_port *port, struct ktermios *old_termios)
 {
  unsigned int cflag, old_cflag;
- unsigned int baud = 0, bits;
+ u32 baud;
+ unsigned int bits;
  unsigned int modem_ctl[4];
 
  dbg("%s - port %d", __func__, port->number);
@@ -595,8 +594,8 @@ static void cp210x_set_termios(struct tty_struct *tty,
  /* If the baud rate is to be updated*/
  if (baud != tty_termios_baud_rate(old_termios) && baud != 0) {
   dbg("%s - Setting baud rate to %d baud", __func__, baud);
-  if (cp210x_set_config_single(port, CP210X_SET_BAUDDIV,
-     ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) {
+  if (cp210x_set_config(port, CP210X_SET_BAUDRATE,
+       &baud, sizeof(baud))) {
    dbg("Baud rate requested not supported by device");
    baud = tty_termios_baud_rate(old_termios);
   }
-- 
 

$sudo make menuconfig


$sudo make -j10


kernel 빌드 시 에러가 발생 아래와 같이 수정.


ERROR-2
LD [M]  ubuntu/omnibook/omnibook.o
ld: /ubuntu/omnibook/sections.lds: No such file: No such file or directory
make[2]: *** [ubuntu/omnibook/omnibook.o] Error 1
make[1]: *** [ubuntu/omnibook] Error 2
make: *** [ubuntu] Error 2
SOLUTION-2
$ sudo vi /usr/src/linux/ubuntu/omnibook/Makefile
160: #EXTRA_LDFLAGS +=  $(src)/sections.lds
161: EXTRA_LDFLAGS += $(PWD)/ubuntu/omnibook/sections.lds


http://thangamaniarun.wordpress.com/2010/07/08/how-to-quickly-build-custom-kernel-on-ubuntu-10-04/




cp210x.ko module 만들기


$sudo make modules


$sudo make modules_install



[/lib/modules]$ ls -l
합계 20
drwxr-xr-x 4 root root 4096 2010-04-29 21:45 2.6.32-21-generic
drwxr-xr-x 5 root root 4096 2011-12-16 18:47 2.6.32-36-generic
drwxr-xr-x 5 root root 4096 2012-01-17 16:24 2.6.32-37-generic
drwxr-xr-x 5 root root 4096 2012-01-24 17:09 2.6.32-38-generic
drwxr-xr-x 3 root root 4096 2012-01-25 17:54 2.6.32.52+drm33.21



kernel 소스 Makefile에 EXTRAVERSION이 실제 설치된 kernel과 틀리다.


그래서 수동으로 cp210x.ko를 2.6.32-38-generic 폴더 밑에 파일로 바꿔주면 된다.


EXTRAVERSION이 다르지만 insmod나 hot-plugin시 문제 없이 module이 올라 간다.


혹시나 드라이버에 문제가 생기면 동일한 linux-image-generic를 synaptic에서 재설치해 주면 해결된다.


module의 EXTRAVERSION을 확인하기 위해서는 modinfo를 이용하면 된다.



alias:          usb:v0FCFp1004d*dc*dsc*dp*ic*isc*ip*
alias:          usb:v0FCFp1003d*dc*dsc*dp*ic*isc*ip*
alias:          usb:v0BEDp1101d*dc*dsc*dp*ic*isc*ip*
alias:          usb:v0BEDp1100d*dc*dsc*dp*ic*isc*ip*
alias:          usb:v08FDp000Ad*dc*dsc*dp*ic*isc*ip*
alias:          usb:v08E6p5501d*dc*dsc*dp*ic*isc*ip*
alias:          usb:v0745p1000d*dc*dsc*dp*ic*isc*ip*
alias:          usb:v0489pE000d*dc*dsc*dp*ic*isc*ip*
alias:          usb:v0471p066Ad*dc*dsc*dp*ic*isc*ip*
alias:          usb:v045Bp0053d*dc*dsc*dp*ic*isc*ip*
depends:        usbserial
vermagic:       2.6.32.52+drm33.21 SMP mod_unload modversions 
parm:           debug:Enable verbose debugging messages (bool)
[/lib/modules/2.6.32-38-generic/kernel/drivers/usb/serial]$