android 기본 개발환경인 이클립스 ADT 만을 이용하면 환경설정파일을 자동으로 관리해줄수가 없습니다.
그래서 이 문서에서는 maven 을 이용해 환경설정파일을 소스 수정없이 빌드옵션 수정만으로 관리할수있도록 구성하는 방법을 알아봅니다.

* maven 을 이용한 android 자동 빌드환경 구성

   - http://cranix.net/374

 

* resource 디렉토리 만들기
  - src/main/resources 디렉토리를 생성합니다.
image

- 프로젝트 마우스오른쪽 –> maven –> update project configuration 을 실행하면 위와같이 소스폴더에 포함되는것을 확인할수 있습니다.

 


* config 파일 읽기
  - resource 디렉토리에 config.properties 파일을 생성하고 아래와같이 입력합니다.

url = http://test/real

  - properties 파일을 읽기위한 코드는 아래와 같습니다.

package net.cranix.android.hello;


import java.io.IOException;
import java.util.Properties;

/**
* @author cranix
*/
public class Constants {
    private static Properties config = new Properties();
    static {
        try {
            config.load(Constants.class.getClassLoader().getResourceAsStream("config.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
   
   
    public static String URL = config.getProperty("url");
}

   - 이것의 사용은 간단합니다.

package net.cranix.android.hello;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class HelloActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        TextView tv = (TextView) findViewById(R.id.textView1);
        tv.setText(Constants.URL);
    }
}

 


* 디렉토리 구조 만들기

   - config 디렉토리를 생성하고 config_beta.properties,config_real.properties 파일을 만들어서 집어넣습니다.

image

  - 위와같은 형태로 디렉토리 구조를 만듭니다.
  - config_beta.properties  파일과 config_real.properties 파일에는 beta 와 real 에서 사용될 적절한 환경변수를 집어넣습니다.

 

* maven pom 파일 수정하기
  - pom 파일을 아래와같이 수정합니다.


<properties>
   …
   <config>beta</config>
</properties>


<build>

    <plugins>
        <plugin>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>1.7</version>
            <executions>
                <execution>
                    <phase>generate-resources</phase>
                    <configuration>
                        <target>
                            <delete
                                file="${project.basedir}/src/main/resources/config.properties" />
                            <copy tofile="${project.basedir}/src/main/resources/config.properties"
                                file="${project.basedir}/config/config_${config}.properties" />
                        </target>
                    </configuration>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        …
   </plugins>

</build>

   - 위와같이 했을때 execution 에서 오류나는 경우가 있는데 이것은 단순 버그임으로 이클립스의 Problems view 에서 delete 합니다.

image

  - 프로젝트 마우스오른쪽 –> maven –> update project configuration 을 실행합니다.

 

* build 파라메터를 변경하여 실행
   - real 환경으로 실행하기
     --> run as –> maven build … 을 클릭하고 아래와같이 입력하고 실행합니다.
image

   - 이제부터는 위와같이 build 의 parameter 를 변경하는것 만으로 beta 와 real 설정파일을 변경할 수 있습니다.

Posted by cranix

안드로이드 에서는 xml 만을 이용하여 이미지의 전환효과를 줄수 있습니다.
예를들어 웹상에서 롤오버 같은 기능을 xml 만을 이용해서 만들수 있게 되는것이죠.
해당 xml 은 아래와 같이 작성합니다.

- btn.xml
 <?xml version="1.0" encoding="utf-8"?>
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_focused="true" android:drawable="@drawable/btn_focus"/>
     <item android:state_enabled="false" android:drawable="@drawable/btn_off"/>
     <item android:state_selected="true" android:drawable="@drawable/btn_select"/>
    
     <item android:drawable="@drawable/btn_normal" /> <!-- default -->
 </selector>

위와 같은 xml 을 작성해서 drawable 에 넣어놨다면 안드로이드 전역에서 R.drawable.btn 이라는 리소스를 사용 가능하게 됩니다.
예를들어 이 xml 을 background 로 넣은 view 는 상태가 focused, enabled 혹은 selected 될때 위 xml 에 정의된대로 바뀌게 됩니다.
Posted by cranix
안드로이드에서 애니메이션 처리를 하기위해서는 두가지를 해야 합니다.
animation 을 정의하는 xml 파일을 작성하고, 해당 xml 을 view 나 activity 에 적용하는 작업 입니다.

<Animation xml 만들기>
- pull_down_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
 <translate android:fromYDelta="0" android:toYDelta="100%p" android:duration="300"/>
 
</set>

위 소스는 타겟이 pull_down 으로 없어지는 애니메이션을 정의한 것입니다.
이러한 움직임을 정의하는 translate 태그 말고도, 투명도를 제어하는 alpha 태그, 회전을 제어하는 rotate 태그, 크기를 제어하는 scale 태그가 있습니다.

<Animation 적용하기>
이와같은 xml 은 아래와같이 적용하고 또 리스너를 이용해서 애니메이션의 시작/끝 지점을 잡아낼 수 있습니다.
 Animation anim = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.push_up_webview);   
   anim.setAnimationListener(new Animation.AnimationListener() {
    public void onAnimationStart(Animation animation) {
    }
    
    public void onAnimationRepeat(Animation animation) {
    }
    public void onAnimationEnd(Animation animation) {
     runOnUiThread(new Runnable() {
      public void run() {
       progressLoading.setVisibility(View.GONE);
      }
     });     
    }
   });   
   progressLoading.startAnimation(anim);

Posted by cranix
안드로이드에서 가장 많이 사용하는 View 는 ListView 일 것으로 생각됩니다.(적어도 저는...)
이 리스트뷰는 기본적으로 리스트형의 많은양의 데이터를 표시하기위해 존재합니다.
그래서 프로그래밍 하는 스타일에 따라 체감속도에 영향을 많이 줍니다.

안드로이드에서는 이러한 데이터의 효율적인 처리를 위해서 이미 사용되어진 view 를 재활용 할 수 있도록 해 주고 있습니다.
이번 포스트에서는 그 재활용 하는 방법에 대해서 알아보도록 하겠습니다.


안드로이드는 ListView 에 데이터를 채울때 Adapter 를 이용합니다.
이 Adapter 를 생성할때 가장 중요한메소드는 getView() 입니다.
아래와 같은 기본형을 가집니다.
View getView(int position, View convertView, ViewGroup parent)

이 메소드의 파라메터중 convertView 가 재활용과 관련된 파라메터 입니다.
이 convertView 파라메터에서는 재사용할 view 가 없다면 null 을 넘겨주고 있다면 해당 view 를 넘겨줍니다.

이를 이용하여 Holder 패턴을 구현하는데 대부분 아래와 같이 사용합니다.
 public class ItemHolder {
  public TextView textView = null;
 }

