monkeyツールの乱数シード

昨日のデ部Ustを見ていて、monkeyツールのrandom seedについて議論があったので、Monkey.java*1を調べてみた。

  • verbose levelが1以上の時、Seedをlogに吐く。
  • verbose levelは-vオプションの数に等しい。
    • monkey -v -v -vでverbos level 3。
  • monkey -sでSeedを指定しない場合のデフォルト値は-1。
  • mRandomインスタンスは--randomize-throttleなどを指定した場合にも使い回されるので、再現性を求めるなら、指定するオプションも完全一致させる必要がある。


これ、デフォルト値-1が設定されるので、seedを与えなくても、生成される乱数列は毎回同じになるんじゃね?


こんなコードをHello Worldに埋め込んでエミュレータで実験してみた。

    SecureRandom sr = new SecureRandom();
    sr.setSeed(-1);
    for (int i=0 ; i<4 ; i++) {
      long l = sr.nextLong();
      System.out.println(l);
    }


1回目。

I/System.out( 413): -5016930203193634067
I/System.out( 413): -3643974259573985036
I/System.out( 413): 5907839790866025284
I/System.out( 413): 6981625101179673431


2回目。PIDが異なるので、プロセスは新規に生成されているはず。

I/System.out( 527): -5016930203193634067
I/System.out( 527): -3643974259573985036
I/System.out( 527): 5907839790866025284
I/System.out( 527): 6981625101179673431


3回目。エミュレータを再起動してみた。

I/System.out( 349): -5016930203193634067
I/System.out( 349): -3643974259573985036
I/System.out( 349): 5907839790866025284
I/System.out( 349): 6981625101179673431


まったく同じ結果
に。


setSeed(-1)をコメントアウトして実験。


1回目。

I/System.out( 414): 6822932661241022103
I/System.out( 414): 5358746818087779010
I/System.out( 414): -4362015058690887859
I/System.out( 414): 4871243452630524967


2回目。連続して実行。PIDは同じで、Life Cycleだけ回ってる。

I/System.out( 414): -5304354331753208905
I/System.out( 414): 2147412941124701195
I/System.out( 414): 7510597109857331964
I/System.out( 414): 2967048142811875505


3回目。PIDが違うので新規プロセス。

I/System.out( 457): 6055662423267597421
I/System.out( 457): 739041615359471551
I/System.out( 457): 7143595282741928130
I/System.out( 457): -1476730436998667919


しっかり乱数になっているようだ。


結論。

  • monkeyで再現性を意図したseedの設定は不要。
  • というか、monkeyで常にランダムな挙動を意図するなら、seedを指定しない場合にsetSeed(-1)するコードは間違っているんじゃ?


Monkey.javaの543行目。

        mRandom.setSeed((mSeed == 0) ? -1 : mSeed);

        if (mSeed != 0)
            mRandom.setSeed(mSeed);

であるべきじゃないかな。

Google+のInstant Uploadについてのよくある誤解

AndroidアプリのInstant Uploadを有効にした場合にアップロードされるPicassaのアルバムはプライベートな専用のアルバムになる。自動的に公開されるわけではない。



また、Picassaの1GB無料クォータのルールに変更が加えられていて、

  • 長辺が2048px以下の画像
  • 15分以内の動画

に関しては無料になる。*1したがって、1GBクォータを浪費するわけではない。ただし、私がテストした写真では長辺2048pxになっていたが、一応テストをしてみることを推奨します。


というわけで、↓の記事はフライイングでした。ごめんなさい。むしろ、多くの端末を使っていて、撮った写真が散乱しているなら、バックアップ用に使うのもいいかもしれない。

Google+のAndroidアプリで必ず設定すべきたった1つの項目


ごめんなさい。誤解がありました。↑の記事をお読みいただけると幸い。


Google+Androidアプリをインストールして、ログイン後すぐに[Menu]キーを押して設定に入る。Notificationうざいので切りつつ、最後の[Instant Upload]をよく読もう。


自動的に撮影した写真や動画をアップロードする設定がデフォルトでオンになっている。ちゃっちゃか外しておこう。不用意に撮影したあんな写真やこんな動画がででーんと公開されてしまうプライベートなアルバムにアップロードされる。*1


