Pepperのタブレットでのログメッセージ処理

PepperのタブレットにはAndroid 4.0.4がいて、ここでWebブラウザが走っています。おそらくAndroidデフォルトのブラウザのようで、JavaScriptなども(4.0.4なのでつらいところもありますが)動きます。
が、デフォルトのボックスなど使ってもそのままではちょっとログまわりが貧弱な感じで開発はつらそうだなと。そんなわけでいくつか試行してみたのでそのメモ。

なお、今回のお試しコード類は https://github.com/yacchin1205/pepper-tablet に置いてあります。

#アプリケーション内にタブレット用コンテンツを定義

まず、アプリケーション内にタブレット用のリソースを定義する方法を簡単にまとめてみます。
基本的には、[Pepperで画像を撮影してタブレットに画像表示](http://qiita.com/Atelier-Akihabara/items/833e49a079788af55afb)にある通り。

1. アプリケーション内に `html` フォルダを作り、そこに `index.html` 他必要なリソースを置く

    ![html-resources.png](https://qiita-image-store.s3.amazonaws.com/0/28770/bf511d48-a4df-b5d5-5b0b-aef1e88698fd.png)

2. tabletボックスライブラリの Show Appボックスを配置する。基本的には以下のボックスだけでOK
    
    ![pepper-load-app-box.png](https://qiita-image-store.s3.amazonaws.com/0/28770/cb3cb4cd-8548-e8a1-ab5b-c052601cad9d.png)


ただ、Pepper TechFes 2014で配布されたバージョンのChoregrapheだと、tablet関連ボックスが前提とするパス構成に問題があるので、 [Show Imageボックスの実装をみてみる](http://qiita.com/Atelier-Akihabara/items/87def938b6553ee9c1e9#%E8%A3%9C%E8%B6%B3show-image%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9%E3%81%AE%E5%AE%9F%E8%A3%85%E3%82%92%E3%81%BF%E3%81%A6%E3%81%BF%E3%82%8B)あたりを参考に、パス処理の部分を修正するなりする必要がある。

これで、タブレットに `index.html` で定義したコンテンツが表示されます。コンテンツを表示させること自体は割と簡単。

アプリケーション中の `html` ディレクトリが、ユーザのホームディレクトリの `public_html` がWebサーバ経由で見えるようになるのと同じような雰囲気。Pepper内にいるローカルなWebサーバが、タブレットのブラウザから参照できるようになっている雰囲気っぽい。

#タブレットのブラウザで発生するメッセージを取得

デフォルトではJavaScriptにエラーなどが発生しても、Choregrapheのログ上は何も言わないみたいで、エラーなど起きてても全然わかりません。これでは開発はつらい感じなので、エラーログを取ったり、あるいは  `console.log` などで状況を出力させたくなります。

なお、今回は以下のようなコンテンツをタブレットに表示させてみてテストしました。以下のように、わざとエラーを発生させるボタンと、 `console.log` を呼び出すようなボタンがあります。

![chrome-html.png](https://qiita-image-store.s3.amazonaws.com/0/28770/07d92da3-b910-5204-53e0-24e692a6b12a.png)

まあ、スクリーンショットのようにChrome Developer Toolsみたいなのがほしいんですけど、とにかくログが出力されるだけでも・・・

##メモリイベントで取得

とりあえず、NAOqiのアーキテクチャを考えると、メモリイベントとしてログがあらわれるのかな、と思いつつAPIドキュメントを調べると、ずばりなものが見つかります。

> Event: "**ALTabletService/message**"
> callback(std::string *eventName*, std::string *subscriberIdentifier*)
> 
>  Raised when message occurs.

メモリウォッチャーで `ALTabletService/message` を監視しつつ、わざとコンテンツでエラーを起こしてみると、こんな感じで見える。

![webview-logview.png](https://qiita-image-store.s3.amazonaws.com/0/28770/792e5875-8caf-4fd4-468f-fd150817c90d.png)

うむ・・・！

まあ、メモリウォッチャーのみだとちょっと確認しずらいので（たぶん、最後に出力されたログのみが表示されている）。せめてログビューアに流したくなるのが人情というものです。

##ログに流す

APIドキュメントを見ていたら、 `ALTabletService::onConsoleMessage(message)` というものもあった。tabletボックスライブラリのタッチイベント取得はこのSignals機構でやってるっぽいし、このシグナルで処理するのがALTabletService API流のように見える。ということで、Show Appボックスを以下のように修正。

なお、以下の感じの修正をしたバージョンのコードを最初に書いたgithub上の webview-console プロジェクトに置いてあります。

###consoleMessageCallbackメソッドの追加

console messageを受け取るためのメソッドを作る。Show AppボックスのPythonスクリプト末尾に以下のようなコードを追加。

```py
    def consoleMessageCallback(self, message):
        self.logger.info("[ConsoleMessage] %s" % message)
```

メッセージを受け取ったら、 `self.logger` を使ってログを出力している。

###onInput_onStartメソッドの修正

`tabletService.loadApplication` を実行する手前に以下のようなコードを追加。

```py
                # コンソールを監視開始
                if not self.consoleConnectId:
                    self.consoleConnectId = tabletService.onConsoleMessage.connect(self.consoleMessageCallback)
```

これで、`consoleMessageCallback` を `onConsoleMessage` に反応するように設定できる。

###onLoad, onUnloadメソッドの修正

アンロード時にハンドラを登録解除するようにする。`onUnload`メソッドに以下のようなコードを追加。

```py
        # コンソールの監視終了
        if self.consoleConnectId:
            try:
                self._getTabletService().onConsoleMessage.disconnect(self.consoleConnectId)
                self.consoleConnectId = None
            except Exception as e:
                self.logger.error(e)
```

あと、ロード時に、メンバの初期化もしておく。`onLoad`メソッドに以下のようなコードを追加。

```py
        self.consoleConnectId = None
```

###動かす

この修正を施したプロジェクトを動かしてみると、ログビューアでログが見えます。エラーが起きればこんな感じ。

```
[INFO ] behavior.box :consoleMessageCallback:80 _Behavior__lastUploadedChoregrapheBehaviorbehavior_1143658480__root__ShowApp_2: [ConsoleMessage] Uncaught TypeError: Cannot call method 'call' of null
```

記録し忘れたけど、ちゃんと `console.log` の出力も見えます。十分ではないけど、これでだいぶデバッグが楽になるのではないかなー。と期待。
PepperのタブレットでJavaScriptとかどの程度動くのかもいじってみたいなあ・・・