 public View getView(int position, View convertView, ViewGroup parent) {
  ItemHolder holder = null;
  if (convertView == null || convertView.getId() != R.layout.list_item) {
// 재사용할 view 가 없거나 재사용할 view 가 다른 layout 으로 작성되어졌을경우 xml 새로 파싱합니다.
// convertView 에는 여기서 inflate 한 view 만 넘어오는것이 아닙니다.
// 예를들어 이 listview 에 headerView 가 있다면 headerView 역시 convertView 에 넘어오게 됩니다. 
// 이럴경우 원하지 않은 결과가(거의 크래쉬) 나오기때문에 반드시 layout 이 맞는지를 비교해 줘야합니다.


   convertView = inflater.inflate(R.layout.list_item, null);
   holder = new ItemHolder();
   holder.textView = (TextView) convertView.findViewById(R.id.textView1);
// 파싱된 결과를 holder 에 담아서 tag 로 저장해둡니다.
   convertView.setTag(holder);
   convertView.setId(R.layout.list_item);
  }
  else {
// 재사용할 view 가 있을경우 해당 view 의 tag 를 가져와서 ItemHolder 로 캐스팅하여 사용합니다.
   holder = (ItemHolder) convertView.getTag();
  }

// 여기부터는 얻어온 holder 를 이용하여 데이터를 채웁니다.
  holder.textView.setText(getItem(position).toString());
  
  return convertView;
 }

이런 형태를 취하는 이유는 안드로이드에서 시간이 가장 오래걸리는 작업중의 하나가 findViewById 메소드를 이용한 xml 파싱작업 이기 때문에 해당 메소드의 호출을 최소화 하기 위함입니다.




Posted by cranix

 

Lazy 오목 Online!

 

- 게임물등급위원회 전체용가 -


 

- 인공지능 플레이 기능 -

- 터치실수를 없애기위해 두번 터치해야 돌 놓아지는 시스템 적용 -

- 온라인상의 다른 유저와 게임기능 -

- 채팅 기능 -

- 렌주룰에의한 금수 완벽 적용(단 AI 플레이시는 제외) -

- 백이 금수(3*3,4*4,6목,장목)를 이용하여 승리할 경우 가산점 부여 -

- 유저랭킹 및 금수랭킹 기능 -


- 전화번호로 직접요청 가능-

- 다른 작업중에도 내 차례가 되면 노티 해주는 기능 -


- 룰정보 확인 -



Lazy 오목용 유저 게시판을 만들었습니다. 
아래 주소로 접속해 주세요.

http://apps.silpir.net
 



업데이트 로그
- v2.2 ad
    - 네트워크 연결 안되어있어도 AI 와 플레이 가능
    - 전체적인 반응속도 대폭 개선
    - 렌주룰완전 적용
    - 서버 안정화

- v2.15 ad
   - 채팅 기능이 추가되었습니다.

- v2.1 ad
   - 흑이 3/3/3,4/4/4 되던거 안되도록 수정
   - 게임에 들어가자마자 메뉴 버튼을 누르면 튕기던 버그 수정
   - 금수로 승리하면 +1 점 추가됩니다.
   - 영어옵션 추가 (번역이 완벽하지 않습니다.)
   - 종료예약 추가
    - 사운드 추가
    - 최근게임리스트 추가
    - 노티가 너무 많이나오던거 수정




- v2.0 ad
   - 흑(선) 플레이시 3*3, 4*4, 6목 모두 안되게 수정
   - 룰정보 페이지 추가 (게임룰,금수룰,점수룰 설명)
   - 커뮤니케이션용 홈페이지 생성 : http://apps.silpir.net
   - 여러 디바이스 대응을 위해서 레이아웃의 크기단위를 dp 로 수정
   - 게임랭킹 기존 11개에서 15개 보이도록 수정


- v1.9 ad
   - 점수 시스템 개선 --> 30일동안 업데이트가 없는 점수데이터는 다른 유저의 점수에 영향을 미치지 않고 삭제됨
   - 랭킹화면에서 원하는 유저를 클릭하면 "게임신청" 이 나와서 직접 신청할수 있는 기능
   - 흑(선) 플레이시 3*3 룰을 적용받는 기능 ( 단 컴퓨터 "autobot" 은 3/3 적용받지 않음 )
   - 현재 기다린 시간 표시해주는 기능
   - 웹 클라이언트와 대국시 점수반영안되게 함.


- v1.82 ad
<광고 삽입>
   - 사용자가 많아지다보니 서버유지가 힘들어져 서버유지 비용을 벌기위해 광고 삽입


- v1.8 beta
<노티 시스템 업데이트>
    - 내가 해야할 차례라면 어플을 꺼놔도 노티가 오게 됩니다. (예를들어 게임대기를 눌러놓고 어플을 꺼놓으면 게임이 시작될때 문자온것과 똑같이 노티로 알려주게 됩니다.)

