ザウルスをアンドロイドにしてあげる
本館 Android Zaurus
2012-01-30 んふんふ。コンプリート。
Transformer Primeで有線LAN
dmesgを見ていたらUSB Hostモジュールとして
<6>[ 8.162292] usbcore: registered new interface driver asix
が登録されていた。USBイーサの石。ということで、ビックカメラで下記を購入。
BUFFALO 10/100M USB2.0用 LANアダプタ (Wii&MacBookAir対応) LUA3-U2-ATX
- 出版社/メーカー: バッファロー
- 発売日: 2009/08/01
- メディア: Personal Computers
- 購入: 29人 クリック: 120回
- この商品を含むブログ (14件) を見る
早速、家に帰ってつないでみたら、dmesgに
<6>[ 100.845783] tegra_usb_resume+ <6>[ 100.889849] tegra_usb_resume- <6>[ 101.181095] usb 1-1.2: new high speed USB device using tegra-ehci and address 3 <6>[ 101.241086] usb 1-1.2: New USB device found, idVendor=0b95, idProduct=7720 <6>[ 101.242163] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3 <6>[ 101.242764] usb 1-1.2: Product: AX88772 <6>[ 101.243787] usb 1-1.2: Manufacturer: ASIX Elec. Corp. <6>[ 101.244357] usb 1-1.2: SerialNumber: 556D27 <6>[ 102.133280] asix 1-1.2:1.0: eth0: register 'asix' at usb-tegra-ehci.2-1.2, ASIX AX88772 USB 2.0 Ethernet, 4c:e6:76:xx:xx:xx <6>[ 102.184767] eth0: link down <6>[ 102.190679] ADDRCONF(NETDEV_UP): eth0: link is not ready <6>[ 103.795184] ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready <6>[ 103.807939] eth0: link up, 100Mbps, full-duplex, lpa 0xC5E1
logcatに
D/ConnectivityService( 177): ConnectivityChange for ETHERNET: CONNECTED/CONNECTED D/ConnectivityService( 177): Setting TCP values: [4095,87380,110208,4096,16384,110208] which comes from [net.tcp.buffersize.wifi] D/ConnectivityService( 177): adding dns /192.168.62.200 for ETHERNET D/ConnectivityService( 177): adding dns /8.8.8.8 for ETHERNET D/ConnectivityService( 177): changing default proxy to D/ConnectivityService( 177): sending Proxy Broadcast for D/ConnectivityService( 177): addDefaultRoute for ETHERNET (eth0), GatewayAddr=192.168.62.200 D/Tethering( 177): Tethering got CONNECTIVITY_ACTION D/Tethering( 177): MasterInitialState.processMessage what=3 V/TweetDeck( 771): ETHERNET CONNECTION UP I/MediaUploader( 820): No need to wake up D/GTalkService( 352): [ReonnectMgr] ### report Inet condition: status=false, networkType=9 I/ActivityManager( 177): Start proc com.asus.cm for broadcast com.asus.cm/.push.PushControlReceiver: pid=950 uid=1000 gids={3003, 1015, 3002, 3001} D/ConnectivityService( 177): reportNetworkCondition(9, 0) D/ConnectivityService( 177): Inet connectivity change, net=9, condition=0,mActiveDefaultNetwork=9 D/ConnectivityService( 177): starting a change hold D/GTalkService( 352): [RawStanzaProvidersMgr] ##### searchProvidersFromIntent D/CMC->CMConfig( 950): DMConfig.init() D/CMC->CMConfig( 950): mFumoHandlerName=DefaultFumoHandler D/GTalkService( 352): [ReonnectMgr] ### report Inet condition: status=false, networkType=9 D/ConnectivityService( 177): reportNetworkCondition(9, 0) D/ConnectivityService( 177): Inet connectivity change, net=9, condition=0,mActiveDefaultNetwork=9 D/ConnectivityService( 177): currently in hold - not setting new end evt
netcfgの結果は
$ netcfg lo UP 127.0.0.1/8 0x00000049 00:00:00:00:00:00 dummy0 DOWN 0.0.0.0/0 0x00000082 aa:02:9a:xx:xx:xx usb0 DOWN 0.0.0.0/0 0x00001002 62:80:3d:xx:xx:xx sit0 DOWN 0.0.0.0/0 0x00000080 00:00:00:00:00:00 ip6tnl0 DOWN 0.0.0.0/0 0x00000080 00:00:00:00:00:00 wlan0 UP 0.0.0.0/0 0x00001003 c8:60:00:xx:xx:xx eth0 UP 192.168.62.3/24 0x00001043 4c:e6:76:xx:xx:xx
ブラウザやマーケットも有線LAN経由でアクセス出来る。ConnectivityManagerに手を入れないと、マーケットは「ネットワークの回復を待っています」というダイアログが出て使えないと思っていたのだが、いつの間にか TYPE_ETHERNET としてイーサネットのサポートが入っていた。 ConnectivityManager.TYPE_ETHERNET のようなフレームワークで使用されている。ethデバイスが追加されるとDHCPなどの面倒を見てくれるようだ。root権限は不要。
有線LANでも使えると嬉しい人も中には居るのではなかろうか。ただし、 ro.sercure=1 かつ ro.debuggable=0 なので、充電しつつLAN経由でのadb接続は残念ながら出来ない。またTetheringデバイスからeth0が除外されているので、簡易WiFiルータとしても使えない。
モジュールがカーネルにスタティックリンクされているせいか、一度接続してからUSBアダプタを抜いて再接続すると、リブートするまでイーサネットに接続できなくなる。
2012-01-27 んふんふ。96%からなかなか進まない。
Transformer Primeのマルチコアとクロック
ASUS タブレットパソコン Eee Pad TF201 TF201-GD64D
- 出版社/メーカー: Asus
- メディア: エレクトロニクス
- クリック: 16回
- この商品を含むブログ (1件) を見る
Tegra 3初物ということで、発売日に購入。とある勉強会でUstream用に購入当日にまさかの実戦投入。勉強会を始めてから2時間程して、電源つないでいるのになぜか電池がきれそうになり、よく見たらちゃんとタブレットとキーボードが接続されていなかった。というか、タブレット側の電池だけで2時間もUstream出来たのが驚き。
4コアということで、コアがどんなクロックで推移するのか気になったので、CPUクロックを3秒ごとにprintfするCプログラムを書いて眺めてみた。そのまとめ。
- GovernorはInteractive
- 設定可能なクロックは102MHzから1.4GHz
- 102 204 370 475 620 760 880 1000 1100 1200 1300 1400
- 1.2GHzまでしか使わない
- /system/etc/normalmode.shで
echo 1 > /sys/module/cpu_tegra/parameters/system_mode echo 1200 > /sys/kernel/tegra_cap/core_cap_levelこれが効いているらしく、ログに
V/NvPowerMgr( 416): setPowerState(): scaling, capLevel, capState, userCap, aggressiveness = 1, 1200, 1, 1200000, 29
- turbomode.shを使うとスペック通りに、1コア時Max 1.4GHz、マルチコア時Max 1.3GHzで動作する
- アプリケーションによるマルチコア利用
- ホーム画面のスワイプは2コアを1.2GHzで回す高負荷処理
- 思ったより重い処理なのでむやみにぶいんぶいんすると電池持ちに影響するかも
- Grow Ballは4コア全開
- Rip Tideは3コアしか使わない
- 通常処理に2コア。水滴などのTegra 3追加効果の処理に1コア。
- twiccaは更新時に3コアまで全力で使う
- 他のアプリはほとんど2コアの全力で収まってしまう
- コンカレントGCに別コアを起こすような挙動は見られない
- ホーム画面のスワイプは2コアを1.2GHzで回す高負荷処理
- 1.2GHz x 2 -> 760MHz x 2 -> 1.2GHz x 1 -> 600MHz x 1のような推移
- 負荷に応じてコア数とクロックをうまく調整してくれている
- sleepで寝ないv8
- ブラウザでGoogle Newsを開いた状態でsleepすると204, 370, 620をうろうろする
- すべてのアプリを閉じてホームに戻ってからsleepすると、102MHz
- PC版Googleホームでも同様にsleepしてもCPUクロックが落ちない。v8が寝ない。
- PC版Googleホームはsleepしなくても370, 620, 880, 1200をうろうろする
- PC版iGoogleも
- Mobile版は102MHzに落ち着く。
どうもsleepしても、ブラウザがActive状態だとv8は寝ないようなので、sleepするときはブラウザを閉じてからの方が、電池持ちがよくなりそう。これは他のAndroid端末に共通なのかもしれない。
2012-01-13
Android Security読書感想文
Android Security 安全なアプリケーションを作成するために
- 作者: タオソフトウェア株式会社
- 出版社/メーカー: インプレスジャパン
- 発売日: 2011/12/29
- メディア: 大型本
- 購入: 4人 クリック: 89回
- この商品を含むブログ (2件) を見る
タオソフトウェアさん*1が執筆されて、インプレスさん*2から出版されている「Android Security」を、なぜか献本頂いた。ありがとうございました。
こんな人は是非読むべきだと思う。
- Androidアプリケーションを受託開発している
- Androidアプリケーションを外注しようとしている
- Androidアプリケーションを開発しているが、セキュリティについては考えたこともない
- 普通のAndroidユーザだが、パーミッションの意味をあまりよく分かっていない
開発者だけでなく、普通のAndroidユーザに薦めたいのは、P.117からの「6.5 疑われやすいパーミッションの組み合わせ」だ。立ち読みでもいいから一度目を通してもらいたい。あまりAndroidアプリが危険が危ないと煽るつもりはないが、どういう危険性があるかというのは認識しておくべきだと思う。
それにしても、READ_PHONE_STATEを要求するアプリ大杉だろ。
2012-01-11
Levels in Renderscript(超訳)
Levels in RenderscriptというRenderscriptを解説した記事が本家に上がったので、久々に超訳。誤訳などあればご指摘を。
ICSではRenderscript(RS)がアップデートされた。いくつかの新しい機能が加えられ、アプリケーションで計算を簡単に高速化出来るようになっている。大量の処理が必要な大きなデータバッファがある場合、計算の高速化のためにRSは興味深い。この例ではレベル/サチュレーション処理をビットマップに施してみる。
この場合、サチュレーションはすべてのピクセルと色行列のかけ算として実装され、レベルはいくつかの演算で実装されるのが常套だ。
1. 入力レベルの調整
2. ガンマ補正
3. 出力レベルの調整
4. 有効値へのクランプ
単純な実装はこのようになる。
for (int i=0; i < mInPixels.length; i++) {
float r = (float)(mInPixels[i] & 0xff);
float g = (float)((mInPixels[i] >> 8) & 0xff);
float b = (float)((mInPixels[i] >> 16) & 0xff);
float tr = r * m[0] + g * m[3] + b * m[6];
float tg = r * m[1] + g * m[4] + b * m[7];
float tb = r * m[2] + g * m[5] + b * m[8];
r = tr;
g = tg;
b = tb;
if (r < 0.f) r = 0.f;
if (r > 255.f) r = 255.f;
if (g < 0.f) g = 0.f;
if (g > 255.f) g = 255.f;
if (b < 0.f) b = 0.f;
if (b > 255.f) b = 255.f;
r = (r - mInBlack) * mOverInWMinInB;
g = (g - mInBlack) * mOverInWMinInB;
b = (b - mInBlack) * mOverInWMinInB;
if (mGamma != 1.0f) {
r = (float)java.lang.Math.pow(r, mGamma);
g = (float)java.lang.Math.pow(g, mGamma);
b = (float)java.lang.Math.pow(b, mGamma);
}
r = (r * mOutWMinOutB) + mOutBlack;
g = (g * mOutWMinOutB) + mOutBlack;
b = (b * mOutWMinOutB) + mOutBlack;
if (r < 0.f) r = 0.f;
if (r > 255.f) r = 255.f;
if (g < 0.f) g = 0.f;
if (g > 255.f) g = 255.f;
if (b < 0.f) b = 0.f;
if (b > 255.f) b = 255.f;
mOutPixels[i] = ((int)r) + (((int)g) << 8) + (((int)b) << 16)
+ (mInPixels[i] & 0xff000000);
}
このコードはビットマップがすでにロードされていて、処理のために整数配列に移されていることを想定している。ビットマップはすでにロードされているので、これは簡単だ。
mInPixels = new int[mBitmapIn.getHeight() * mBitmapIn.getWidth()];
mOutPixels = new int[mBitmapOut.getHeight() * mBitmapOut.getWidth()];
mBitmapIn.getPixels(mInPixels, 0, mBitmapIn.getWidth(), 0, 0,
mBitmapIn.getWidth(), mBitmapIn.getHeight());
データ処理のループが終われば、描画のためにビットマップに戻すことも簡単だ。
mBitmapOut.setPixels(mOutPixels, 0, mBitmapOut.getWidth(), 0, 0,
mBitmapOut.getWidth(), mBitmapOut.getHeight());
フィルター本体の定数計算や、(ボタンなどの)コントロールの制御、画像表示などのコードを含めて、アプリケーション全体のコード量は232行程度になる。手元の実機では800x423の画像処理におおよそ140-180msecかかる。
もしこれで十分でなかったらどうする?
画像処理のコア部分をRSに移植するのはとても簡単だ。上記のピクセル処理本体をRSで実装しなおすとこうなる。コードはhttp://code.google.com/p/android-renderscript-samples/source/browse/Levelsにある。
void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
float3 pixel = convert_float4(in[0]).rgb; // 3要素ベクトル
pixel = rsMatrixMultiply(&colorMat, pixel); // ライブラリ関数
pixel = clamp(pixel, 0.f, 255.f); // ライブラリ関数
pixel = (pixel - inBlack) * overInWMinInB; // ベクトル演算
if (gamma != 1.0f)
pixel = pow(pixel, (float3)gamma); // ライブラリ関数
pixel = pixel * outWMinOutB + outBlack; // ベクトル演算
pixel = clamp(pixel, 0.f, 255.f); // ライブラリ関数
out->xyz = convert_uchar3(pixel); // ライブラリ関数
}
コード行数が極端に少なくて済むのは、浮動小数点のベクトルや行列演算、フォーマット変換があらかじめ組み込まれているからだ。また、ループが存在しないことに着目して欲しい。
準備のためのコードは、スクリプトをロードする必要があるので、ほんの少し複雑になる。
mRS = RenderScript.create(this);
mInPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
Allocation.MipmapControl.MIPMAP_NONE,
Allocation.USAGE_SCRIPT);
mOutPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapOut,
Allocation.MipmapControl.MIPMAP_NONE,
Allocation.USAGE_SCRIPT);
mScript = new ScriptC_levels(mRS, getResources(), R.raw.levels);
このコードはRSのコンテキストを生成している。続いて、2つのメモリアロケーションをこのコンテキストを使って生成し、ビットマップデータのRS用コピーを保持する。最後にデータ処理のためにスクリプトをロードする。
ソースコードには、他にもいくつか小さなコードの塊があり、定数に変更があった時に計算し直してスクリプトへコピーしている。グローバル変数はスクリプトからリフレクションされているので、簡単に行える。
mScript.set_inBlack(mInBlack);
mScript.set_outBlack(mOutBlack);
mScript.set_inWMinInB(mInWMinInB);
mScript.set_outWMinOutB(mOutWMinOutB);
mScript.set_overInWMinInB(mOverInWMinInB);
先に述べたように、すべてのピクセルを処理するためのループがない。ビットマップデータを処理し、結果をコピーするRSコードはこうなる。
mScript.forEach_root(mInPixelsAllocation, mOutPixelsAllocation);
mOutPixelsAllocation.copyTo(mBitmapOut);
最初の行はスクリプトと入力アロケーションを取り出して、結果を保持する出力アロケーションを設定している。たったこれだけで、ネイティブにコンパイルされたバージョンのスクリプトを、アロケーションに入っているすべてのピクセルに対して、1つづつ一度だけ呼び出す。しかし、Dalvikの実装とは異なり、プリミティブ(コンパイルされたスクリプト)は自動的に複数のスレッドを生成して処理を行う。ネイティブコードの効率と合わさることで、大きなパフォーマンス向上を生んでいる。ガンマ関数のありなしで計算コストが大きく異なるので、両方の結果を下に示す。
800x423の画像
| Device | Dalvik | RS | Gain |
| Xoom | 174ms | 39ms | 4.5x |
| Galaxy Nexus | 139ms | 30ms | 4.6x |
| Tegra 30 device | 136ms | 19ms | 7.2x |
ガンマ補正を加えた場合の800x423の画像
| Device | Dalvik | RS | Gain |
| Xoom | 994ms | 259ms | 3.8x |
| Galaxy Nexus | 787ms | 213ms | 3.7x |
| Tegra 30 device | 783ms | 104ms | 7.5x |
ゲインが大きいほど、簡単なコーディングで得られる見返りが大きいことを示す。
訳注: Xoom, GN, Tegra 3というのは理にかなった選択。
Xoom: 2コア、VFP3
GN: 2コア、NEON
Tegra 3: 4コア、NEON
Tegra 30というのは、単なる記憶違いもしくはTegra 3が正式名称になるまえに30と呼び習わしていたのかもしれない。
2011-09-12 Top Favorites枠ありがとうございました。
DevQuiz 2011 - Go
解答晒し。誰が書いても似た様になるだろうけど。
1つだけ疑問。オリジナルのCountColorの引数がpngになっていたけど、image/pngをimportした時に、名前が衝突してpng.Decode()が呼び出せない。io.Readerの変数名がpngというのも気持ち悪いのでsrcに変更したけど、本当はどうすべきだったのか*1。
package main
import (
"fmt"
"io"
"strings"
"image"
"image/png"
/* add more */
)
func rgbaToInt(s image.Color) uint32 {
r, g, b, a := s.RGBA()
i32 := r + g<<8 + b<<16 + a<<24
return i32
}
func CountColor(src io.Reader) int {
hash := make(map[uint32] int)
dec, e := png.Decode(src)
if e != nil {
fmt.Println(e)
return -1
}
for y := dec.Bounds().Min.Y; y < dec.Bounds().Max.Y; y++ {
for x := dec.Bounds().Min.X; x < dec.Bounds().Max.X; x++ {
color := dec.At(x, y)
if hash[rgbaToInt(color)] != 1 {
hash[rgbaToInt(color)] = 1
}
}
}
return len(hash)
}
/* これらの関数は提出時に自動挿入されます。 */
func main() {
png := GetPngBinary()
cnt := CountColor(png)
fmt.Println(cnt)
}
DevQuiz 2011 - 一人ゲーム
解答晒し。やや長いのでpatebin。
- まず、ロボット的に最短に近い手数を出す。(ruledengine)
- 奇数かつ5で割り切れる数が1以上なら、取り除く(evalremove5)
- それ以外は半分
- 繰り返せば最短に近い手数が出そう
- ロボットが出した手数まで全探索(walkaroundengine)
- 単純な2分木探索
- 取り除かれた数字には-1をいれておくことで、配列のコピーを避ける
DevQuiz 2011 - スライドパズル
解答晒し。やや長いのでpatebin。
- 単純なA*(のハズ)
- 16個プロセスを立ち上げて分散
- mod16番目の問題をそれぞれが対応
- 1プロセスあたり100MB程度のメモリ消費
- キュー済みかどうかの判定がstrcmp
- ハッシュ関数が思いつかなかった
- 正解文字列生成にsort
- bubble sortを実装
- しかし、100問しか解けなかった
- 参考になりません
C言語だと再発明する車輪が多すぎです。
*1:@adakoda 情報: importでPNG "image/png"とするとエイリアスがつけられる。
dsk
2011/09/22 15:30
import imgpng "image/png"ならimgpng.Decode()で衝突しません。