さらに[Instant Upload settings]の中を見てみると。。。



SDカードに保存されている写真や動画までアップロードしてしまう。これはさすがにデフォルトがオフになっているので、



クリックするとワーニングが出る。

*1:15:30訂正

【超訳】AndroidのUIをUnitTestできるNative Driver

Introducing Native Driver超訳


Native DriverはWeb Driver APIの実装で、WebアプリケーションではなくネイティブアプリケーションのUIを叩くもの。Android版がダウンロード出来るようになったので、ユーザとコントリビュータをゆっくり募集。Google Code (http://nativedriver.googlecode.com/ )に置いてある。iPhone(iOS)版も開発中でもうすぐ使える。


WebDriverはブラウザの機能を綺麗でオブジェクト指向APIとして見せてくれるので、Googleでは多くのプラットフォーム上でWebアプリケーションをテストするのにWebDriverを使っている。(WebDriverについては、このブログ記事を参照)


なぜWebDriver APIをネイティブアプリケーションに使うのか不思議に思うかもしれない。理由としては、

  • ネイティブアプリケーションもWebアプリケーションも、ユーザとのやり取りは基本同じ:
    • クリック、キー入力、ウィンドウ切り替え、テキストを読む。
  • テストの記述者はサポートしたいそれぞれのプラットフォームごとに同じテストを書かなければいけない。
  • また別のAPIを誰も学習したくはない。
  • WebDriverはすでにユーザ層がありツールのエコシステムもある。WebDriverに似たAPIなら簡単に統合できる。
  • つまり: お気に入りのUIテストAPIを再利用しよう。


NativeDriverは、WebDriverのすっきりしたところと成功しているところをネイティブアプリケーションにも持ってこようという試み。WebDriver APIをいくつかのキーとなる所で拡張をして、ネイティブアプリケーション用に既存のAPIを再翻訳している。


Android用のGoogle Mapsアプリケーションに対するNativeDriverのテストのコードはこんな感じになる。(テスト風景は動画が見られる)

AndroidNativeDriver driver = new AndroidNativeDriverBuilder()
	.withDefaultServer()
	.build();
driver.startActivity("com.google.android.maps.MapsActivity");

// placesボタンをクリックしてPlacesアクティビティを開く
// (検索ボックスの右)
AndroidNativeDriver btn = driver.findElement(By.id("btn_header_places"));
btn.click();

// Placesウィンドウを閉じる
// Androidの戻るボタンを押すのと等価
driver.navigate().back();

// 横画面を表示するために回転する
driver.rotate(ScreenOrientation.LANDSCAPE);


startActivityメソッドとドライバーを作るオブジェクトビルダーの使い方以外、すべてのAPI呼び出しは、標準のWebDriver API呼び出しで出来ている。Android Debug Bridge(ADB)接続と一緒にドライバーを準備するので、ビルダーでドライバーを作る必要がある。


AndroidのNativeDriverはInstrumentationを使ってテスト対象のアプリケーションを監視、操作する。InstrumentationはAndroidの標準機能だが、いくつか制限がある。例えば、別プロセスの一部であるUIを叩けない(もしそんなことが出来たら、悪意のあるアプリケーションが端末を乗っ取れてしまう)。ADBが解決してくれるのはまさにそこ。ADBは外部からの接続で、特定のアプリケーションと括り付いていないので、アプリケーションをまたいでイベントを挿入できる。ADBでスクリーンショットも撮れるし、NativeDriverを改良するにつれて新しいやり方で使っていく予定。標準のInstrumentationテストより、AndroidのNativeDriverのテストが強力な理由でもある。


AndroidのNativeDriverは今すぐ試せるし、サンプルテストを走らせたり自分のアプリにInstrumentationを入れられる。あと、ユーザML開発者MLに参加して。


ネイティブのテストが楽しくなるよっ!じゃ!

感想: ドライバーとかネイティブって単語の使い方が異次元。

Android SDKのQEMUでArmv7対応

ちょっと調べたいことがあって、masterツリーでビルドしてみたら、

  • TARGET_ARCH_VARIANT=armv7-a

になってて驚いた。ソースコードレビューを見てみると、

ということらしい。QEMUのパッチは

で取り込まれていたので、ビルドしてみて遊んだ。

$ cd master
$ repo sync -j4
$ source build/envsetup.sh
$ lunch full-eng
$ time make -j8

蛇足だけど、repo syncも-jで並列できる。ビルドしたバイナリファイルのアーキテクチャを確認。

$ prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-readelf \
  -A \
  out/target/product/generic/system/bin/dalvikvm
Attribute Section: aeabi
File Attributes
  Tag_CPU_name: "ARM v7"
  Tag_CPU_arch: v7
  Tag_CPU_arch_profile: Application
  Tag_ARM_ISA_use: Yes
  Tag_THUMB_ISA_use: Thumb-2
  Tag_VFP_arch: VFPv3
  Tag_ABI_PCS_wchar_t: 4
  Tag_ABI_FP_denormal: Needed
  Tag_ABI_FP_exceptions: Needed
  Tag_ABI_FP_number_model: IEEE 754
  Tag_ABI_align8_needed: Yes
  Tag_ABI_enum_size: int
  Tag_ABI_HardFP_use: SP and DP

ビルドしたエミュレータを起動。$ANDROID_PRODUCT_OUTがlunchで設定されているので、引数なしで起動できる。

$ out/host/linux-x86/bin/emulator -wipe-data &

起動したらadbで覗いてみる。

$ adb shell cat /proc/cpuinfo
Processor       : ARMv7 Processor rev 0 (v7l)
BogoMIPS        : 331.77
Features        : swp half thumb fastmult vfp edsp neon vfpv3 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xc08
CPU revision    : 0

Hardware        : Goldfish
Revision        : 0000
Serial          : 0000000000000000

ところで、現在のmasterツリーでビルドしたemulatorのbrowserは起動できない。Building MLにパッチがあるが、レビュー中のパッチをcherry pickしてみる。

$ cd bionic
$ git fetch git://android.git.kernel.org/platform/bionic \
  refs/changes/94/23894/3 && git checkout FETCH_HEAD
$ cd ..
$ time make -j8

QEMUパッチのコメントによると、emulatorの起動時間が短くなったらしいので、計測してみた。emulatorコマンドをンッターーーンッ!してからホーム画面が表示されるまでの時間。

tree 初回起動 2度目の起動
master 1:19 0:27
gingerbread 1:54 0:39

多少、早くなることが期待できる。あと、/proc/cpuinfoにあるとおり、NEONのエミュレーションにも対応しているが、愚直にx86コードへトランスレートしているだけなので遅くなるらしい。試してみた。TARGET_ARCH_VARIANTをexportで変更してもlunchの方が優先されるらしく、BoardConfig.mkを直接変更した。

 --- a/target/board/generic/BoardConfig.mk
 +++ b/target/board/generic/BoardConfig.mk
 @@ -18,7 +18,7 @@ TARGET_NO_KERNEL := true
  # that are slower to emulate. On the other hand, it is possible to emulate
  # application code generated with the NDK that uses NEON in the emulator.
  #
 -TARGET_ARCH_VARIANT := armv7-a
 +TARGET_ARCH_VARIANT := armv7-a-neon
  TARGET_CPU_ABI := armeabi-v7a
  TARGET_CPU_ABI2 := armeabi

まずはバイナリのアーキテクチャをチェック。

$ prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-readelf \
  -A \
 out/target/product/generic/system/bin/dalvikvm 
Attribute Section: aeabi
File Attributes
  Tag_CPU_name: "ARM v7"
  Tag_CPU_arch: v7
  Tag_CPU_arch_profile: Application
  Tag_ARM_ISA_use: Yes
  Tag_THUMB_ISA_use: Thumb-2
  Tag_VFP_arch: VFPv3
  Tag_NEON_arch: NEONv1
  Tag_ABI_PCS_wchar_t: 4
  Tag_ABI_FP_denormal: Needed
  Tag_ABI_FP_exceptions: Needed
  Tag_ABI_FP_number_model: IEEE 754
  Tag_ABI_align8_needed: Yes
  Tag_ABI_enum_size: int
  Tag_ABI_HardFP_use: SP and DP

$  prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-readelf \
   -A \
   out/target/product/generic/system/lib/libjpeg.so 
Attribute Section: aeabi
File Attributes
  Tag_CPU_name: "ARM v7"
  Tag_CPU_arch: v7
  Tag_CPU_arch_profile: Application
  Tag_ARM_ISA_use: Yes
  Tag_THUMB_ISA_use: Thumb-2
  Tag_VFP_arch: VFPv3
  Tag_NEON_arch: NEONv1
  Tag_ABI_PCS_wchar_t: 4
  Tag_ABI_FP_denormal: Needed
  Tag_ABI_FP_exceptions: Needed
  Tag_ABI_FP_number_model: IEEE 754
  Tag_ABI_align8_needed: Yes
  Tag_ABI_enum_size: int
  Tag_ABI_HardFP_use: SP and DP

そして、動かしてみた。

tree neon Sprite Text Neocore
master off 55fps 4.1fps
master on 55fps 4.3fps
gingerbread n/a 30fps 3.2fps

あれ?速くなってるし。なぞゆえ。gingerbreadよりmasterの方が速いのはこのところ少しずつ追加されているOpenGLトランスコードの効果らしい。関係ないと思われるが起動時間も。

tree 初回起動 2度目の起動
master-neon 1:17 0:30

QEMUのArmv7対応はもう1つOSSらしい点がある。パッチのコメントにあるのだが、

  • upstreamはMeeGo
  • NEON対応はLinaroの成果

を取り入れていて、今後も相乗効果が期待できる。

主要なTwitter Appの戦闘力を調べてみた

Android Marketを手動でスクレーピングして、主要なTwitter Appのダウンロード数を調べてみた。

App Downloads Memo
Twitter 10,000,000 - 50,000,000 公式。プリインストールもあり別格。
TWIDROYD for Twitter 1,000,000 - 5,000,000 最古参の1つ。
TweetDeck (Twitter, Facebook) 1,000,000 - 5,000,000 AIR版PCアプリ, Webサービスもある。
TweetCaster for Twitter 1,000,000 - 5,000,000 よく知らない。
twicca 500,000 - 1,000,000 元サヤ力。
Seesmic (Facebook, Twitter) 500,000 - 1,000,000 Webサービスもある。
Plume for Twitter 500,000 - 1,000,000 フランス産らしい。
twipple for Android 100,000 - 500,000 NEC BIGLOBE。健闘している。
Swift App for Twitter 100,000 - 500,000 最古参の1つ。公式アプリ作成に移籍後メンテされていない。
TweetsRide for Twitter 100,000 - 500,000 最古参の1つ。
Twigee for Twitter 50,000 - 100,000 よく知らない。
TWIDROYD PRO for Twitter 10,000 - 50,000 有料$3.99。無料版の1/100
Plume Premium for Twitter 10,000 - 50,000 有料€1.99。無料版の1/50
TweetCaster Pro for Twitter 10,000 - 50,000 有料$4.99。無料版の1/100

そんなけ。

android_disk_vdiのadb接続

昨日作ったVirtualBoxAndroid x86仮想マシンにadb接続が出来たのでレポート。

  • VirtualBoxの設定でネットワークをブリッジアダプタに。
  • 起動。
  • DevToolsを開いて一番下のTerminal Emulator。
  • ifconfig eth0でIPアドレスを確認。
  • PCのコンソールで、ADBHOSTを指定してadbの起動。
    • ADBHOST= adb devices


ネットワーク設定のアダプタタイプはデフォルトのIntel Pro/1000MTでいいようだ。PCnet-PCI IIでもadb接続出来た。


IPもあるしDNSも設定されているが、アプリケーションからネットワークには接続できないし、マウスが効かないので、出来ることは限られる。ApiDemosにあるOpenGLデモのSpriteTextは11ms/fなので、かなり速いには違いないけど。