    - 어플을 처음 실행하면 가장최근에 플레이한 게임으로 자동으로 이동시켜주는 기능이 있었는데 이 기능을 빼고 내가 해야할 게임들의 노티를 띄우도록 하였습니다. (여러게임을 동시에 진행하고 있다면 이 기능이 오히려 불편하기 때문입니다.)


<기타 버그수정>
   - 노티로 오는 전화번호가 가려지지않고 모두 나오던것 수정

   - 노티가 제대로 동작하지 않던것 수정



====== 룰 정보 =======

렌주룰
- LazyOmok 은 렌주룰을 따릅니다.
- 렌주룰은 먼저하는 흑의 유리함을 어느정도 없애기위해 개발된 룰입니다.
- 간단한 룰에대해서는 아래에 정리하였습니다.
- 그 외에 자세한 정보를 원하시면 아래 홈페이지를 이용해 주시기 바랍니다.
- http://www.renjukorea.com

게임룰
승리
- 자신의 돌을 가로,세로 혹은 대각선중의 하나로 5개 연속으로 놓으면 승리하게 됩니다.
- 백은 6개 이상 연속으로 놔도 승리 처리됩니다.
- 게임중 상대 턴인 상태에서 5분이상 기다렸을때 종료하면 승리하게 됩니다.
패배
- 상대가 먼저 승리조건을 만족시키면 패배합니다.
- 게임중 자신의 턴인 상태에서 종료하면 패배합니다.

금수룰
- LazyOmok 에서는 먼저하는 흑의 유리함을 어느정도 없애기 위해서 유저가 흑 플레이시 금수를 적용하고 있습니다.
- LazyOmok 에서 금수는 3*3, 4*4, 6목, 장목 입니다.
- 장목은 돌을 6개 이상 이어나가는것을 말합니다.
- 백과, AI(autobot)는 금수룰을 적용받지 않습니다.
- 만약 이길수 있는 자리에 금수가 겹쳐있다면 금수우선룰에 의해 놓을수 없게 됩니다.

점수룰
- 점수는 승리시 +2 점, 패배시 -2점 입니다.
- 만약 백이 금수로 승리할때에는 승점에 +1 점 추가됩니다.
- 점수는 유저랭킹과 금수승랭킹으로 나뉘어서 저장됩니다.
- 30일동안 점수의 업데이트가 없으면 자동으로 점수데이터가 초기화됩니다.


 
언젠가 아이폰용 한게임 고스돕을 해본적이 있습니다.

상당한 퀄리티에 잘 만들어져 있었으나 한가지 불편한점이 있었습니다.

 

바로 게임도중 끊기면 그 판이 날라간다는 것이지요.

이런 상황이 발생하면 폰 탓만 했는데 그게 아니라는 생각이 들었습니다.

 

아무리 현재 3G 가 좋아졌고 곳곳에 와이파이 존이 있다고 하지만

여러가지 다른 환경적인 요인에 의해서 순간적으로 네트웍이 끊기는 상황은 자주 나타나고 있습니다.

 

이러한 상황에서 끊김없는PC 에서 하던것과 똑같이 온라인게임을 만들면,

위와 같이 해당 게임이 날라가는 상황을 피할수 없게 됩니다.

 

그래서 좀 더 모바일 환경에 맞는 Online게임을 만들수 없을까?

라는 생각에서 나온것이 바로 “Lazy 오목 Online!” 입니다.

 

이 게임은 모바일에서 메시지 주고받듯이 게임을 진행할 수 있습니다.

예를들면 게임을 시작하고 자신의 차례가 되면 아래와 같은 노티가 오게됩니다.

해당 노티를 터치하면 바로 해당 게임으로 넘어가게 되고 플레이를 계속할 수 있게 됩니다.

(단 이러한 노티는 게임을 Home 키를 눌러서 백그라운드 상태로 돌려놨을때만 동작합니다. 즉 현재 게임화면을 보고있으면 노티가 오지 않습니다.)

 

또한 이 게임은 시간제한이 없습니다.

PC 에서처럼 모바일 환경은 언제나 게임에 집중할 수 없기 때문에 시간제한을 없앴습니다.

대신 누구나 종료할수 있도록 만들었습니다.

 

이렇게 시간제한 없이 게으른 플레이를 할 수 있다고 하여서 이름도 “Lazy” 입니다.^^

 

 

Posted by cranix

CranixDialer Beta (v1.5)
이번 버젼에서는 다음과 같은 기능이 추가/변경 되었습니다.
  • 메인 리스트에 바로 전화걸기 버튼 추가
  • 버튼사운드 하나로 줄임(로딩속도 향상)
  • 메인 검색루틴 수정
  • 아이콘 변경

이번 버젼에서는 전화걸기 버튼 추가와 이전 버젼에서의 버그를 수정하였습니다.
이전 버젼에서 숫자마다 따로 사운드를 넣다보니 로딩속도 때문에 초기 구동속도가 느렸습니다.
그래서 부득이 버튼 사운드를 하나로 줄여서 구동속도를 빠르게 하였습니다.
또한 메인의 프로그램실행시 아이콘을 변경하였습니다.

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



CranixDialer Beta (v1.4)
이번 버젼에서는 다음과 같은 기능이 추가/변경 되었습니다.
  • 메인 검색 알고리즘 수정(약간의 속도향상및 몇몇 폰에서 오류나는 현상 수정예상-_-;)
  • 버튼 사운드 출력 방식 수정(기존의 딜레이 있던 현상 수정)
  • 메시지 보내는 방식 수정(몇몇 폰에서 메시지 보내기 누를때 오류나는 버그 수정 예상)

이번 버젼에서는 안정화 시키려고 노력했습니다.
사실 제가 폰이 디자이어밖에 없는 관계로 다른폰에서 테스트는 못해보았지만..ㅜㅜ
여러 예상되는 오류를 수정하였습니다.




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

CranixDialer Beta (v1.3)
이번 버젼에서는 다음과 같은 기능이 추가/변경 되었습니다.
  • 아이콘 수정
  • 새로운 연락처 추가시 업데이트 제대로 안되던 버그 수정
  • 영어 대소문자 모두 검색
  • 단축번호누를시 반응 설정
  • 버튼 누를시 사운드 효과 추가

 



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



CranixDialer Beta (v1.2)
이번 버젼에서는 다음과 같은 기능이 추가/변경 되었습니다.
  • 아이콘 변경
  • 단축번호 기능 추가
  • 짧은클릭을 "연락처보기" 로 설정해 놨을때 연락처에 없는 번호 클릭하면 오류나던거 수정
이번 버젼은 단축번호 기능을 추가하였습니다.
단축번호를 사용하기 위해서는 숫자 다이얼 패드에서 숫자를 길게 누르면 됩니다.

이후업데이트는 기능추가보다는 버그개선 및 안정화 그리고 속도개선 같은 기본적인 기능 업그레이드 될 예정입니다.


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

CranixDialer Beta (v1.1)
이번 버젼에서는 다음과 같은 기능이 추가/변경 되었습니다.
  • Setting 페이지 추가
  • 키패드,숫자패드 선택가능
  • 키패드 진동 선택가능
  • 통화및 메시지 보낸후 자동종료 선택가능
  • 짧은터치시 반응 선택가능
  • "*" 길게 누르면 진동모드/정상모드 전환
  • 전화목록이 없을때 실행안되던 버그수정
  • 아이콘 변경 (미반영)
  • 반응속도 대폭 개선
  • 특정 상황에서 오류나는 버그 수정
  • "010" 을 입력하면 010 으로 시작되는 전화번호 검색되지 않음

이번 버젼은 Setting 페이지를 추가한것이 가장 큰 특징입니다.
그리고 자잘한 버그들을 수정하였습니다.

이번 버젼에서는 드디어!
안드로이드 마켓에 등록하였습니다.
마켓에서 CranixDialer 로 검색하신후에 받으시면 됩니다!


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

CranixDialer Beta (v1.0)
업데이트 목록입니다.

