2012年5月5日土曜日

Pandaboard AndroidでVNC Server

Pandaboardを動かしていて何が面倒かといえばディスプレイをつながなければならないということではないでしょうか?
はい、というわけで、VNC Serverの出番です。これを導入すると、画面を見るだけでなく、マウス操作などもリモートからコントロールすることができるのです!!

Android上で動作するVNC Serverにも各種あるのですが、色々試した結果、ICS(Android 4.0)という条件で現状利用できるのは、droid-VNC-serverだけのようです。
今回はソースコードからビルドを通しますが、そのためにはAndroidのソースツリーが必要になります。以前ビルドを確認しているAndroid-4.0.4のツリーを使ってみたいと思います。Android自体のビルドはこちらを参照のこと。

まずはソースコードのゲット。
$ mkidr work
$ cd work
$ git clone https://github.com/oNaiPs/droid-VNC-server.git

そのままではビルドが通らないのでfastdroid-vncのソースコードも用意しておきます。
$ cd work
$ wget http://fastdroid-vnc.googlecode.com/files/fastdroid-vnc-1.0.tgz
$ tar xvzf fastdroid-vnc-1.0.tgz
(※なお、こちらでは、VNC Viewerに画面が映りませんのであしからず。ICSではね)

続いて、ビルド手順。
以降、android_404_tracking-pandaがAndroidのソースツリーとして記載します。
まずはREADMEに書かれている通り、サービスのソースコードをAndroidソースツリーのexternal下にコピーします。
$ cp work/droid-VNC-server/droidvncdaemon android_404_tracking-panda/external/

フルビルドを通してもいいのですが、下記のように部分ビルドをする方がお手軽です。
$ cd android_404_tracking-panda
$ . build/envsetup.sh
$ launch pandaboard-eng
(下記が部分ビルドのコマンドです。)
$ TARGET_TOOLS_PREFIX=/opt/android-toolchain-eabi/bin/arm-linux-androideabi- mmm external/droidvncdaemon/

と、すると早速エラーが。。。一個ずつ対処方法を説明していきます。まずは、
external/droidvncdaemon/vnc/libvncserver-kanaka/rfb/rfbproto.h:59:23: error: rfbconfig.h: No such file or directory
ファイルが足りないと言っているわけですが。
このファイルは、
fastdroid-vnc-1.0/LibVNCServer-0.9.7/rfb/rfbconfig.h
にありますので、これをコピーしてやります。
$ cp ~/work/fastdroid-vnc-1.0/LibVNCServer-0.9.7/rfb/rfbconfig.h ~/android_404_tracking-panda/external/droidvncdaemon/vnc/libvncserver-kanaka/rfb/

さらに、includeパスを通しておく必要がありますので、droidvncdaemon/vnc/Android.mkの51行目あたりの下記箇所に一行を追加。
local_c_includes := \
~略~
    $(LOCAL_PATH)/libvncserver-kanaka/rfb \
~略~

で、ビルドを行うと、続いては、
$ TARGET_TOOLS_PREFIX=/opt/android-toolchain-eabi/bin/arm-linux-androideabi- mmm external/droidvncdaemon/
~略~
external/droidvncdaemon/vnc/gralloc_method.c:158: error: 'struct framebuffer_device_t' has no member named 'read'
~略~
そんなメンバーありませんよ!というよくあるエラーですね。これの対処方法は、、、

えーと、現状
android_404_tracking-panda/hardware/libhardware/include/hardware/fb.h
にstruct framebuffer_device_tの定義があります。
あるんですが、read(フレームバッファから画像を取得する)というものはなくなっている。(以前はあったようですが。)
まあ、つまりICSではこの方法ではフレームバッファの描画内容を取得できないということです。

というわけで、該当ソースコードはビルドから外しましょう。
droidvncdaemon/vnc/Android.mkの17行目あたりのgralloc_method.cの行を削除します。
それから、こちらに依存するupdate_screen.cとdroidvncserver.cも関連箇所をコメントアウトします。
(※修正箇所はあとでまとめることにします。)

これでビルドをかけると今度は、
$ TARGET_TOOLS_PREFIX=/opt/android-toolchain-eabi/bin/arm-linux-androideabi- mmm external/droidvncdaemon/
~略~
external/droidvncdaemon/vnc/displaybinder.cpp:40: error: undefined reference to 'android::ScreenshotClient::ScreenshotClient()'
~略~
などのリンカーエラーが発生。
これは、ScreenshotClientのクラス定義が、以前はlibui.soに含まれていたものが現在はlibgui.soに含まれるようになったため、libuiだけをリンクする現在のmakeファイルでは対応できていないせいです。

