2016년 11월 14일 월요일

Android workspace widget & shortcut 설정하기


  • 용어설명
- workspace: 안드로이드 바탕화면
- workspace의 아이콘은 앱링크인 App shortscut과, workspace에서 동작하는 appwidget으로 나뉜다.
- Hotseat 영역은 화면의 가장아래 가상버튼위 공간으로 통화버튼이 들어간 자리다.

  • 런처 설정 파일
- Launcher2/res/xml-sw600dp/default_workspace.xml : DB생성 초기 값으로 favorite table에 등록된다. 어느 스크린에 어떤 아이콘이 들어갈지 설정할 수 있으며 shortcut은 favorite xml tag로 표시된다.
 30 <!-- Middle screen [2] --> 31 <!--appwidget 32 launcher:packageName="com.android.deskclock" 33 launcher:className="com.android.alarmclock.AnalogAppWidgetProvider" 34 launcher:screen="2" 35 launcher:x="1" 36 launcher:y="0" 37 launcher:spanX="2" 38 launcher:spanY="2" /> 39 <favorite 40 launcher:packageName="com.android.camera" 41 launcher:className="com.android.camera.Camera" 42 launcher:screen="2" 43 launcher:x="0" 44 launcher:y="3" /-->
- Launcher2/res/values-sw600dp/config.xml : Hotseat 자리 개수, workspace rotation 등 설정파일:
- res/xml/dimens.xml : 아이콘 사이즈, 위치 등 설정파일:

  • 데이터 베이스 확인
sqlite3 /data/data/com.android.launcher/databases/launcher.db

sqlite> .table
android_metadata  favorites       

sqlite> select * from favorites;

1|||-100|2|2|3|2|2|4|2||||||||0    << 아날로그시계 앱위젯
3|갤러리|#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.gallery3d/.app.Gallery;end|-100|3|1|3|1|1|0|-1||||||||0
5|설정|#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.settings/.Settings;end|-100|3|2|3|1|1|0|-1||||||||0
7|전화|#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.dialer/.DialtactsActivity;end|-101|1|1|0|1|1|0|-1||||||||0
9|주소록|#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.contacts/.activities.PeopleActivity;end|-101|2|2|0|1|1|0|-1||||||||0
11|메시지|#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.mms/.ui.ConversationList;end|-101|4|4|0|1|1|0|-1||||||||0
13|인터넷|#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.browser/.BrowserActivity;end|-101|5|5|0|1|1|0|-1||||||||0
14|Dev Tools|#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.development/.Development;end|-100|2|3|2|1|1|0|-1||0|||�PNG|||0

sqlite> delete from favorites where  _id=1  
launcher.db의 favorites 테이블의 모든 행을 지우면 google search bar만 남는다.

  • 코드내 favorite DB 생성명령
302             db.execSQL("CREATE TABLE favorites (" +                             
303                     "_id INTEGER PRIMARY KEY," +                                
304                     "title TEXT," +                                             
305                     "intent TEXT," +                                            
306                     "container INTEGER," +                                      
307                     "screen INTEGER," +                                         
308                     "cellX INTEGER," +                                          
309                     "cellY INTEGER," +                                          
310                     "spanX INTEGER," +                                          
311                     "spanY INTEGER," +                                          
312                     "itemType INTEGER," +                                       
313                     "appWidgetId INTEGER NOT NULL DEFAULT -1," +                
314                     "isShortcut INTEGER," +                                     
315                     "iconType INTEGER," +                                       
316                     "iconPackage TEXT," +                                       
317                     "iconResource TEXT," +                                      
318                     "icon BLOB," +                                              
319                     "uri TEXT," +                                               
320                     "displayMode INTEGER," +                                    
321                     "profileId INTEGER DEFAULT " + userSerialNumber +           
322                     ");");



참조:
https://developer.android.com/guide/practices/ui_guidelines/widget_design.html
https://developer.android.com/guide/topics/appwidgets/index.html



2016년 11월 10일 목요일

플래쉬가 없지만 Quick Settings icon에 flashlight를 표시하는 방법

안드로이드 개발보드에 플래쉬가 없긴하지만 Quick Settings에 Flashlight 아이콘이 나오게 하고 싶다.


결론:
Quick settings에 표시하는 아이콘의 리스트는
/data/data/com.android.providers.settings/databases/settings.db의 secure 테이블에서 sysui_qs_tiles컬럼으로 관리된다.
없을경우 R.string.quick_settings_tiles 에서 표시할 리스트를 가져온다. 여기에 필요한 리스트를 추가하면 된다.
확인 결과 quick settings tile list에 기본값으로 flashlight는 포함된다.
하지만 FlashlightController에서 비활성화 플래그로 인해 표시를 하지않는다. 이 값을 강제로 설정하면 표시는 가능하다.