  • 쌍자음 검색추가
  • 클립보드 복사메뉴 추가
  • 리스트에서 back 누를시 프로그램 종료
  • 업데이트 제대로 안되던 버그 수정
  • 연락처가 통화로그와 섞이는 버그 수정
  • 다이얼 버튼 추가 !
  • 속도개선
  • 부재중 통화왔을때 CranixDialer 누르면 알람메시지 사라지도록 수정 (미구현)

이번 버젼은 다이얼버튼을 추가했습니다.
위에서 보는바와같이 초성과 숫자가 한꺼번에 검색됩니다.

부재중 알람메시지 사라지게 하는방법을 아직 찾지 못했네요.-_-;
혹시 아시는분 있으면 가르쳐 주시기 바랍니다.


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

CranixDialer Beta (v0.9)
  • 아이콘 변경
  • 알림메시지의 부재중 통화 클릭하면 CranixDialer 도 선택에 뜨도록 수정
  • 시간이 스크롤바에 가려지지않게 수정
  • 최근 통화목록과 연락처가 통합되어 한꺼번에 검색됨
  • 기본으로 최근통화목록이 제일위에 정렬되고 검색시에는 검색어 우선순위별로 자동정렬됨
  • 리스트를 터치하면 키보드가 숨겨져서 넓은 화면이 되도록 수정
  • 검색텍스트박스를 위로 올림
  • neoStyle 키보드를 사용시 맨윗사람 안보이는 버그 수정
  • 프로그램 정보 창 추가
  • *119 와 같은 형태의 전화 전화걸기가능
  • 소스코드 재작성
  • 돋보기 버튼 길게 클릭하면 CranixDialer 뜨게 수정

제 폰에서 마루타 실험한 결과 버그를 확인하지 못했습니다.
그래서 이렇게 올립니다.
테스트 부탁드립니다.





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



CranixDialer Beta (v0.81)

통화목록의 날짜 버그때문에 급히 수정버젼을 올립니다.
이번 버젼에서 추가/수정 된 기능은 아래와 같습니다.