というわけで、Android.mkにlibguiのライブラリを追加します。

これでビルドを通すと無事にビルドが通ります。out/target/product/pandaboard/system/bin/下にandroidvncserver_froyoとandroidvncserver_gingerupの実行ファイルが出来上がります。
以下、ひとまず、修正差分をまとめます。

droidvncdaemon/vnc/Android.mkの修正 update_screen.cの修正 droidvncserver.cの修正 実行するには。

例えばこちらで作ったpandaboard用のAndroidインストール済みSDカードをPC(Ubuntu)に挿し、出来上がった実行ファイルをコピーしてインストールします。必要なのは、androidvncserver_gingerupの方だけです。
(Ubuntuの場合にはandroidのsystemパーティションが、/media/system/に自動でマウントされます。)
$ sudo cp out/target/product/pandaboard/system/bin/androidvncserver_gingerup /media/system/bin/

これでpandaboardを起動させましょう。

Androidが立ち上がったところで、シリアルコンソールから下記コマンドを実行。※なお、VNCはネットワーク経由でのリモートアクセスですので、事前に有線LANあるいはWiFiを設定し、VNC Viewerをインストールしたマシンと通信できるようにセットしておきます。

(例えば、有線LANを使う場合には、下記コマンドを実行すると、DHCPでIPアドレスを取得します)
# netcfg eth0 dhcp
(取得したIPアドレスの確認)
# netcfg
(androidvncserverの起動)
# androidvncserver_gingerup &

実行時に表示されるメッセージからわかる通り、TCPポート5901でVNC Serverは起動しています。
たとえばUltraVNC Viewerでみる場合には"IPアドレス::5901"で接続します。

以下のような感じで、ばっちりリモートアクセスできてます。レスポンスやフレームレートは少々低いですが、ちょっとした操作をするだけであれば妥協できるレベルかと。

一つ注意点としては、Androidがサスペンド状態に入ると、VNCが切断されてしまいます。
設定メニューからサスペンド(スリープ)までの時間をデフォルトの1分という設定から30分に延長できるのですが、それもどうかという場合には下記コマンドでスリープまでの時間を無限(スリープしない)にできます。(さりげなく、TIPS)

# sqlite3 /data/data/com.android.providers.settings/databases/settings.db 'insert into "system" values(null, "screen_off_timeout",-1);'
※実際にちゃんと機能しているのかどうかあやしいところですが。。。

以上。活用してくれたまえ

3 件のコメント:

  1. はじめまして。
    仕事でPandaboardを使っていて、いつも参考にさせてもらっています。
    今回、一番最後にサスペンドまでの時間を無限にするというのがありました。
    現状、LinaroのAndroidは、Pandaboard上で、サスペンドから復帰できないというバグが出ているかと思う(私の環境だけでしょうか?)のですが、このコマンドを入力して、サスペンドに入らないようにすれば大丈夫かと思い試したのですが、やはりサスペンドに入ってしまうようです。
    基本、ACアダプタが常時接続されている前提で、長時間稼動し続けるシステムを構築したいと考えているんですが、何か手立ては無いでしょうか。
    12.04を使っていろいろとテストをしていると、何かの拍子に落ちないような形で動くことがまれにあるのですが、何が条件でその現象に入るのかがまったく特定できず、苦戦しています。
    「これで解決できる」といったものではなく「これを試してみては」という程度のものでもいいので、何か解決の糸口となりそうなものがあればお教えいただければ助かります。

    返信削除
  2. 昼に上記のコメントを書かせていただいたものです。
    Androidがサスペンドから戻らないと書きましたが、今日1日いろいろと試して見たところ、どうもUSB OTGを接続している場合のみの現象のようです。
    アプリの開発をしているもので、ほとんどつなぎっぱなしで動かしており、この条件にまったく気づいていませんでした。
    お騒がせしました。失礼いたします。

    返信削除
    返信
    1. Kim様
      コメント&有力な情報ありがとうございます!

      私はちょっと動かしてみた程度でして、詳しく検証はしておらず恐縮です。
      今後ともよろしくお願いいたします<(_ _)>

      削除