fresh digitable

めんどくさかったなってことを振り返ったり振り返らなかったりするための記録

Androidのtimestampについて勉強したこと

SensorEventのtimestampについてのメモの続きっぽいもの。いわゆるRTCとセンサとかGPSのタイムスタンプはそれぞれ違うものだという話。このへんはLinuxの基本的なことだと思うがよくわかってなかったし、今もいまいちよくわかっていないので、間違ってたら教えて下さい。

timestampの基本的な話

ほとんどSystemClockAPIリファレンスに書いてあることですが。。。

Androidにはスタートがそれぞれ違うタイムスタンプが3つある。ざっくりいうとこんな感じ。

  1. System.currentTimeMillis(): 1970.1.1からの経過時間
  2. uptimeMillis(): システム起動時からの経過時間。システムがdeep sleepになったりした間はカウントが止まる。
  3. elapsedRealtime(), elapsedRealtimeNanos(): システム起動時からの経過時間。システムがdeep sleepになってた間の分もカウントに含まれる。

1は壁掛け時計と同じで、ユーザやシステムが値を変更できる。だからいつの間にか時間が戻っていたり思っていたより進んでいた、なんてことが起こる。値が変わったことは次のブロードキャストインテントで教えてもらえる。

  • ACTION_TIMER_TICK: 時間が変わったことを1分毎に通知する。manifestファイルではなく、Context.registerReceiver()レジスタを登録する。
  • ACTION_TIME_CHANGED: 時間がセットされたことを通知する。
  • ACTION_TIMEZONE_CHANGED: タイムゾーンが変わったことを通知する。

一方、2や3は単調であること(数値の変化が単純に増えることだと思う)が保証されている。

GPSのtimestamp

位置情報はLocationクラスで渡されるが、測位した時間を知るメソッドとして、UTC時間がもらえるgetTime()と、前述のgetElapsedRealtimeNanos()がある。ただし、getElapsedRealtimeNanos()API Level 17からなのでちょっと使いづらい。

センサのtimestamp

加速度センサとかの値(SensorEvent)に入ってるtimestampは、APIリファレンスには

イベントが起きた時間(ナノ秒)

程度の説明しかなくて正直なんのこっちゃわからん。ナノ秒ということなのでシステム起動からの経過時間だと思われる。ここはソースを追いかけたけどよくわからなかった。

前に書いたものではセンサの時間をSystem.nanoTime()とみなそうとしていたのだが、果たして正しいのか。

Androidナノ秒のタイムスタンプをもらうならSystem.nanoTime()elapsedRealtimeNanos()だが、中で呼んでいるネイティブなコードがそれぞれ違うようだ。

  • System.nanoTime(): clock_gettime()CLOCK_MONOTONICを渡している
  • elapsedRealtimeNanos(): ioctl()/dev/alarmのファイルディスクリプタANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME)を渡している

clock_gettime(CLOCK_MONOTONIC, )Linuxでよく使われる時間関数で、ここによるとNTPなどの時間調整の影響を受けると書いてある。だが、ioctl()が何をしているのかわからない。。。ざんねん!私の冒険はここで終わってしまった!

引き続き調査します。なにかわかったら続きを書きます。

おまけ

SystemClock.cpp(4.3.0_r2.2)のelapsedRealtimeNanos()を読んでいたら気になる記述があった。

  • clock_gettime appears to have clock skews and can sometimes return
  • backwards values. Disable its use until we find out what's wrong.

clock_gettimeはときどき時間が歪んだり過去の値を返したりするから、何が悪いかわかるまで使えないようにしておくよ、とのこと。ioctl()はその代わりに使われている様子。

おまけ2

書いてる最中、某アイドルの声で「elapseRealtimeなの!」が脳内再生されていたんだが明らかに某社畜botの影響です本当にありがとうございました。