  • 여러개 한꺼번에 나오는 송수신목록 하나로 합치고 갯수만 표시하도록 수정
  • 송/수신/부재중 통화 화살표 아이콘으로 표시
  • 각 송수신목록별 통화로그 출력


※ 0.8 버젼에 시간 오늘/내일 표시하는 부분과 송수신 갯수 출력하는 부분이 버그가 있어서 수정해서 올립니다.


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




CranixDialer Beta (v0.7)
이번 버젼에는 다음과 같은 기능이 추가되었습니다.
  • 검색어 우선순위 (첫글자부터 매칭된 이름이나 붙어있는 이름 우선순위줌)
  • 클릭시 바로 전화걸리지 않고 선택메뉴 나옴
  • 모르는 번호는 Unknown 대신 전화번호로 나오기
  • 통화기록 개별삭제 및 전체삭제
  • 기타 자잘한 버그수정
  • 메시지 보내기 메뉴 추가
이번 버젼에서 UI 추가나 수정은 없습니다.
대신 검색기능을 조금 더 강화하고 편의기능을 추가하였습니다.

다음버젼에는 UI 의 전체적인 수정이 있을 예정입니다.
"초성검색 다이얼 버튼" 역시 UI 부분이기 때문에 다음버젼에 추가될 예정입니다.

더 추가할 기능이나 아이디어 있으시면 댓글 달아주세요.
적극 반영하겠습니다.


--------------------------------------------------------------------------------------
CranixDialer Beta (v 0.5)





안드로이드 초성검색 어플 CranixDialer!
초성검색 기능에 충실하게 만들었습니다.

아직 베타라 수정사항이 많이 있을것을 예상됩니다.
써 보시고 버그나 수정사항이 있으시면 댓글 달아주세요.
다음 버전에 반영하도록 하겠습니다.








Posted by cranix
안드로이드에서 UBI FS 를 사용하기 위해서는 아래와 같이 커넬셋팅을 해야한다.
먼저 make menuconfig 로 들어간 다음에 아래 순서대로 빌트인 (*) 을 하자
참고로 커널버젼 2.6.29 이다.


- Device Drivers -> Memory Technology Device (MTD) support -> UBI - Unsorted block images -> Enable UBI <*>

- File systems -> Miscellaneous filesystems -> UBIFS file system surpport <*>


 
Posted by cranix
TAG Android, ubifs
개요
안드로이드에서 hardware/libhardware/include/hardware 디렉토리에 가보면 HAL 관련 헤더파일들이 있는데 이중 copybit 라는것이 있다.
이것이 하는일은 무엇일까?
일단은 헤더파일부터 분석하고 다른 기기에 포팅된 copybit 를 보면서 다른점을 파악해 보도록 하겠다.



위치
안드로이드 기본 헤더파일 이기때문에 "hardware/libhardware/include/hardware" 디렉토리에 헤더파일이 위치하고 "hardware/libhardware/modules/" 디렉토리에 소스파일이 위치하면 된다.



copybit.h 분석

