More Related Content Similar to Pf部2012年1月勉強会.androidsola Similar to Pf部2012年1月勉強会.androidsola (20) Pf部2012年1月勉強会.androidsola2. 自己紹介
●
twitter : @androidsola
G+ : http://gplus.to/sola
blog : http://blog.sola-dolphin-1.net/
3. 本日の内容
●
カスタム ROM を作り始めた理由
●
これまでに変更した内容
●
今後
●
カスタム ROM の作り方(※自分のやり方)
10. SC-04D からの変更点
● Android を 4.0.1 から 4.0.3 に変更
● kernel を 3.0.1 から 3.0.8 に変更+クロック変更
● software navigation bar に menu キーを設置
● ロックスクリーンでマナーモード切替出来るように変更
● カメラのシャッター音を変更
● 再起動メニューの追加
● Tablet 用の UI に切り替える機能の追加
11. Android を 4.0.1 から 4.0.3 に変更
● SC-04D には(現時点で)バージョンアップが来ないので、
自分で上げた。( 4.0.1 は黒歴史バージョンだし ... )
12. Android を 4.0.1 から 4.0.3 に変更
● manifest を 4.0.1_r1 から 4.0.3_r1 に変更
変更前
repo init -u
https://android.googlesource.com/platform/ma
nifest -b android-4.0.1_r1
変更後
repo init -u
https://android.googlesource.com/platform/ma
nifest -b android-4.0.3_r1
13. Android を 4.0.1 から 4.0.3 に変更
● Graphics のライブラリを 4.0.3 用のものに変更する
Binaries for Galaxy Nexus
http://code.google.com/intl/ja/android/nexus/
drivers.html
14. kernel を 3.0.1 から 3.0.8 に変更
● Graphics のライブラリに合わせて、更新
ドライバとライブラリの組み合わせが悪いと起動しない。
表示を出そうとする辺りで、落ちる。
→ リブートを繰り返して、起動しない端末になる。
これは、 PandaBoard でも同じ。
16. software navigation bar に
menu キーを設置
● navigation bar 用のレイアウトファイルを変更する
標準のレイアウト
左から、
40dp 、 80dp 、 80dp 、 80dp 、 40dp (合計 320dp )
となっている。
17. software navigation bar に
menu キーを設置
● navigation bar 用のレイアウトファイルを変更する
改造後のレイアウト
左から、
80dp 、 80dp 、 80dp 、 80dp (合計 320dp )
にした。
右端の menu を出す部分は要らないので潰した。
18. software navigation bar に
menu キーを設置
● navigation bar 用のレイアウトファイルを変更する
frameworks/base/packages/SystemUI/res/layout/navigation_bar.xml
追加した menu キーの部分
+ <com.android.systemui.statusbar.policy.KeyButtonView
android:id="@+id/mymenu"
+ android:layout_width="80dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_menu"
+ systemui:keyCode="82"
+ android:layout_weight="0"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:contentDescription="@string/accessibility_menu"
+ />
横向きにした時の部分も忘れずに変更する。
19. software navigation bar に
menu キーを設置
● 右端の menu キーが出ないようにする
frameworks/base/packages/SystemUI/src/com/android/systemui/statusba
r/phone/NavigationBarView.java
以下 2 つのメソッドを空に変更
public void setMenuVisibility(final boolean show)
public void setMenuVisibility(final boolean show, final boolean
force)
以下のメソッドに menu キー用の処理を追加
public void setDisabledFlags(int disabledFlags, boolean force)
他の home や back キー同様の処理を入れただけ。
(たぶん) navigation bar が消えてる時に無効にしてる。
20. software navigation bar に
menu キーを設置
● 補足)キーイベントの種類
frameworks/base/core/java/android/view/KeyEvent.java
約 200 個のキーイベントが存在する。
ソース( navigation_bar.xml )を変更すれば、
自分好みにキーイベントを割り当てる事が出来る。
22. ロックスクリーンで
マナーモード切替出来るように変更
● sound on の状態のサークルを作る
frameworks/base/core/res/res/values/arrays.xml
<array name="lockscreen_targets_with_camera">
<item>@drawable/ic_lockscreen_unlock</item>
- <item>@null</item>
+ <item>@drawable/ic_lockscreen_soundon</item>
<item>@drawable/ic_lockscreen_camera</item>
<item>@null</item>
</array>
23. ロックスクリーンで
マナーモード切替出来るように変更
● sound off の状態のサークルを作る
frameworks/base/core/res/res/values/arrays.xml
+ <array name="lockscreen_targets_with_camera_silent">
+ <item>@drawable/ic_lockscreen_unlock</item>
+ <item>@drawable/ic_lockscreen_silent</item>
+ <item>@drawable/ic_lockscreen_camera</item>
<item>@null</item>
+ </array>
24. ● 追加した sound on/off の状態のサークルを出す( 1 )
frameworks/base/policy/src/com/android/internal/policy/impl/LockScreen
.java
public void updateResources() {
int resId;
if (mCameraDisabled) {
// Fall back to showing ring/silence if camera is disabled by
DPM...
resId = mSilentMode ? R.array.lockscreen_targets_when_silent
: R.array.lockscreen_targets_when_soundon;
} else {
- resId = R.array.lockscreen_targets_with_camera;
+ resId = mSilentMode ? R.array.lockscreen_targets_with_camera
+ : R.array.lockscreen_targets_with_camera_silent;
+
}
mMultiWaveView.setTargetResources(resId);
}
25. ● 追加した sound on/off の状態のサークルを出す( 2 )
frameworks/base/policy/src/com/android/internal/policy/impl/LockScreen
.java
public void onTrigger(View v, int target) {
- if (target == 0 || target == 1) {
+ if (target == 0) {
mCallback.goToUnlockScreen();
- } else if (target == 2 || target == 3) {
+ } else if (target == 1) {
+ toggleRingMode();
+ mUnlockWidgetMethods.updateResources();
+ mCallback.pokeWakelock();
+ } else if (target == 2 || target == 3) {
if (!mCameraDisabled) {
// Start the Camera
Intent intent = new
Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
26. カメラのシャッター音を変更
● シャッター音とフォーカス時の音
frameworks/base/data/sounds/effects/camera_click.ogg
frameworks/base/data/sounds/effects/ogg/camera_click.ogg
frameworks/base/data/sounds/effects/ogg/camera_focus.ogg
28. Tablet 用の UI に切り替える機能の追加
● Galaxy Nexus 単体で Tablet の UI も使えるようにした
同じイメージで切替可能
※再起動は必要
31. Tablet/Phone 統合
● Tablet と Phone の UI が統合されており、
以下の処理で区別している。
frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUI
Service.java
public void onCreate() {
// Pick status bar or system bar.
IWindowManager wm = IWindowManager.Stub.asInterface(
ServiceManager.getService(Context.WINDOW_SERVICE));
try {
SERVICES[0] = wm.canStatusBarHide() Phone 向け
? R.string.config_statusBarComponent
: R.string.config_systemBarComponent;
} catch... Tablet 向け
32. Tablet/Phone 統合
● wm.canStatusBarHide() が返す true/false を
決めている場所
frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWi
ndowManager.java
int shortSizeDp = shortSize
* DisplayMetrics.DENSITY_DEFAULT
/ DisplayMetrics.DENSITY_DEVICE;
mStatusBarCanHide = shortSizeDp < 600;
mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
mStatusBarCanHide
? com.android.internal.R.dimen.status_bar_height
: com.android.internal.R.dimen.system_bar_height);
33. Tablet/Phone 統合
● Galaxy Nexus での計算式
int shortSizeDp = shortSize
* DisplayMetrics.DENSITY_DEFAULT
/ DisplayMetrics.DENSITY_DEVICE;
mStatusBarCanHide = shortSizeDp < 600;
int shortSizeDp = 720 (縦横の小さい方の解像度)
* 160
/ 320; ( ro.sf.lcd_density の値)
mStatusBarCanHide = 360 < 600;
34. Tablet/Phone 統合
● 解像度 800×480 なタブレットの場合の例
int shortSizeDp = shortSize
* DisplayMetrics.DENSITY_DEFAULT
/ DisplayMetrics.DENSITY_DEVICE;
mStatusBarCanHide = shortSizeDp < 600;
int shortSizeDp = 480 (縦横の小さい方の解像度)
* 160
/ 120; ( ro.sf.lcd_density の値)
mStatusBarCanHide = 640 < 600;
35. Tablet 用の UI に切り替える機能の追加
● 最初に思い付いた方法
/system/build.prop を書き換えて再起動する
Phone UI の時は ro.sf.lcd_density=320
Tablet UI の時は ro.sf.lcd_density=160
→root 権限が必要なのと、めんどくさいのでボツ
36. Tablet 用の UI に切り替える機能の追加
● 次に思い付いた方法
Phone UI 用と Tablet UI 用の system.img を作成
必要な時に書き換える
→ これもめんどくさい
37. Tablet 用の UI に切り替える機能の追加
● 最終的に思い付いた方法
開発者向けオプションで、
ON/OFF 選択して再起動
→root 権限も書き換えの手間もない。
再起動の約 30 秒待つだけ。
38. Tablet 用の UI に切り替える機能の追加
● UI 切り替えの仕組み
persist.sys.force.tablet の値で切り替え
true : Tablet UI 、 true 以外: Phone UI
開発者向けオプションの
Tablet UI を使用にチェックを入れると、 true になる。
→ 設定アプリにこの機能を入れる。
39. Tablet 用の UI に切り替える機能の追加
● ro.sf.lcd_density を参照してるところ( 1 )
frameworks/base/services/surfaceflinger/DisplayHardware/DisplayHardwa
re.cpp
void DisplayHardware::init(uint32_t dpy) の抜粋
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);
40. Tablet 用の UI に切り替える機能の追加
● ro.sf.lcd_density を参照してるところ( 1 )を乗っ取る
frameworks/base/services/surfaceflinger/DisplayHardware/DisplayHardwa
re.cpp
void DisplayHardware::init(uint32_t dpy) の抜粋
mDensity = atoi(property) * (1.0f/160.0f);
+if (property_get("persist.sys.force.tablet", property, NULL) > 0) {
+ if (strcmp(property, "true") == 0) {
+ strcpy(property, "160");
+ mDensity = atoi(property) * (1.0f/160.0f);
+ }
+}
41. Tablet 用の UI に切り替える機能の追加
● ro.sf.lcd_density を参照してるところ( 2 )
frameworks/base/core/java/android/util/DisplayMetrics.java
private static int getDeviceDensity() {
return SystemProperties.getInt("qemu.sf.lcd_density",
SystemProperties.getInt("ro.sf.lcd_density",
DENSITY_DEFAULT));
}
42. Tablet 用の UI に切り替える機能の追加
● ro.sf.lcd_density を参照してるところ( 2 )を乗っ取る
frameworks/base/core/java/android/util/DisplayMetrics.java
private static int getDeviceDensity() {
+ String forceTablet =
SystemProperties.get("persist.sys.force.tablet");
+ if (! "".equals(forceTablet)) {
+ if (forceTablet.equals("true")) {
+ return DENSITY_DEFAULT;
+ }
+ }
return SystemProperties.getInt("qemu.sf.lcd_density",
SystemProperties.getInt("ro.sf.lcd_density",
DENSITY_DEFAULT));
}
43. Tablet 用の UI に切り替える機能の追加
● 以上の変更で Tablet UI にしたところ、問題発生
Tablet の UI になって起動するが、
SystemUI が落ちる ...orz
44. Tablet 用の UI に切り替える機能の追加
● 原因は software navigation bar
software navigation bar は Tablet の UI で
出してはいけないらしい。
Tablet の UI は独自に持ってるためか?
47. software navigation bar
● 表示させるには以下の変更が必要
frameworks/base/core/res/res/values/config.xml
初期値
<bool name="config_showNavigationBar">false</bool>
表示させるために変更した後
<bool name="config_showNavigationBar">true</bool>
● Emulator で試す場合
qemu.hw.mainkeys が 1 に設定されて、
config_showNavigetionBar の値が false に変更される。
emulator で試す場合は 0 に設定する。
48. Tablet 用の UI に切り替える機能の追加
● config_showNavigationBar の値を上書きする
frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWind
owManager.java
config_showNavigationBar を参照してるところの後に追加する。
+ String forceTablet =
SystemProperties.get("persist.sys.force.tablet");
+ if (! "".equals(forceTablet)) {
+ if (forceTablet.equals("true")) mHasNavigationBar = false;
+ else if (forceTablet.equals("false")) mHasNavigationBar = true;
+ }
50. 今後の予定
●
カスタム ROM を公開
1.Galaxy Nexus SC-04D に特化したもの
→ 今まで通り、ソースからビルドして作成
2.Factory Image ベースで作成したもの
→SC-04D が無くてもビルド可能にするためのもの
3.AOSP + gapps の組み合わせで作成したもの
→ よくあるカスタム ROM の配布と同じ形式
51. ソースコードの公開場所
●
bitbucket
https://bitbucket.org/sola
fork してどんどん改良して欲しいです。
(改良したものは公開して欲しい)