과정:
Flashlight는 카메라 서비스에서 제공되는 기능으로 카메라 API를 통해서 제어를 할 수있다.
Quick settings icon의 경우 SystemUI에서 관리한다.


//SystemUI 설정 (QSTileHost.java 참조)
1) settings.db 업데이트
   adb shell settings get secure sysui_qs_tiles
   adb shell settings put secure sysui_qs_tiles wifi,bt,inversion,cell,airplane,rotation,flashlight,location,cast,hotspot

settings put을 하면 바로 화면에 적용된다.
위 명령에서 설정값이 없으면 R.string.quick_settings_tiles 에서 리스트를 가져온다.

2)SystemUI/res/values/config.xml
 - R.string.quick_settings_tiles
 - R.string.quick_settings_tiles_default
 - quick settings의 행과 열 설정값.
 - 각종 UI 타이밍 설정값

settings.db의 sysui_qs_tiles의 기본값은 flashlight가 포함되어 있는데, 안나온다.
flashlight 타일의 소스를 보면 HAL포팅이 되어있어야 온/오프 표시가 된다는 것을 알수 있다.

* SystemUI 소스확인
소스위치 : android/frameworks/base/packages/SystemUI
Quick settings 소스 위치: SystemUI/src/com/android/systemui/qs
Status Bar의 명칭 : http://minuhome.tistory.com/13

//타이틀 리스트 생성
 ../systemui/statusbar/phone/QSTileHost.java :
 QSTileHost : recreateTiles()
  { final List<String> tileSpecs = loadTileSpecs();
    createTile(titleSpec)); }

//타이틀 리스트에 따라 퀵세팅 인스턴스생성
 QSTileHost : createTile() { else if (tileSpec.equals("flashlight")) return new FlashlightTile(this); }

//플래쉬 라이트 초기화
src/com/android/systemui/qs/tiles/FlashlightTile.java

//플래쉬상태표시
아래 FlsahController가 활성화 되어 있을경우 표시가된다.
강제로 state.visible=true로 하면 퀵세팅패털에서 플래쉬아이콘을 볼 수 있다.:

handleUpdateState()
state.visible = mWasLastOn != 0 || mFlashlightController.isAvailable();

//개발보드 HAL 로깅메시지
10-06 04:08:22.790 2468-2468/? D/ExynosCameraParameters: [CAM_ID(1)][ParametersFront]-DEBUG(setParameters):strNewFlashMode off


*플래쉬 HAL
각 보드별 특성 설정: android/device/company/products
컴파일 결과물: android/out

HAL Module : out/target/product/mv7420/obj/lib/*.so
HAL Module은 커널의 장치를 제어하는 인터페이스 라이브러리이다.
아래 링크정보를 보고 어떤파일이 컴파일되는 지 확인해 볼수 있다.
HAL Module link 정보:
out/target/product/mv7420/obj/SHARED_LIBRARIES/module_namexxx_intermediates/module_namexxx.P


백라이트 HAL:
Nexus: android/device/lge/liblight
HTC: android/device/htc/flounder/lights
mv7420: device/samsung/smdk_common/liblight/lights.c
센서 HAL
Nexus: android/device/lge/libsensor
HTC: android/device/htc/flounder/sensor_hub/libsensors
mv7420: vendor/invensense/libsensors_HAL_1_1/sensors_mpl.cpp

오디오 HAL
       android/device/samsung/mv7420/audio

카메라 HAL
  libexynoscamera.so  : hardware/samsung_slsi/exynos7420/libcamera/ExynosCameraSensorInfo.cpp
        libcamera_client.so : frameworks/av/camera/*.c
libcamera_metadata.so : system/media/camera/src/*.c
        libcameraservice.so : frameworks/av/services/camera/libcameraservice/*.cpp


1. 카메라 매니져 접근:
 SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java :
 mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
2. 카메라 장치 오픈
 SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java :
 mCameraManager.openCamera(getCameraId(), mCameraListener, mHandler);:0:
3. 플래시 명령 전달
 builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH);




*특정 태크 로깅 설정

Dalvik property 설정:setprop log.tag.<your_log_tag> <level>

$ ./adb shell stop
$ ./adb shell setprop log.tag.QSTileHost DEBUG
$ ./adb shell setprop log.tag.FlashlightController DEBUG
$ ./adb shell start



*파워버튼 두번 누르면 카메라켜기
android/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java

powerMultiPressAction(..) {
 ...
 case MULTI_PRESS_POWER_LAUNCH_CAMERA:
    Slog.i(TAG, "Launching camera by power button.");
    if (!mCameraLensCoverState != CAMERA_LENS_COVERED) {
        if (!interactive) {
            wakeUpFromPowerKey(eventTime);
        }
        launchCamera();
    }
    break;
...
}