 /**

 * The id of this module

 */

#define COPYBIT_HARDWARE_MODULE_ID "copybit"


/**

 * Name of the graphics device to open

 */

#define COPYBIT_HARDWARE_COPYBIT0 "copybit0"

이부분은 안드로이드 HAL copybit ID 와 하드웨어 디바이스 드라이버 이름을 지정하는 곳이다.
역시나 copybit 도 하드웨어가 있는거 같다.


 /* supported pixel-formats. these must be compatible with

 * graphics/PixelFormat.java, ui/PixelFormat.h, pixelflinger/format.h

 */

enum {

    COPYBIT_FORMAT_RGBA_8888    = HAL_PIXEL_FORMAT_RGBA_8888,

    COPYBIT_FORMAT_RGBX_8888    = HAL_PIXEL_FORMAT_RGBX_8888,

    COPYBIT_FORMAT_RGB_888      = HAL_PIXEL_FORMAT_RGB_888,

    COPYBIT_FORMAT_RGB_565      = HAL_PIXEL_FORMAT_RGB_565,

    COPYBIT_FORMAT_BGRA_8888    = HAL_PIXEL_FORMAT_BGRA_8888,

    COPYBIT_FORMAT_RGBA_5551    = HAL_PIXEL_FORMAT_RGBA_5551,

    COPYBIT_FORMAT_RGBA_4444    = HAL_PIXEL_FORMAT_RGBA_4444,

    COPYBIT_FORMAT_YCbCr_422_SP = HAL_PIXEL_FORMAT_YCbCr_422_SP,

    COPYBIT_FORMAT_YCbCr_420_SP = HAL_PIXEL_FORMAT_YCbCr_420_SP,

};

다음은 PIXEL 포멧을 지정하는 곳이다.
아마도 graphics/PixelFormat.java, ui/PixelFormat.h, pixelflinger/format.h 이 파일들에서 이것을 사용하는것이 아닐까 싶다.

 /* name for copybit_set_parameter */

enum {

    /* rotation of the source image in degrees (0 to 359) */

    COPYBIT_ROTATION_DEG    = 1,

    /* plane alpha value */

    COPYBIT_PLANE_ALPHA     = 2,

    /* enable or disable dithering */

    COPYBIT_DITHER          = 3,

    /* transformation applied (this is a superset of COPYBIT_ROTATION_DEG) */

    COPYBIT_TRANSFORM       = 4,

    /* blurs the copied bitmap. The amount of blurring cannot be changed

     * at this time. */

    COPYBIT_BLUR            = 5

};

copybit 의 파라메터를 셋팅한다.
이로서 copybit 는 기본적인 2d 연산인 이동,회전,투명,블러 처리 등을 하는것을 알 수있다.

 /* values for copybit_set_parameter(COPYBIT_TRANSFORM) */

enum {

    /* flip source image horizontally */

    COPYBIT_TRANSFORM_FLIP_H    = HAL_TRANSFORM_FLIP_H,

    /* flip source image vertically */

    COPYBIT_TRANSFORM_FLIP_V    = HAL_TRANSFORM_FLIP_V,

    /* rotate source image 90 degres */

    COPYBIT_TRANSFORM_ROT_90    = HAL_TRANSFORM_ROT_90,

    /* rotate source image 180 degres */

    COPYBIT_TRANSFORM_ROT_180   = HAL_TRANSFORM_ROT_180,

    /* rotate source image 270 degres */

    COPYBIT_TRANSFORM_ROT_270   = HAL_TRANSFORM_ROT_270,

};

 이부분은 아마도 COPYBIT_TRANSFORM 파라메터와 같이 사용해서 이미지의 회전을 담당하는것 같다.

 /* enable/disable value copybit_set_parameter */

enum {

    COPYBIT_DISABLE = 0,

    COPYBIT_ENABLE  = 1

};

파라메터 셋팅을 끌수도 있는것인가?
그게 과연 필요한가?


 /* use get_static_info() to query static informations about the hardware */

enum {

    /* Maximum amount of minification supported by the hardware*/

    COPYBIT_MINIFICATION_LIMIT  = 1,

    /* Maximum amount of magnification supported by the hardware */

    COPYBIT_MAGNIFICATION_LIMIT = 2,

    /* Number of fractional bits support by the scaling engine */

    COPYBIT_SCALING_FRAC_BITS   = 3,

    /* Supported rotation step in degres. */

    COPYBIT_ROTATION_STEP_DEG   = 4,

};

하드웨어의 기본적인 정보들 인거 같다.
각각 다른 의미를 지니고 있는것 같지만 아직은 역할을 잘 모르겠다.

/* Image structure */

struct copybit_image_t {

    /* width */

    uint32_t    w;

    /* height */

    uint32_t    h;

    /* format COPYBIT_FORMAT_xxx */

    int32_t     format;

    /* base of buffer with image */

    void        *base;

    /* handle to the image */

    native_handle_t* handle;

};


/* Rectangle */

struct copybit_rect_t {

    /* left */

    int l;

    /* top */

    int t;

    /* right */

    int r;

    /* bottom */

    int b;

};


/* Region */

struct copybit_region_t {

    int (*next)(struct copybit_region_t const *region, struct copybit_rect_t *rect);

};

copybit_region_t 는 이름그대로 복사 영역이라는 뜻인거 같고 copybit_rect_t 구조체를 링크 시키고 있는것을 알 수있다.
아마도 해당 영역에 copybit 작업을 한 후에 완료된 region 을 image 에 적용하도록 설계되어 있는거 같다.

/**

 * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM

 * and the fields of this data structure must begin with hw_module_t

 * followed by module specific information.

 */

struct copybit_module_t {

    struct hw_module_t common;

};


/**

 * Every device data structure must begin with hw_device_t

 * followed by module specific public methods and attributes.

 */

struct copybit_device_t {

    struct hw_device_t common;


    /**

     * Set a copybit parameter.

     *

     * @param dev from open

     * @param name one for the COPYBIT_NAME_xxx

     * @param value one of the COPYBIT_VALUE_xxx

     *

     * @return 0 if successful

     */

    int (*set_parameter)(struct copybit_device_t *dev, int name, int value);


    /**

     * Get a static copybit information.

     *

     * @param dev from open

     * @param name one of the COPYBIT_STATIC_xxx

     *

     * @return value or -EINVAL if error

     */

    int (*get)(struct copybit_device_t *dev, int name);


    /**

     * Execute the bit blit copy operation

     *

     * @param dev from open

     * @param dst is the destination image

     * @param src is the source image

     * @param region the clip region

     *

     * @return 0 if successful

     */

    int (*blit)(struct copybit_device_t *dev,

                struct copybit_image_t const *dst,

                struct copybit_image_t const *src,

                struct copybit_region_t const *region);


    /**

     * Execute the stretch bit blit copy operation

     *

     * @param dev from open

     * @param dst is the destination image

     * @param src is the source image

     * @param dst_rect is the destination rectangle

     * @param src_rect is the source rectangle

     * @param region the clip region

     *

     * @return 0 if successful

     */

    int (*stretch)(struct copybit_device_t *dev,

                   struct copybit_image_t const *dst,

                   struct copybit_image_t const *src,

                   struct copybit_rect_t const *dst_rect,

                   struct copybit_rect_t const *src_rect,

                   struct copybit_region_t const *region);

};

이것은 모든 안드로이드 HAL 모듈이 가지고 있는 device 와 module 구조체를 생성하는 부분이다.
안드로이드 내에서 이 HAL 모듈을 사용하기 위해서는 여기에 적혀있는 함수를 사용해야만 하기 때문에 이 함수들이야 말로 이 모듈의 기능을 함축하고 있다고 할 수있다.

copybit 에서보면 device 에 추가 함수들이 몇개 보이는데 한번 알아보도록 하자.
먼저 set_parameter 함수는 위에서 알아본 enum 구조체를 사용해서 파라메터를 등록하는 부분인거 같다.
다음으로 get은 역시 위에서 알아본 enum 구조체를 이용하여 하드웨어에 맞는 값을 돌려주는 일을 하는거 같다.

제일 중요한 부분인 blit 함수와 stretch 함수를 보자.
아마 set_parameter 함수를 이용해서 원하는 셋팅을 한후에 blit 이나 stretch 함수를 호출해서 변환을 하는것 같다.

blit 와 stretch 함수는 하는 역할은 똑같이 복사하는것인데 blit 은 원본을 그대로 복사하고 stretch 는 원본을 줄이거나 늘려서 복사하는역할을 하는것 같다.

Posted by cranix
개요
안드로이드 기본 소스코드는 밧데리가 없으면 시작되자마자 바로 꺼지도록 되어있다.
그래서 타겟보드에서 작업할 때에는 가장 먼저 이 밧데리 부분을 주석걸어 주어야지 꺼지지않고 실행이 된다.
이번 포스트에서는 그 방법을 알아보도록 하자.


밧데리 패치
"frameworks/base/services/java/com/android/server/BatteryService.java" 파일을 열어자.

     private final void shutdownIfNoPower() {

        // shut down gracefully if our battery is critically low and we are not powered.

        // wait until the system has booted before attempting to display the shutdown dialog.

        /*

        if (mBatteryLevel == 0 && !isPowered() && ActivityManagerNative.isSystemReady()) {

            Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);

            intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);

            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

            mContext.startActivity(intent);

        }

        */

    }


    private native void native_update();


    private synchronized final void update() {

        //native_update();


        boolean logOutlier = false;

        long dischargeDuration = 0;

        ...
약 186 라인쯤에 위와 같은 부분을 찾을 수 있는데 위처럼 주석을 걸어주자.
이제 컴파일하고 타겟보드에 올리고 실행하면 제대로 될 것이다.
Posted by cranix
필요한 라이브러리 설치하기
컴파일 하기위해서 필요한 라이브러리를 한꺼번에 설치하자.

# apt-get install git-core gnupg flex bison gperf libsdl-dev libesd0-dev libwxgtk2.6-dev build-essential zip curl libncurses5-dev zlib1g-dev
# apt-get install valgrind



자바 1.5 설치하기
안드로이드는 아직 자바 1.6을 지원하지 않는다. 그래서 1.5 를 설치해야 하는데 문제는 우분투 9.10 에서는 자바 1.5 를 apt-get 으로 설치할수 없다는 것이다.
그래서 아래와 같은 방법이 필요하다.

시스템>관리>소프트웨어 소스를 선택하면 [소프트웨어 소스] 창이 뜬다.
여기서 기타 소프트웨어 탭에서 아래 와 같이 추가해 주자.

deb http://kr.archive.ubuntu.com/ubuntu/ jaunty multiverse
deb http://kr.archive.ubuntu.com/ubuntu/ jaunty-updates multiverse

창을 닫으면 소프트웨어를 다시 읽는것을 볼 수 있다.
내 컴퓨터 같은경우는 다시 읽다가 거의 다된 시점에서 계속 멈추어 있길래 취소를 눌러주었다.
뭔가 오류가 났지만 상관없이 진행되었다.
다되었으면 apt-get 으로 설치해 보도록 하자.

 # apt-get install sun-java5-jdk

 이제 설치되었다면 버젼을 확인해 보자.

 # java -version

 만약 1.5 가 아니라면 아래 명령으로 자바 리스트를 확인한후 업데이트 시켜주자.

# update-java-alternatives -l

java-1.5.0-sun 53 /usr/lib/jvm/java-1.5.0-sun

java-6-sun 63 /usr/lib/jvm/java-6-sun

# update-java-alternatives -s java-1.5.0-sun

 만약 자바 버젼을 바꾸는 도중 아래와 같은 메시지를 볼 수도 있을것이다.

update-alternatives: error: no alternatives for firefox-javaplugin.so.

update-alternatives: error: no alternatives for iceape-javaplugin.so.

update-alternatives: error: no alternatives for iceweasel-javaplugin.so.

update-alternatives: error: no alternatives for jhat.

update-alternatives: error: no alternatives for jrunscript.

update-alternatives: error: no alternatives for midbrowser-javaplugin.so.

update-alternatives: error: no alternatives for mozilla-javaplugin.so.

update-alternatives: error: no alternatives for schemagen.

update-alternatives: error: no alternatives for wsgen.

update-alternatives: error: no alternatives for wsimport.

update-alternatives: error: no alternatives for xjc.

update-alternatives: error: no alternatives for xulrunner-1.9-javaplugin.so.

update-alternatives: error: no alternatives for xulrunner-javaplugin.so.

update-alternatives: error: no alternatives for firefox-javaplugin.so.

update-alternatives: error: no alternatives for iceape-javaplugin.so.

update-alternatives: error: no alternatives for iceweasel-javaplugin.so.

update-alternatives: error: no alternatives for midbrowser-javaplugin.so.

update-alternatives: error: no alternatives for mozilla-javaplugin.so.

update-alternatives: error: no alternatives for xulrunner-1.9-javaplugin.so.

update-alternatives: error: no alternatives for xulrunner-javaplugin.so.

이것은 안드로이드 소스 컴파일과는 관계없지만 다른 어플을 실행하는데 문제가 될 수도 있기 때문에 아래와 같이 sun-java5-plugin 과 sun-java6-plugin 을 설치해 주자.

 # apt-get install sun-java5-plugin sun-java6-plugin

 

컴파일 하기
이제 컴파일할 환경은 다 갖추어 졌다.
다운받은 안드로이드 소스에는 크로스 컴파일 환경까지 갖추어져 있다.
(안드로이드 소스 다운받는법은 android 소스 다운로드 받기 를 참조하자)
그래서 컴파일을 하기위해서는 "build/envsetup.sh" 파일을 환경등록 해주어야 한다.
다운받은 소스의 루트 디렉토리에서 아래와같이 실행해서 환경등록 해주도록 하자.

 # source build/envsetup.sh

다되었다면 이제 make 를 하면 된다.

 # make

안드로이드 소스는 최초 컴파일시 시간이 무척오래 걸린다.
사실 -j 옵션으로 스레드를 돌려주면 시간을 약간 줄일 수 있다.
그런데 이 옵션은 최초 컴파일시는 왠만해서 사용하지 않는것이 좋다.
왜냐하면 먼저 컴파일 된 것을 참조하는 구문이 있을수도 있는데 그런곳에서 오류가 나서 컴파일이 멈추어 버리는 현상이 나오기 때문이다.
일단 처음에는 느리더라고 그냥 make 를 쓰자.

Posted by cranix