1. はじめに
アプリケーション開発では、新しいユースケース(例えばジオロケーション、歩数計測、ヘッドトラッキングなど)を実現するために、センサーデータの活用がますます進んでいます。 モバイルデバイスでは、特に新しいセンサーが定期的に追加されており、この傾向が顕著です。
センサーデータをWebに公開する取り組みは、これまで進みが遅く、また場当たり的でした。 実際にWebで公開されているセンサーはごくわずかしかありません。 公開されていたとしても、抽象度が高すぎる高レベルなラッパーのみなど、利用可能なユースケースが制限された形であることが多いです。 センサーごとにAPIも大きく異なるため、Webアプリケーション開発者の認知的負担が増し、実装も遅れる要因となっています。
Generic Sensor APIの目的は、センサー系API間の一貫性を促進し、 高性能な低レベルAPIによって高度なユースケースにも対応できるようにし、 仕様策定と実装を簡略化することで、新しいセンサーがWeb上に公開される速度を上げることです。
Generic Sensor APIをベースにした具体的なセンサー、適用ユースケース、コード例の一覧は、[GENERIC-SENSOR-USECASES] および [MOTION-SENSORS] 解説文書に掲載されています。
2. 対象範囲
本節は規範的ではありません。
現時点で本仕様の対象範囲は、デバイスセンサーから取得したデータを公開可能とするためのプリミティブの定義に限定されています。
リモートセンサーや、パーソナルエリアネットワーク(例:Bluetooth)上のセンサーを公開することは対象外です。 これらの分野で作業が進展すれば、共通のより低レベルのプリミティブが見つかる可能性があり、その場合には本仕様もそれに合わせて更新されます。 ただし、この場合でも実装への影響はほとんど、または全くありません。
また、本仕様には現時点でセンサー探索APIも含まれていません。 これは、現在ユーザーエージェントが利用可能なセンサーの数が限られており、そのようなAPIが必要とされていないためです。 § 3 ハードウェア機能のフィーチャ検出について で述べるようなフィーチャ検出を用いることで、現状は十分です。 将来のバージョンでセンサー探索APIが仕様化される可能性があり、現在のAPIもその点を考慮して設計されています。
3. ハードウェア機能のフィーチャ検出について
本節は規範的ではありません。
フィーチャ検出はWeb開発におけるベストプラクティスです。 本テーマに関する情報はオンライン・オフラインともに豊富に存在し、本節の目的はフィーチャ検出の詳細を論じることではなく、ハードウェア依存機能の検出という文脈に置くことです。
以下のフィーチャ検出例を考えてみましょう:
if ( typeof Gyroscope=== "function" ) { // run in circles... } if ( "ProximitySensor" in window) { // watch out! } if ( window. AmbientLightSensor) { // go dark... } // etc.
これらはいずれも、APIの存在や特性について何らかの情報を得る方法ですが、 実際にそのAPIが本物のハードウェアセンサーに接続されているか、 そのセンサーが動作するか、 まだ接続されているか、 あるいはユーザーがアクセスを許可するかどうかについては何も教えてくれません。 なお後者については、Permissions API [PERMISSIONS] を使って確認できます。
理想的には、基盤となるハードウェアの状態に関する情報が事前に得られるのが望ましいです。 しかし、これは二つの理由から困難です。 まず、ハードウェアからこの情報を取得するには性能やバッテリーの消耗が大きく、クリティカルパス上の遅延要因となります。 また、ハードウェアの状態は時間とともに変化し、 ユーザーが許可を取り消したり、センサーとの接続が切断されたり、 OS側でバッテリー残量に基づきセンサー利用を制限したりする場合もあります。
したがって、効果的な戦略はフィーチャ検出とともに、 求めているセンサーのAPIが存在することを確認し、 さらに防御的なプログラミングとして、
-
Sensorオブジェクトのインスタンス化時にスローされるエラーの検出、 -
そのオブジェクトから発せられるエラーイベントのリスニング、
-
上記すべてをユーザー体験を損なうことなく優雅に処理することで、センサーの有無によってユーザー体験が悪化しないよう配慮すること、が重要です。
let accelerometer= null ; try { accelerometer= new Accelerometer({ frequency: 10 }); accelerometer. addEventListener( 'error' , event=> { // Handle runtime errors. if ( event. error. name=== 'NotAllowedError' ) { console. log( 'Permission to access sensor was denied.' ); } else if ( event. error. name=== 'NotReadableError' ) { console. log( 'Cannot connect to the sensor.' ); } }); accelerometer. addEventListener( 'reading' , () => reloadOnShake( accelerometer)); accelerometer. start(); } catch ( error) { // Handle construction errors. if ( error. name=== 'SecurityError' ) { console. log( 'Sensor construction was blocked by the Permissions Policy.' ); } else if ( error. name=== 'ReferenceError' ) { console. log( 'Sensor is not supported by the User Agent.' ); } else { throw error; } }
4. セキュリティとプライバシーに関する考慮事項
センサーの測定値は機微なデータであり、悪意あるWebページからの様々な攻撃対象となりえます。リスク低減策について説明する前に、センサーが抱える主要なプライバシーおよびセキュリティリスクを挙げます。 [MOBILESENSORS] では主な脅威を位置情報の追跡、盗聴、キーストロークモニタリング、デバイスフィンガープリント、ユーザー識別に分類しており、 この区分は本仕様にも適しています。
センサー同士を組合わせて使った場合や、他機能との連携、あるいは継続的な利用がなされることで、 攻撃の成功リスクは高まります。特にデータの相関やフィンガープリントによる個人識別リスクが増加します。 JavaScript APIを利用するWebアプリ開発者は、この情報がどのような他データと相関されプライバシーリスクとなるか、長期間データを収集した場合のリスクなどにも留意してください。
センサー値やイベント発火頻度の違いによってフィンガープリントで特定される可能性があります。 ユーザーエージェント側でイベント頻度を制限する等により、このリスクの低減が図られる場合があります。
センサーの読み取り精度を下げることは一般的にフィンガープリントのリスクを減少させます。 ユーザーエージェントは、必要以上に詳細な測定データを提供すべきではありません。各センサー種別ごとに個別に評価してください。
このAPIを使う同じJavaScriptコードが、同一デバイス上の異なるウィンドウコンテキスト内で同時に動作する場合、相互にユーザーを特定でき、予期しないトラッキング手段になる可能性もあります。
ユーザーエージェントは、センサー利用時のインジケーターを表示したり、利用の停止をユーザーが選択できるように配慮すべきです。 また、現在または過去のセンサー利用状況を確認できる機能を提供するのも検討に値します。
センサーAPIを利用するWebアプリ開発者は、アプリ全体の観点からプライバシー影響評価(PIA)を実施してください。
デバイス上で検出できる全センサーの組み合わせ自体が識別子となり、フィンガープリントに利用される恐れがあります。
特定のセンサー組み合わせにより、端末間での非公開通信チャネルが形成されるリスクも存在します。
センサーはユーザーの端末横断的なリンク付け・追跡にも使われ得ます。
4.1. プライバシー・セキュリティ脅威の種類
本節は規範的ではありません。
4.1.1. 位置情報の追跡
この種の脅威では、センサー値を使ってGPSなどの位置センサーを介さずに端末の位置を推定する攻撃が行われます。例えば加速度センサーのデータから統計モデルを用いて推定経路を出し、 マップマッチングアルゴリズムで(半径200メートル程度の)推定座標を取得するなど[MOBILESENSORS]。
4.1.2. 盗聴
ジャイロセンサー値から音声を復元するケースは盗聴攻撃の例です。 [GYROSPEECHRECOGNITION] を参照。
4.1.3. キーストロークモニタリング
センサー値から様々なユーザー入力が推測可能であり、モーションセンサーによるユーザーのPIN・パスワード・ロックパターン(クリック・スクロール・ズーム等のタッチ動作も含む)への攻撃例も多岐に渡ります。機械学習アルゴリズムでユーザー情報を導出する場合が通常です。[STEALINGPINSVIASENSORS]。
4.1.4. デバイスフィンガープリント
センサーから得られる情報により、そのセンサーを用いた端末固有の識別が可能となる場合があります。 全てのセンサーモデルには製造誤差や個体差があり、同じモデルであっても微妙な違いが生じます。こうした製造バラツキや誤差はフィンガープリントに悪用され得ます。[ACCELPRINT] [MOBILESENSORS]。
4.1.5. ユーザー識別
センサー値から個人を特定できる場合があり、たとえばスマートフォンやウェアラブルのモーションセンサーから各人特有の歩行パターンが推定できるケースなどがあります。
4.2. リスク軽減策
本節は規範的ではありません。
本節では、仕様の規範的セクションで定めているリスク軽減策の一部を、高レベルで紹介します。
4.2.1. セキュアコンテキスト
センサー値は Secure Contexts仕様書 [POWERFUL-FEATURES] にてネットワーク攻撃者にとって重要なターゲットと明示されています。 そのため、本仕様または拡張仕様で定義される全てのインターフェースは、セキュアコンテキスト内でのみ利用できます。
4.2.2. パーミッションポリシー
ユーザーが馴染みのないコンテキストにセンサーの値を共有することによるプライバシーリスクを避けるため、センサーの値は、 documentが指定された利用可能であり、ポリシーで制御された機能がそのセンサータイプについて許可されている場合のみ利用できます。詳細は[PERMISSIONS-POLICY]を参照してください。
4.2.3. フォーカスされた範囲
センサーの値は、アクティブなdocumentに対してのみ、 そのフォーカスとオリジンチェックがtrueを返す場合に利用可能です。
これは、navigable内の要素がフォーカスを得た場合に、スキミング攻撃のリスクを軽減することを目的としています。 例えば、ユーザーがiframe内でサードパーティ支払いサービスを使ってゲーム内購入を行うときなどです。
4.2.4. 可視状態
センサーの値は、アクティブなdocumentで、その 可視状態が「visible」の場合のみ利用できます。
4.2.5. Permissions API
センサーの値へのアクセスは、Permissions APIによって制御されます。[PERMISSIONS]。
4.3. 個別対策
各センサー種別について、想定ユースケースや脅威プロファイルなどを個別に評価する必要があります。 下記のリスク軽減策のいくつかは特定センサーに有効ですが、同時に一部ユースケースを阻害したり妨げたりする場合もあります。
注: これらのリスク軽減策は、常時または一時的(例:特定操作中・脅威を増大させる他API利用時等)に適用できます。
4.3.1. 最大サンプリング周波数の制限
ユーザーエージェントや拡張仕様は、特定のセンサー種別に対して最大サンプリング周波数を設定することで、脅威の一部を緩和できます。
上限値は、センサー種別や、対処対象の脅威・攻撃者の想定リソースなどに応じて選定する必要があります。
最大サンプリング周波数の制限は、低遅延や高密度データ取得に依存するユースケースには利用できなくなります。
4.3.2. センサーを完全停止する
これは明らかに最終手段ですが、特定の時期だけ一時的に実施することで非常に有効な場合もあります。例として、ユーザーが別オリジン([rfc6454])や別アプリで認証情報を入力するときにパスワードスキミングの防止を目的にする場合などが挙げられます。
4.3.3. 取得データ数の制限
最大サンプリング周波数の制限の代わりに、センサー値の取得回数そのものを制限する方法もあります。 この場合、サンプリング頻度が高くても、Webアプリへ提供されるデータ量は抑えられます。
中間値を間引くことで、特定フィルター処理等に依存する一部ユースケースが成り立たなくなります。
4.3.4. 精度の低減
センサー値や読み取り時刻の精度を落とすことも、リスク低減に有効です。そのためユーザーエージェントは、不必要に詳細なセンサーデータを公開すべきではありません。
具体的なセンサー実装でしきい値チェックアルゴリズムを設け、最新値との差が小さい新測定値は破棄する方式も考えられます。
具体的なセンサー実装では量子化アルゴリズムにより、デバイスセンサーからのセンサー値の精度をさらに削減可能です。
注: この両対策は補完的です。しきい値チェックだけでは値が高精度で露出しすぎる場合があり、逆に丸めのみだと元値が別値に丸まった際に攻撃者はより正確な値を推定できるリスクがあります。
注: センサー読み取り値や、その時刻差を用いた追加演算にも不正確さが生じる場合があり、この軽減策が一部ユースケースに影響します。
注: センサー値にランダムなバイアスを加える方法も似た効果がありますが、ノイズ除去が容易なため実際の運用には向きません。
4.3.5. API利用をユーザーに通知
ユーザーエージェントは、現在または過去のAPI利用状況をユーザーに通知することを選べます。
注: これは実際のセンサー値のログ記録を意味しません(別の問題を引き起こす恐れがあります)。
5. 概念
5.1. センサー
デバイスセンサーという用語は、デバイスの基礎となる物理センサーインスタンスを指します。
デバイスセンサーは物理量を測定し、環境に関する情報源となるセンサー読み取り値を提供します。
それぞれのセンサー読み取り値は、デバイスセンサーによって時刻tnに測定された物理量の値により構成され、その時刻は読み取りタイムスタンプと呼ばれます。
デバイスセンサーが空間的な測定(例えば加速度や角速度など)を行う場合、それはローカル座標系上で解決されなければなりません。これはデバイスセンサーのセンサー読み取り値の参照座標系を表します。 このようなセンサー読み取り値を提供するデバイスセンサーは、空間センサーと呼ばれます。
空間センサーは、同時に測定可能な直交軸の数に応じて、一次元、二次元、三次元のいずれかとなります。
スカラー物理量(例:温度)の場合、ローカル座標系での解決は必要ありません。
モバイルデバイスで通常使われるローカル座標系は、デバイスの画面に対してX軸・Y軸が平行、Z軸が画面表面に垂直な直交座標系(デカルト座標系)です。
プラットフォームセンサーという用語は、ユーザーエージェントが一つまたは複数のデバイスセンサーから 一つのセンサー種別に由来するセンサー読み取り値を取得するために利用するプラットフォームインターフェースを指します。
プラットフォームセンサーは、基盤となるプラットフォーム(例:ネイティブのセンサーフレームワーク)、 あるいはユーザーエージェントがデバイスセンサーに直接アクセスできる場合はユーザーエージェント自身により定義されます。
実装の観点では、プラットフォームセンサーを対応するデバイスセンサーへのソフトウェアプロキシとして扱うことができます。基盤となるプラットフォームがサポートしていれば、同じデバイスセンサーと同時にやりとりする複数のプラットフォームセンサーが存在する場合もあります。
単純なケースでは、プラットフォームセンサーが一つのデバイスセンサーに対応しますが、 センサー読み取り値がソフトウェア上で行われるセンサーフュージョンの結果である場合、プラットフォームセンサーはセンサーフュージョンに関与する複数のデバイスセンサーの集合となります。
センサー読み取り値と実際に測定されている物理量との間の差異は、製造時に行われるキャリブレーションによって補正されます。センサーによっては、未知の誤差を補うために動的キャリブレーションが必要な場合もあります。
注記: プラットフォームセンサーは センサーフュージョンによって生成される場合、 仮想センサーや合成センサー(synthetic sensor)と呼ばれることがあります。しかし、本仕様ではこれらの間に実質的な違いは設けていません。
5.2. センサー種別
異なるセンサータイプは、温度、気圧、心拍数、明るさなど、異なる物理量を測定します。
本仕様書では、高レベルと低レベルのセンサータイプを区別します。
センサータイプのうち、実装方法によって特徴付けられるものは低レベルセンサーと呼ばれます。 例えば、ジャイロスコープは低レベルセンサータイプです。
実装にかかわらず、その読み値にちなんで名付けられたセンサーは 高レベルセンサーと呼ばれます。 例えば、ジオロケーションセンサーはユーザーの位置情報を提供しますが、このデータがどのように取得されたかは意図的に非公開です (GPSチップ、ネットワークセルの三角測量、Wi-Fiネットワークなど、またはそれらを組み合わせて取得する場合があります)。 取得方法は実装固有のさまざまなヒューリスティックに依存します。 高レベルセンサーは一般的には 低レベルセンサーにアルゴリズムを適用することで得られるものです。 例えば、歩数計はジャイロスコープだけの出力で構築できます。また、センサーフュージョンによるものもあります。
ただし、高レベルと低レベルセンサータイプの区分はやや恣意的であり、しばしば曖昧です。 例えば、気圧を測定するバロメーターは、ほとんどの場合低レベルと考えられますが、抵抗式圧電センサーと温度センサーのセンサーフュージョンの成果物でもあります。 構成要素のセンサーを公開しても実用的な意味はありません。誰が圧電センサーの温度を気にするでしょうか? 気圧高度計も同じカテゴリになるでしょう。一方で、バロメーターやGPS信号どちらからでもデータ取得可能な漠然とした高度計は、明らかに高レベルセンサータイプと分類されます。
この区別が曖昧なため、仕様の拡張(§ 10 拡張性参照)では、対象とするセンサータイプに対して 高レベルおよび低レベルセンサーの分野固有の定義を行うことが推奨されています。
異なるセンサータイプからのセンサーの値は センサーフュージョンというプロセスで組み合わせることができます。 このプロセスにより、より高レベル、あるいはより高精度なデータ(多くの場合、レイテンシは増加します)が提供されます。 例えば、三軸磁力計の値を、加速度計の値と組み合わせることで正しい方位が得られます。
スマートセンサーやセンサーハブは内蔵計算資源を持ち、キャリブレーションやセンサーフュージョンをハードウェアレベルで実行し、 CPUリソースを解放しつつ、バッテリー消費の削減も可能です。
センサーフュージョンは、ハードウェアレベルで実行できない場合や、アプリケーション固有の フュージョンアルゴリズムが必要な場合はソフトウェアで実施することもできます。
5.3. デフォルトセンサー
Generic Sensor APIは、最も一般的なユースケースを簡単に扱えることを目指しつつ、高度なユースケースにも対応できるよう設計されています。
現在一般的な端末には、同じ種別のデバイスセンサーを複数搭載していることは稀です。複数の同種デバイスセンサーが必要なユースケースは特殊用途に限られ、例えば一部2-in-1ノートPCのようなセンサー種別の場合に限られます。
APIはそのため、対応するSensorサブクラスをインスタンス化するだけで、
各種別ごとのデバイスのデフォルト(しばしば唯一)のセンサーと
シンプルにやりとりできるようになっています。
特定の種別をもつセンサーを特定する追加情報が与えられていない場合、 デフォルトセンサーはユーザーエージェントによって選択されます。
基盤となるプラットフォームがデフォルトセンサーの取得インターフェースを持つ場合は、ユーザーエージェントはそのプラットフォームのセンサーを選択します。 そうでない場合はユーザーエージェント自身がデバイス上に存在するセンサーの うちどれをデフォルトセンサーとするかを定義します。
let sensor= new Accelerometer({ frequency: 30 }); sensor. onreading= () => { ... } sensor. start();
注: 特定のセンサー種別については、拡張仕様がデフォルトセンサーを定義しない場合があります。例えばジオロケーションのセンサーでは実装が複数のバックエンドを用いることがあり、デフォルトを明示する意味がありません。
同じ種別に対応するデバイスセンサーが複数存在しうるケースでは、 拡張仕様側が識別方法を定義する必要があります。
var sensor= new DirectTirePressureSensor({ position: "rear" , side: "left" }); sensor. onreading= _=> console. log( sensor. pressure); sensor. start();
5.4. サンプリング周波数とレポート周波数
本仕様の目的で、プラットフォームセンサーのサンプリング周波数は、基礎となるデバイスセンサーからセンサー読み取り値を取得する頻度として定義されます。その取得方法は実装依存です。
プラットフォームセンサーのサンプリング周波数は、デバイスセンサーの実際のサンプリングレートとは一致しない場合があり、その実際の間隔は本仕様では不透明です。
注: システムレベルAPIやセンサーのハードウェアインターフェースは、ポーリング型やイベント型のどちらの場合もあります。ポーリングベースのデバイスセンサーでは、プラットフォームセンサーのサンプリング周波数は新しい読み取り値取得の頻度です。イベントベースの場合は、システムやハードウェアにリクエストした頻度またはそれ以下でイベントが発生します(値が変わらない場合は発生しないこともあります)。
デバイスセンサーはプラットフォームセンサーから受け入れ可能なサンプリング周波数の範囲として、最小サンプリング周波数および最大サンプリング周波数を提供することがあります。プラットフォームセンサーの サンプリング周波数は、デバイスセンサーの最小サンプリング周波数未満または最大サンプリング周波数超過としてはなりません。
プラットフォームセンサーのサンプリング周波数は、
関連付けられたアクティブ化済みセンサーオブジェクト集合のアイテムの[[frequency]]から
算出されます。計算方法は実装依存ですが、プラットフォームセンサーのセンサー種別で定義された最小/最大サンプリング周波数、
およびデバイスセンサーの最小・最大サンプリング周波数の範囲内でなければなりません。
注: 例えば、ユーザーエージェントは与えられた[[frequency]]集合の最小公倍数(LCD)としてサンプリング周波数を推定し、それを基盤プラットフォームが定める上限で打ち切るなどできます。
特定のSensorオブジェクトにおけるレポート周波数とは、
このオブジェクト上で"reading"イベントが発火する頻度として定義されます。
Sensorオブジェクトは、
ユーザーエージェントが基盤プラットフォームから取得する頻度以上で新しい測定値にアクセスできないため、
レポート周波数は
プラットフォームセンサーのサンプリング周波数を超えることはなく、
それもまた(指定されていれば)デバイスセンサーの最大サンプリング周波数を超えることはありません。
レポート周波数は、以下のような場合にSensorの[[frequency]]と異なることがあります:
-
リクエストされた
[[frequency]]が、Sensorに紐付くプラットフォームセンサーについてサンプリング範囲取得で返された境界値外である場合。 -
OSやデバイスセンサーが、前回報告値と十分に異ならない測定値をハードウェア・OSフィルターによって自動的に破棄した場合。
-
Sensorインスタンスに紐付くセンサー種別のしきい値チェックアルゴリズムが失敗し、プラットフォームセンサーの最新値が更新されなかった場合。
5.5. センサー読み取り値を公開する条件
ユーザーエージェントは、すべての次の条件が満たされた場合にのみ、センサーの値を公開できる Document
document に対してセンサーの値を公開できます。
-
document の 関連設定オブジェクト が セキュアコンテキスト である。
-
document の 表示状態 が「visible」である。
-
document に対する フォーカスとオリジンのチェック が true を返す。
-
特定の条件:拡張仕様は、このリストに新しい条件を追加して、対象センサータイプに対する要件を厳しくすることができます。
注: 上記の条件に加えて、Sensor
のサブクラスはそのコンストラクターで センサーのポリシー制御機能のチェック
操作を呼び出し、§ 7.1.7 Sensor.start() は センサーアクセスのリクエスト
を呼び出します。これらのチェックはまとめて § 4.2 緩和策 で説明されている対策に対応しています。
注: ハードウェアリソースを解放するために、ユーザーエージェントは、基盤となるプラットフォームセンサーに対して、新しい値が利用可能になった通知を中断するよう要求することができます。その通知は、センサーの値を公開できる場合に再開されます。
6. モデル
6.1. センサータイプ
センサータイプは以下の関連データを持たなければなりません:
-
1つ以上の拡張センサーインターフェース。
-
最小サンプリング周波数。正の数値。これは実装依存か拡張仕様で定義される。両方が設定されている場合は、より大きい値が使用されます。
-
最大サンプリング周波数。正の数値。これは実装依存か拡張仕様で定義される。両方が設定されている場合は、より小さい値が使用されます。
最小サンプリング周波数は最大サンプリング周波数より大きくなってはいけません。
センサータイプは次の関連データを持つ場合があります:
-
しきい値チェックアルゴリズム。これは2つの異なるセンサーデータを引数にとり、それらが十分異なればプラットフォームセンサーの最新データのmapを更新するかどうかを判断する。
6.2. センサー
現在のブラウジングコンテキストのプラットフォームセンサーは以下を持つ必要があります:
新しいセンサーデータがプラットフォームセンサーで取得され、かつユーザーエージェントが現在のセンサーデータを公開できる場合、ユーザーエージェントは最新データの更新をプラットフォームセンサーおよびそのセンサーデータを引数として行います。
最新データのマップは、キーが"timestamp"で、値はデータのタイムスタンプをミリ秒単位・高分解能で推定した値(unsafe current time)です。
latest reading["timestamp"]は初期状態ではnullですが、 最新データ マップが以前のデータをキャッシュしている場合はその値になります。
その他のエントリは、プラットフォームセンサーによって測定された異なる量の値を格納します。 これらのエントリのキーは、センサータイプに関連付けられた拡張センサーインターフェースで定義される属性の識別子と一致していなければなりません。 属性ゲッターの戻り値は、実装している拡張センサーインターフェースオブジェクトと属性の識別子を引数として最新データから値を取得することで得られます。
-
minimumFrequencyをplatformSensorのセンサータイプの最小サンプリング周波数とする。
-
もしplatformSensorに接続されたデバイスセンサーに最小サンプリング周波数があれば、minimumFrequencyとその値のうち最大のものをminimumFrequencyとする。
-
maximumFrequencyをplatformSensorのセンサータイプの最大サンプリング周波数とする。
-
もしplatformSensorに接続されたデバイスセンサーに最大サンプリング周波数があれば、maximumFrequencyとその値のうち最小のものをmaximumFrequencyとする。
-
タプル (minimumFrequency, maximumFrequency) を返す。
この例は、上記で説明されたモデルの実装例の一つを示します。
下図では、2つの異なる有効化されたSensorオブジェクトが、それぞれのブラウジングコンテキストから1つのデバイスセンサーとやり取りしています。

"idle"状態のSensorオブジェクトは、プラットフォームセンサーの有効化されたセンサーオブジェクトには含まれないため、デバイスセンサーとやり取りしません。
この例では、プラットフォームセンサーのインスタンスはブラウジングコンテキストごとに1つ存在します。
最新データのマップは、同じコンテキスト上のSensorオブジェクト間で共有され、
対応するプラットフォームセンサーの要求されたサンプリング周波数と同じ頻度で更新されます。
7. API
7.1. センサーインターフェース
[SecureContext ,Exposed =(DedicatedWorker ,Window )]interface :Sensor EventTarget {readonly attribute boolean ;activated readonly attribute boolean ;hasReading readonly attribute DOMHighResTimeStamp ?;timestamp undefined ();start undefined ();stop attribute EventHandler ;onreading attribute EventHandler ;onactivate attribute EventHandler ; };onerror dictionary {SensorOptions double ; };frequency
Sensorオブジェクトは関連付けられたプラットフォームセンサーを持ちます。
具象的なSensorオブジェクトもまた、関連付けられたセンサータイプを持ちます。これは、そのセンサータイプにインターフェースがあり、
拡張センサーインターフェースのいずれかと一致します。
本仕様で述べられるタスクソースは、センサータスクソースです。
対応するセンサーインターフェースのイベントハンドラー属性に対するイベントハンドラーイベントタイプは、Event handlersのセクションで定義されています。
navigator. permissions. query({ name: 'accelerometer' }). then( result=> { if ( result. state=== 'denied' ) { console. log( 'Permission to use accelerometer sensor is denied.' ); return ; } let acl= new Accelerometer({ frequency: 30 }); let max_magnitude= 0 ; acl. addEventListener( 'activate' , () => console. log( 'Ready to measure.' )); acl. addEventListener( 'error' , error=> console. log( `Error: ${ error. name} ` )); acl. addEventListener( 'reading' , () => { let magnitude= Math. hypot( acl. x, acl. y, acl. z); if ( magnitude> max_magnitude) { max_magnitude= magnitude; console. log( `Max magnitude: ${ max_magnitude} m/s2` ); } }); acl. start(); });
7.1.1. センサーのライフサイクル
注意: 上記の図のノードはSensorオブジェクトの状態を表しており、基礎となるプラットフォームセンサーやデバイスセンサーの可能な状態と混同すべきではありません。
7.1.2. Sensorのガベージコレクション
Sensorオブジェクトの[[state]]が"activating"の場合、"activated"イベント、"reading"イベント、または"error"イベントのリスナーが1つでも登録されていれば、ガベージコレクションされてはなりません。
Sensorオブジェクトの[[state]]が"activated"の場合、"reading"イベントまたは"error"イベントのリスナーが1つでも登録されていれば、ガベージコレクションされてはなりません。
Sensorオブジェクトの[[state]]が"activated"または"activating"の時にガベージコレクションされる場合、ユーザーエージェントはこのオブジェクトを引数としてdeactivate a sensor objectを呼び出さなければなりません。
7.1.3. Sensorの内部スロット
Sensorのインスタンスは、以下の表で説明される内部スロットとともに生成されます:
| 内部スロット | 説明(非規範的) |
|---|---|
[[state]]
| Sensorオブジェクトの現在の状態。"idle"、"activating"、"activated"のいずれか。初期状態は"idle"です。
|
[[frequency]]
| Hz単位の倍精度数値。関連するプラットフォームセンサーのサンプリング周波数の計算や、このSensorオブジェクトの報告周波数の上限に用いられる。初期値はnull。
|
[[lastEventFiredAt]]
| このSensorオブザーバーに送信された直近センサーデータの高解像度タイムスタンプ(起点からのミリ秒単位の経過時間)。初期値はnull。
|
[[pendingReadingNotification]]
| 新しいセンサーデータが報告された後にオブザーバーへの通知が必要かを示すブール値。初期値はfalse。 |
7.1.4. Sensor.activated
7.1.5. Sensor.hasReading
hasReadingゲッターの手順は次の通りです:
-
get value from latest reading を this および "timestamp" を引数に呼び出し、その結果をtimestampとする。
-
timestampがnullでなければtrueを返す。
-
そうでなければfalseを返す。
7.1.6. Sensor.timestamp
timestampゲッターの手順は次の通りです:
-
globalをthisの関連グローバルオブジェクトとする。
-
get value from latest readingをthisと"timestamp"を引数に呼び出し、その結果をunsafeTimestampとする。
-
unsafeTimestampがnullならnullを返す。
-
それ以外の場合、relative high resolution timeにunsafeTimestampおよびglobalを渡して返す。
7.1.7. Sensor.start()
start()メソッドの手順は次の通りです:
-
以下のサブステップを並列処理で実行:
-
request sensor accessをthisを引数に呼び出し、その結果をpermissionStateとする。
-
permissionStateが"denied"の場合:
-
creatingを使って"
NotAllowedError"DOMExceptionのeを作る。 -
notify errorをthisとeを引数にタスクキューへ積む。
-
戻る。
-
-
connect to sensorをthisとthisの関連グローバルオブジェクトを引数に呼び出し、その結果をconnectedとする。
-
connectedが偽の場合:
-
creatingを使って"
NotReadableError"DOMExceptionのeを作る。 -
notify errorをthisとeを引数にタスクキューへ積む。
-
戻る。
-
-
activate a sensor objectをthisを引数に呼び出す。
-
7.1.8. Sensor.stop()
stop()メソッドの手順は次の通りです:
7.1.9. Sensor.onreading
onreadingはEventHandlerであり、新しいセンサーデータが利用可能なことを通知するために呼び出されます。
7.1.10. Sensor.onactivate
onactivateはEventHandlerであり、this.[[state]]が"activating"から"activated"に変わったときに呼び出されます。
7.1.11. Sensor.onerror
onerrorはEventHandlerであり、抽象またはIDL操作でエラーが同期的に処理できなかったときに呼び出されます。
7.1.12. イベントハンドラー
以下は、Sensorインターフェースを実装するオブジェクトが属性としてサポートしなければならないイベントハンドラー(および対応するイベントハンドラーイベントタイプ)です:
| event handler | event handler event type |
|---|---|
onreading
| reading
|
onactivate
| activate
|
onerror
| error
|
7.2. SensorErrorEvent インターフェイス
[SecureContext ,Exposed =(DedicatedWorker ,Window )]interface :SensorErrorEvent Event {(constructor DOMString ,type SensorErrorEventInit );errorEventInitDict readonly attribute DOMException error ; };dictionary :SensorErrorEventInit EventInit {required DOMException ; };error
SensorErrorEvent
のインスタンスは、Event
の
constructor に記載された手順に従って構築されます。
error 属性は
初期化時に設定された値を返さなければなりません。これは、DOMException
オブジェクトであり、
SensorErrorEventInit
に渡されたものです。
8. 抽象オペレーション
8.1. センサーオブジェクトの初期化
- 入力
-
sensor_instance:
Sensorオブジェクト。options:
SensorOptions辞書インスタンス。 - 出力
-
なし
-
それぞれの key → value (options の要素) について
-
対応する 対応センサーオプション が 含まれていない場合 key
-
-
もし options["
frequency"] が存在する場合、-
sensor_instance.
[[frequency]]を options["frequency"] に設定する。
注記: 要求された options["
frequency"] が必ずしも尊重されるわけではありません。制約については、§ 5.4 サンプリング周波数と報告周波数 を参照してください。 -
8.2. センサーポリシー制御機能の確認
- 入力
-
sensor_type: センサータイプ。
- 出力
-
関連するすべての センサー機能名 が 利用許可されていれば true。 それ以外は false。
-
feature_names を sensor_type に紐付く センサー機能名 とする。
-
それぞれの feature_name (feature_names の要素) について、
-
もし アクティブなドキュメント が policy-controlled feature(ポリシー制御機能) feature_name を利用許可されていない場合:
-
false を返す。
-
-
-
true を返す。
8.3. センサーへの接続
- 入力
-
sensor:
Sensorオブジェクト。global: グローバルオブジェクト。
- 出力
-
sensor が プラットフォームセンサー に紐付いた場合 true、そうでなければ false。
-
platformSensor を null にする。
-
type を sensor に紐付いた センサータイプ とする。
-
virtualSensorType を sensor に紐付いた 仮想センサータイプ または未設定なら null とする。
-
topLevelTraversable を global の navigable の top-level traversable とする。
-
もし virtualSensorType が null でなく、かつ topLevelTraversable の virtual sensor mapping が virtualSensorType を含んでいる場合:
-
virtualSensor を topLevelTraversable の virtual sensor mapping[virtualSensorType] にする。
-
virtualSensor のcan provide readings flag が true の場合、 platformSensor を virtualSensor に対応する プラットフォームセンサー とする。
注記: can provide readings flag が false なら platformSensor は null のままとなり、このアルゴリズムは false を返す。
-
-
それ以外の場合:
-
デバイスに、device sensor が一つだけ存在し、読み取りを提供できる場合
-
この device sensor に対応する プラットフォームセンサー を platformSensor に設定する。
-
-
デバイスに複数の device sensor が存在し、 読み取りを提供できる場合
-
type に関連付けられた default sensor がある場合
-
この default device sensor に対応する プラットフォームセンサー を platformSensor に設定する。
-
-
-
-
もし platformSensor が null なら、false を返す。
-
bounds を プラットフォームセンサーのサンプリング範囲取得 を platformSensor で呼び出した結果とする。
-
もし sensor.
[[frequency]]が null なら、type に依存した 実装依存 の値に設定する。 -
もし sensor.
[[frequency]]が bounds[0] より小さい場合、bounds[0] に設定する。 -
もし sensor.
[[frequency]]が bounds[1] より大きい場合、bounds[1] に設定する。 -
true を返す。
8.4. センサーオブジェクトのアクティブ化
- 入力
-
sensor_instance:
Sensorオブジェクト。 - 出力
-
なし
-
sensor を プラットフォームセンサー(sensor_instance に紐付くもの)とする。
-
追加 sensor_instance を sensor の アクティブなセンサーオブジェクト集合 に追加する。
-
センサー設定をセット を sensor で呼び出す。
-
アクティブ状態通知 を sensor_instance を引数にしてタスクキューへ追加する。
8.5. センサーオブジェクトの非アクティブ化
- 入力
-
sensor_instance:
Sensorオブジェクト。 - 出力
-
なし
-
タスク( sensor_instance にひもづくもの)すべてを タスクキュー(sensor task source)から除去する。
-
sensor を プラットフォームセンサー(sensor_instance に紐付くもの)とする。
-
もし sensor の アクティブなセンサーオブジェクト集合 が sensor_instance を含む 場合、
-
sensor_instance を除去(sensor の アクティブなセンサーオブジェクト集合 から)。
-
センサー設定をセット を sensor で呼び出す。
-
sensor_instance.
[[pendingReadingNotification]]を false に設定する。 -
sensor_instance.
[[lastEventFiredAt]]を null に設定する。
-
8.6. 汎用センサー許可取り消しアルゴリズム
- 入力
-
permissionName: 強力な機能名
- 出力
-
なし
-
Sensorインスタンス sensor を 現在のレルム からそれぞれ処理する:-
もし sensor の センサータイプ の センサー許可名 が permissionNameを含む なら:
-
センサーオブジェクトの非アクティブ化 を sensor で呼び出す。
-
exception を、"生成した結果とする。
NotAllowedError"DOMException。 -
エラー通知 を sensor と exception でタスクキューに入れる。
-
8.7. センサー設定をセット
- 入力
-
platformSensor: プラットフォームセンサー。
- 出力
-
なし
-
もし platformSensor の アクティブなセンサーオブジェクト集合 が 空なら、
-
platformSensor の サンプリング周波数 を 実装依存の値(自身の アクティブなセンサーオブジェクト の
[[frequency]]値に基づく)に設定する。 -
bounds を プラットフォームセンサーのサンプリング範囲取得 を platformSensor で呼び出した結果とする。
-
保証: platformSensor の サンプリング周波数 は bounds[0] 以上 bounds[1] 以下である。
8.8. 最新読み取りの更新
- 入力
-
sensor: プラットフォームセンサー。
reading: センサー読み取り。
- 出力
-
なし
-
type を sensor に紐付いた センサータイプ とする。
-
もし type の 閾値チェックアルゴリズム が定義されていれば、
-
result を type の 閾値チェックアルゴリズム(reading と sensor の 最新読み取り を引数)として呼び出した結果。
-
もし result が false なら、これ以降の手順を中止。
-
-
もし reading["timestamp"] が存在するなら:
-
reading["timestamp"] を現在値から 実装依存の方法で unsafe current time に変換する。単調クロック(time origins と共通)を利用する。
注記: この手順の目的は、別の time origin を基準としたタイムスタンプを 同じ 単調クロック で計算利用可能とすることです。 [HR-TIME] で記載されたオペレーションにも利用されます。
-
-
それ以外の場合、設定 reading["timestamp"] を unsafe shared current time にする。
注記: どちらの場合も、unsafe current time がスクリプトへ公開されることはありません。
Sensor.timestampは常に coarsened moment(time origin に対する相対値)を返します。 -
-
最新読み取り[key] を reading の対応する値に設定
-
-
activated_sensors を sensor に紐付く 集合内の アクティブなセンサーオブジェクト とする。
-
これらのサブステップを 並列で実行:
-
それぞれ s(activated_sensors の要素)につき
-
最新読み取り更新通知 を s を引数に指定して呼び出し。
-
-
8.9. 最新読み取り更新通知
- 入力
-
sensor_instance:
Sensorオブジェクト。 - 出力
-
なし
-
もし sensor_instance.
[[pendingReadingNotification]]が true なら、-
リターン。
-
-
sensor_instance.
[[pendingReadingNotification]]を true に設定する。 -
lastReportedTimestamp を sensor_instance.
[[lastEventFiredAt]]の値とする。 -
もし lastReportedTimestamp が未設定なら
-
新規読み取り通知 を sensor_instance を引数としてタスクキューへ追加する。
-
リターン。
-
-
保証: sensor_instance.
[[frequency]]は null でない。 -
保証: sensor_instance.
[[frequency]]は 0 より大きい。 -
reportingInterval を 1 / sensor_instance.
[[frequency]]の結果とする。 -
timestampDelta を 最新読み取り["timestamp"] - lastReportedTimestamp の結果とする。
-
もし timestampDelta が reportingInterval 以上なら
-
新規読み取り通知 を sensor_instance を引数としてタスクキューへ追加する。
-
リターン。
-
-
deferUpdateTime を reportingInterval - timestampDelta の結果とする。
-
イベントループを deferUpdateTime だけ回す。
-
もし sensor_instance.
[[pendingReadingNotification]]が true なら、-
新規読み取り通知 を sensor_instance を引数にしてタスクキューへ追加する。
-
8.10. 新しい読み取りの通知
- 入力
-
sensor_instance:
Sensorオブジェクト。 - 出力
-
なし
-
sensor_instance.
[[pendingReadingNotification]]を false に設定する。 -
sensor_instance.
[[lastEventFiredAt]]を 最新読み取り["timestamp"] に設定する。 -
"reading" という名前のイベントを sensor_instance 上で発行する。
8.11. アクティブ状態の通知
- 入力
-
sensor_instance:
Sensorオブジェクト。 - 出力
-
なし
-
sensor_instance.
[[state]]を "activated" に設定する。 -
"activate" という名前のイベントを sensor_instance 上で発行する。
-
sensor を platform sensor(sensor_instance に紐付くもの)とする。
-
もし sensor の 最新読み取り["timestamp"] が null でなければ、
-
新しい読み取りの通知 を sensor_instance を引数にしてタスクキューへ追加する。
-
8.12. エラー通知
- 入力
-
sensor_instance:
Sensorオブジェクト。error:
DOMException。 - 出力
-
なし
-
sensor_instance.
[[state]]を "idle" に設定する。 -
"error" という名前のイベントを sensor_instance 上で発行し、
SensorErrorEventを利用し、そのerror属性を error で初期化する。
8.13. 最新読み取りから値を取得
-
もし sensor_instance.
[[state]]が "activated" なら、-
readings を sensor_instance に関連する platform sensor の 最新読み取りとする。
-
type を sensor_instance に紐付いた センサータイプとする。
-
もし type の 読み取り量子化アルゴリズム が定義されていれば、
-
readings を type の 読み取り量子化アルゴリズム を readings で呼び出した結果に設定する。
-
-
もし 拡張仕様 が sensor_instance のためのローカル座標系 を定義していれば、
-
([COORDINATES-TRANSFORMATION] を参照) readings の値を ローカル座標系 にリマップする。
-
-
readings[key] を返す。
-
-
それ以外の場合、null を返す。
8.14. センサーアクセスの要求
- 入力
-
sensor_instance:
Sensorオブジェクト。 - 出力
-
sensor_type を sensor_instance に紐付いた センサータイプとする。
-
sensor_permissions を sensor_type に関連する センサー許可名とする。
-
各 permission_name(sensor_permissions内)について、
-
state を permission_name の使用許可リクエストの結果とする。
-
もし state が "denied" であれば、
-
"denied" を返す。
-
-
-
"granted" を返す。
8.15. フォーカスおよびオリジンの確認
- 入力
-
document:
Document。 - 出力
-
ブール値。
-
origin を document の 該当設定オブジェクト の オリジン とする。
-
focusedDocument を document の node navigable の top-level traversable の 現在フォーカスされているエリア の DOM anchor の node document とする。
-
focusedOrigin を focusedDocument の 該当設定オブジェクト の オリジン とする。
-
もし origin と focusedOrigin が 同一オリジンドメイン であれば true、そうでなければ false を返す。
9. 自動化
Generic Sensor API およびその 拡張仕様 は、適切な応答を返す物理ハードウェアが必要となるため、テスト作成者にとって課題となります。この課題に対応するため、本ドキュメントでは [WEBDRIVER2] の 拡張コマンド をいくつか定義しており、仮想センサーを 定義・制御できます。この仮想センサーは デバイスセンサー と同様の挙動を持ちます。これらの 仮想センサー は特定の特性を持つデバイスを表し、その読み取り値はユーザーによって完全に定義できます。
9.1. 仮想センサー
仮想センサー は、デバイスセンサーの挙動を制御された方法で模擬します。 それ自身に接続されている0個以上のプラットフォームセンサーへセンサー読み取り値を報告します。
仮想センサーには以下のデータがひも付いています:
-
can provide readings flag(boolean)。
-
リクエストされたサンプリング周波数(数値)。 通常のデバイスセンサーの実際のサンプリング周波数が公開されていないのと同様に、 仮想センサーの リクエストされたサンプリング周波数も 実装依存な値であり、最小サンプリング周波数と最大サンプリング周波数の間に収まります。 仮想センサーがどのプラットフォームセンサーにも読み取り値を提供していない場合は、この リクエストされたサンプリング周波数は0となります。
注記: リクエストされたサンプリング周波数の値は、 他にも、接続されているプラットフォームセンサーが特定のサンプリング周波数をリクエストしているかどうか (これはプラットフォームセンサーごとに異なる可能性あり)や、読み取り値が仮想センサーに対しポーリングされているか (この場合はサンプリング周波数が何もリクエストされていない可能性もある)などによって決まります。
-
最小サンプリング周波数(数値)。 仮想センサーはデバイスセンサーでもあるため、 これはデバイスセンサーの 最小サンプリング周波数に対応します。
-
最大サンプリング周波数(数値)。 仮想センサーはデバイスセンサーでもあるため、 これはデバイスセンサーの 最大サンプリング周波数に相当します。
仮想センサータイプ は、ある種のセンサーを表す文字列です。
型別仮想センサー メタデータ は、順序付きマップ であり、仮想センサータイプ から 仮想センサーメタデータ を対応付けます。初期値は空で、拡張仕様 により 型ごとに定義されるべきです。
仮想センサーメタデータ は 構造体 で、その アイテム は次の通り:
各 top-level traversable には 仮想センサーマッピング があり、 順序付きマップ で 仮想センサータイプ から 仮想センサー を対応付けます。
注記: 仮想センサーマッピング の 構造体 は 同種すべての仮想センサーに共通のデータを保持します。仮想センサー 自体は 作成や利用時ごとに異なるデータを持てます。
注記: 仮想センサーマッピング は navigable ではなく top-level traversable に紐付くのは、 同一 top-level traversable 内の すべての センサータイプの プラットフォームセンサー は同じ 仮想センサー に接続されることが 前提だからです。 これは実際のハードウェアが複数画面など共通で読取値を提供する現実的な動作をエミュレートします。
注記: この仕様の web-platform-tests による テスト検証にも役立ちます。すべての WebDriver コミュニケーションは testdriver.js を通じてテストハーネスを含むフレームへ行われます (詳細)。
9.2. 拡張コマンド
9.2.1. 仮想センサーの作成
| HTTPメソッド | URIテンプレート |
|---|---|
| POST | /session/{session id}/sensor |
この拡張コマンドは、指定したセンサータイプの新しい仮想センサーを作成します。同じSensor.start()
を呼び出した同じセンサータイプのSensorインスタンスは、この仮想センサーを
バックエンドデバイスセンサー
として利用するようになります。これは§ 9.2.4 仮想センサーの削除が実行されるまで継続します。
注記: この拡張コマンドの仕組みにより、
同じ型のSensorインスタンスが
共存し、異なるデバイスセンサーを持つことができます。Sensor
sensorがこのコマンド実行前に物理センサーへ接続されている場合、そのセンサーから引き続き読み取り値を受け取ります。
connect to
sensorが再び呼ばれた場合のみ、仮想センサーから読み取りを受けるようになります。
| パラメーター名 | 値の型 | 必須 |
|---|---|---|
"type"
| String
| Yes |
"connected"
| Boolean
| No |
"maxSamplingFrequency"
| Number
| No |
"minSamplingFrequency"
| Number
| No |
-
virtualSensorTypeにparametersからプロパティ"
type"を取得した値を格納する。 -
もしvirtualSensorTypeが
Stringでない場合、 errorとWebDriver error code invalid argumentで返す。 -
もし型別仮想センサーメタデータがvirtualSensorTypeを含まない場合、errorとWebDriver error codeinvalid argumentで返す。
-
topLevelVirtualSensorMappingに現在のブラウジングコンテキストのtop-level traversableの仮想センサーマッピングを格納する。
-
もしtopLevelVirtualSensorMappingがvirtualSensorTypeを含んでいる場合、errorとWebDriver error code invalid argumentで返す。
-
connectedにparametersから
"connected"プロパティをtrueでデフォルト取得した結果を格納する。 -
maxSamplingFrequencyにparametersから
"maxSamplingFrequency"プロパティを実装依存の値でデフォルト取得した結果を格納する。 -
もしmaxSamplingFrequencyが
Numberでない、 またはNaN、+∞、−∞のいずれかならerrorとWebDriver error code invalid argumentで返す。 -
minSamplingFrequencyにparametersから
"minSamplingFrequency"プロパティを実装依存の値でデフォルト取得した結果を格納する。 -
もしminSamplingFrequencyが
Numberでない、 またはNaN、+∞、−∞のいずれかならerrorとWebDriver error code invalid argumentで返す。 -
もしminSamplingFrequencyがmaxSamplingFrequencyより大きい場合、errorとWebDriver error code invalid argumentで返す。
-
virtualSensorに新しい仮想センサーを作成して格納する。
-
virtualSensorのcan provide readings flagにconnectedの値を設定する。
-
virtualSensorのminimum sampling frequencyにminSamplingFrequencyを設定する。
-
virtualSensorのmaximum sampling frequencyにmaxSamplingFrequencyを設定する。
-
topLevelVirtualSensorMapping[virtualSensorType]にvirtualSensorを設定する。
-
successでデータ
nullとして返す。
/session/23/sensor に、次のボディを付けて POST します:
同じセンサータイプの仮想センサーは、トップレベル traversable につき 1 つしか作成できません。これに違反すると、invalid argument のWebDriver エラーコードが返されます。{ "type" : "ambient-light" , "maxSamplingFrequency" : 60 , "minSamplingFrequency" : 5 }
9.2.2. 仮想センサー情報の取得
| HTTPメソッド | URIテンプレート |
|---|---|
| GET | /session/{session id}/sensor/{type} |
この拡張コマンドは、仮想センサーのうち § 9.2.1 仮想センサーの作成によって作成されたものの情報を取得します。
返り値が成功の場合、successに関連付けられるデータは、次のプロパティを持つObjectです:
| プロパティ名 | 値の型 | 説明(参考) |
|---|---|---|
"requestedSamplingFrequency"
| Number
| 仮想センサーの 要求サンプリング周波数 |
注: § 5.4 サンプリング周波数とレポート周波数を見ることで、 サンプリング周波数に関する制約や、 なぜ要求サンプリング周波数が、実装依存値となるのかの説明があります(§ 9.1 仮想センサー)。通常、この値が 仮想センサーの最小サンプリング周波数 と 最大サンプリング周波数で設定される範囲内にあると考えれば安全です。
-
virtualSensorType を、
typeURL変数の値とする。 -
topLevelVirtualSensorMapping を、現在の閲覧コンテキストの トップレベルtraversable の 仮想センサーマッピングとする。
-
もしtopLevelVirtualSensorMappingが含まない virtualSensorTypeならば、 エラーを WebDriverエラーコード invalid argumentで返す。
-
virtualSensor を topLevelVirtualSensorMapping[virtualSensorType] とする。
-
info を新しい
Objectとする。 -
プロパティの設定を infoに対し実行し、"
requestedSamplingFrequency"と virtualSensorの 要求サンプリング周波数を設定する。 -
successでデータinfoを返す。
9.2.3. 仮想センサー読み取り値の更新
| HTTPメソッド | URIテンプレート |
|---|---|
| POST | /session/{session id}/sensor/{type} |
この拡張コマンドは、新しいセンサー読み取りをプラットフォームセンサー で利用可能にします。
注記: 仮想センサーはデバイスセンサーと同じように振る舞うため、ここで生成された センサー読み取りも プラットフォームセンサーで処理されます(たとえば センサータイプの 閾値チェックアルゴリズム や can expose sensor readings の結果などで読み取りが破棄されることがあります)。
| パラメーター名 | 値の型 | 必須 |
|---|---|---|
"reading"
| Object
| Yes |
-
readingにparametersから プロパティ"
reading"を取得した値を格納する。 -
もしreadingが
Objectでなければ、 errorとWebDriver error code invalid argumentで返す。 -
virtualSensorTypeに
typeurl変数の値を格納する。 -
もし型別仮想センサーメタデータが virtualSensorTypeを含まない場合、 errorとWebDriver error code invalid argumentで返す。
-
metadataに型別仮想センサーメタデータ[virtualSensorType]を格納。
-
topLevelVirtualSensorMappingに現在のブラウジングコンテキストの top-level traversable の 仮想センサーマッピングを格納。
-
もしtopLevelVirtualSensorMappingがvirtualSensorTypeを 含まない 場合、errorと WebDriver error code invalid argumentで返す。
-
virtualSensorにtopLevelVirtualSensorMapping[virtualSensorType]を格納。
-
parsedReadingにmetadataのreading parsing algorithmを readingで呼び出した結果を格納する。
-
もしparsedReadingがundefinedであれば、 errorと WebDriver error code invalid argumentで返す。
-
実装依存な方法で parsedReadingを プラットフォームセンサーが取得できるようにする。
-
successでデータ
nullとして返す。
9.2.3.1. 読み取り値の解析アルゴリズム
この仕様では、拡張仕様が型別仮想センサーメタデータで利用する仮想センサーメタデータ定義時に使えるいくつかのアルゴリズムを定義しています。
9.2.3.1.1. 単一値読み取り(数値)の解析
-
value に get a property を parameters・valueName で呼び出した結果を格納する。
-
もし value が
Numberでない、または値が NaN、+∞、−∞ なら undefined を返す。 -
reading に新しい センサー読み取り値 を割り当てる。
-
Set reading[valueName] を value に設定する。
-
reading を返す。
9.2.3.1.2. XYZ読み取り値の解析
-
x に get a property を parameters・"
x" で呼んだ値を格納する。 -
もし x が
Numberでない、または NaN、+∞、−∞ の場合 undefined を返す。 -
y に get a property を parameters・"
y" で呼んだ値を格納する。 -
もし y が
Numberでない、または NaN、+∞、−∞ の場合 undefined を返す。 -
z に get a property を parameters・"
z" で呼んだ値を格納する。 -
もし z が
Numberでない、または NaN、+∞、−∞ の場合 undefined を返す。 -
reading に新しい センサー読み取り値 を割り当てる。
-
Set reading["
x"] を x に設定する。 -
Set reading["
y"] を y に設定する。 -
Set reading["
z"] を z に設定する。 -
reading を返す。
9.2.4. 仮想センサーの削除
| HTTPメソッド | URIテンプレート |
|---|---|
| DELETE | /session/{session id}/sensor/{type} |
-
virtualSensorType に
typeurl変数 の値を格納する。 -
もし型別仮想センサーメタデータがvirtualSensorTypeを含まない場合、errorとWebDriver error code invalid argumentで返す。
-
topLevelVirtualSensorMapping に 現在のブラウジングコンテキストのtop-level traversableの仮想センサーマッピングを格納する。
-
Remove topLevelVirtualSensorMapping[virtualSensorType]。
-
successでデータ
nullとして返す。
注記: 利用中のデバイスセンサーが利用できなくなった場合(例えば物理的切断やUser Agentとは無関係な理由で停止など)に、プラットフォームセンサーやSensorインスタンスがどう振る舞うかは規定されていません。実装では既存のSensorインスタンスを不変としたり(新しい値を報告しない)、センサーオブジェクトを非アクティブ化したり、最終的にエラー通知を呼び出すようにエラー報告したりできます。
10. 拡張性
このセクションは規範的ではありません。
注記: このセクションおよびそのサブセクションは、拡張仕様の著者向けの規範用語でガイダンスを示しています。実装者の立場では、このセクションおよびそのサブセクションは規範的でないものと見なされます。
このセクションでは、本仕様を拡張してさまざまなセンサータイプのAPIを定義する方法について説明します。
このような拡張仕様は、1つのセンサータイプに焦点を当て、高水準(ハイレベル)および低水準(ローレベル) の両方を適宜公開することを推奨します。
拡張仕様は センサー読み取り値に キャリブレーションプロセスが適用されるかどうか明示するのが望ましいです。
拡張仕様
では、関連するセンサータイプのローカル座標系を明示的に定義するか、Sensorごとに設定可能にしても構いません。
最新の拡張仕様の一覧は、[GENERIC-SENSOR-USECASES] および [MOTION-SENSORS] を参照してください。
10.1. セキュリティとプライバシー
拡張仕様は以下を行うことが期待されます:
-
一般的な緩和戦略に準拠すること
-
ケースごとに適用される緩和戦略を考慮すること
-
セキュリティ・プライバシー自己レビューアンケート[SECURITY-PRIVACY-QUESTIONNAIRE] の評価を受けること
-
特に、センサーにより新たな通信チャネルが同一オリジン・ポリシー外で開放されうる場合に生じる 同一オリジン・ポリシー違反の評価を受けること
10.2. 命名
Sensorインターフェース(ローレベルセンサー用)は、そのプラットフォームセンサーにちなんだ名前を付けるべきです。
例えば、ジャイロスコープに対応するインターフェースは単にGyroscopeとするのが好ましいです。
Sensorインターフェース(ハイレベル)は、
物理量の名称+"Sensor"のように命名すべきです。
例えば、距離を測るプラットフォームセンサーは、そのインターフェース名をProximitySensorなどとします。
Sensorサブクラスの属性で
読み取り値を保持するものは、その値の完全な名称を用いて命名するべきです。
たとえばThermometerインターフェースでは値属性名をtemperature(value,
tempではない)として持つのが適切です。
命名の参考として、Quantities, Units, Dimensions and Data Types Ontologies
[QUDT]
を挙げます。
10.3. 単位
拡張仕様は センサー読み取り値の単位を明示しなければなりません。
TAGのAPI設計原則 [API-DESIGN-PRINCIPLES] に従い、すべての時間計測はミリ秒単位とし、それ以外の単位については例外(温度はケルビンよりも摂氏優先)を除き、国際単位系(SI)→SI誘導単位→SIで許容される非SI単位の順で規定すべきです。 詳細についてはSIパンフレット[SI]を参照ください。
10.4. ハイレベル vs. ローレベルセンサーの公開
これまで、Webプラットフォームでセンサーを公開する仕様は、 高レベルセンサーAPIに焦点を当ててきました。 [GEOLOCATION-API] [ORIENTATION-EVENT]
これは多くの理由で妥当なアプローチでした。実際、ハイレベルセンサーには次のような利点があります:
-
開発者の意図が明確に伝わる
-
基盤ハードウェアセンサーの詳細な知識が不要
-
使いやすい
-
ユーザーエージェントが著しい性能・電池寿命改善を実施しやすい
-
公開される情報量・種類が減り、特定のプライバシー/セキュリティ課題を回避できる
しかし、バーチャル/ARなど、ますます多くのユースケースで主にパフォーマンス目的から、ローレベルなセンサーアクセスが要求されています。
ローレベルアクセスを提供することで、Webアプリ開発者はドメイン固有の制約を生かし、より高性能なシステム設計が可能となります。
Extensible Web Manifesto [EXTENNNNSIBLE] の理念に沿い、拡張仕様は主に ローレベルセンサーAPIの公開に注力し、明確な利点がある場合は ハイレベルAPIも公開すべきです。
10.5. 同一タイプの複数センサーを有効化すべきでない場合はいつか?
同じセンサータイプ、同一構築パラメータのSensorインスタンスを複数作成することは、
不要なハードウェアリソース消費につながるため望ましくありません。
新たなセンサー読み取り値が利用可能になった際に複数の監視者が通知を求める場合は、
同一センサータイプの複数インスタンスを作るよりも、
ひとつのSensorインスタンスに
イベントリスナーを追加したり、
シンプルなonreading
イベントハンドラを使うべきです。
逆に、同じセンサータイプであっても、
Sensorsを異なる設定
( frequency、
精度やその他拡張仕様で
定義される設定)で使いたい場合は複数作成しても構いません。
10.6. 定義の要件
拡張仕様は § 6.1 センサータイプに挙げられたすべての関連データを 定義しなければなりません。
このセクションでは、拡張仕様が 明示すべき関連データの詳細を解説します。
-
拡張センサーインターフェース: インターフェース であり、その継承元インターフェースに
Sensorを含むもの。 拡張センサーインターフェースは構築可能である必要があり、 その[Constructor]は オプションで辞書(継承元辞書がSensorOptionsを含む)を引数に取る必要があります。拡張センサーインターフェースは サポートオプション集合(対応センサーオプションという)を持ちます。 拡張仕様 による追加定義が無い限り、 対応センサーオプションには "frequency" だけが含まれます。
User Agentは、センサーインターフェース用に対応できないオプションを 対応センサーオプションから除去しなければなりません。
拡張センサーインターフェース上でセンサー読み取り値を公開する属性は 読み取り専用であり、getterは get value from latest reading を this と属性名(identifier)で呼び、その値を返さなければなりません。
-
もしセンサータイプがセンサーフュージョンである場合は、 そのセンサー許可名は統合元のセンサータイプと同じでなければなりません。
拡張仕様は 各センサータイプについて次を定義しても構いません:
-
辞書(継承元辞書に
SensorOptionsを含むもの) -
デフォルトセンサー。 通常、デバイスごとに各型のプラットフォームセンサーは1つのみとなるため、 デフォルトセンサーの定義は単純です。 ただしセンサータイプに複数 センサーが一般的なケースでは 拡張仕様はデフォルトセンサーを定義しない選択もできます(無意味な場合等)。
10.7. 自動化
ユーザーエージェントの自動化やアプリケーションテストを可能にするため、拡張仕様について以下を推奨します:
-
エントリを一つ以上型別仮想センサーメタデータに追加すること。
-
結果として、一つ以上の仮想センサーメタデータインスタンスを定義すること。
-
センサータイプに対応する仮想センサータイプを指定し、 それが対応する型別仮想センサーメタデータエントリのキーと一致するようにすること。
Proximity Sensor は一つのセンサータイプであり、拡張センサーインターフェースProximitySensorと対応しています。その仮想センサータイプは"proximity"です。[...]
proximity読み取り解析アルゴリズムは、JSON
Objectparameters を受け取り、単一値読み取り(数値)の解析 を parameters と "distance" で呼び出さなければならない。型別仮想センサーメタデータ マップ には、キーが "
proximity" であり、その値が 仮想センサーメタデータ(その reading parsing algorithm が proximity読み取り解析アルゴリズムである)というエントリが必要です。
10.8. Permission API の拡張
各センサータイプのSensorインターフェース実装は、
読み取り値を対応する名前
またはPermissionDescriptor
で保護しなければなりません。
ローレベルのsensorは自身のインターフェース名(例:
"gyroscope"や"accelerometer")を
名前として利用してもよいです。
センサーフュージョンは統合元のすべてのセンサーに対し
利用許可リクエスト が必要です。
たとえフューズデータからローレベル 読み取り値を再構築するのが難しい場合でも、元データの一部は推測される可能性があります。例えば、絶対あるいは地磁気オリエンテーションセンサーが使われるとユーザの空間方向を推定しやすいため、これらのセンサーはデバイスの地磁気との関係を提供する磁力計(magnetometer)の利用許可が必須です。対して、相対オリエンテーションセンサーはそのような情報を公開しないため、磁力計の利用許可は不要です。
Permission descriptors
を使うことで、許容される精度やサンプリング周波数に最大制限を設定することもできます。以下は、加速度センサー向けのPermission APIの拡張例です。
dictionary AccelerometerPermissionDescriptor :PermissionDescriptor {boolean highAccuracy =false ;boolean highFrequency =false ; };
10.9. Permissions Policy API の拡張
各センサータイプのSensorインターフェース実装は、
(センサーフュージョンされていない場合は)1つ、
されている場合は複数の、
ポリシー制御機能 を持ち、その実装がドキュメント内で利用可能かどうかを制御します。
機能のデフォルト許可リストは'self'です。
注記: デフォルト許可リスト
'self'は、同一オリジンの入れ子フレームで
Sensorインターフェースの実装利用を許可し、サードパーティコンテンツからの
センター読み取りアクセスを防ぎます。
センサー機能名の集合は、関連付けられたポリシー制御機能のトークンすべてを含まなければなりません。
ローレベルのsensorは
インターフェース名をポリシー制御機能トークン(例: "gyroscope"や"accelerometer")として
使ってもよいです。拡張仕様に
明記がなければ、センサー機能名は
タイプに結び付いたセンサー許可名と一致します。
allow
属性を追加します:
< iframe src = "https://third-party.com" allow = "accelerometer" /></ iframe >
センサーフュージョンは、統合元センサーのセンサー機能名を利用しなければなりません。
< iframe src = "https://third-party.com" allow = "accelerometer; magnetometer; gyroscope" />
10.10. WebIDL例
以下は近接センサー用に本仕様を拡張した場合のWebIDL例です。
[SecureContext ,Exposed =Window ]interface ProximitySensor :Sensor {constructor (optional ProximitySensorOptions proximitySensorOptions = {});readonly attribute double ?distance ; };dictionary ProximitySensorOptions :SensorOptions {double min ;double max ;ProximitySensorPosition position ;ProximitySensorDirection direction ; };enum ProximitySensorPosition {"top-left" ,"top" ,"top-right" ,"middle-left" ,"middle" ,"middle-right" ,"bottom-left" ,"bottom" ,"bottom-right" };enum ProximitySensorDirection {"front" ,"rear" ,"left" ,"right" ,"top" ,"bottom" };
11. 謝辞
まず何よりも、Anssi Kostiainen に本仕様の開発全体を通じて継続的に献身的なご支援・ご助言頂いたことに感謝します。また、Mikhail Pozdnyakov, Alexander Shalamov, Rijubrata Bhaumik, Kenneth Rohde Christiansen には、その実装フィードバック・ご提案・リサーチにより 仕様策定に多大な示唆を頂きました。
Rick Waldron には、Web向けのgeneric sensor API設計への議論喚起、元となるAPIのスケッチ、 Johnny-Five開発での実装フィードバック、仕様策定での継続的なご助言など、多大な貢献に特別な感謝を申し上げます。
Boris Smus, Tim Volodine, Rich Tibbett には、 一貫性あるWebセンサーAPI公開初期作業への特別な謝意を表します。
Anne van Kesteren には、会合・IRC双方で粘り強いサポートを頂いたことに感謝します。
Domenic Denicola、Jake Archibald 両氏にもご支援に感謝します。
Frederick Hirsch、Dominique Hazaël-Massieux(HTML5Appsプロジェクト経由)には、管理・技術の両面での協力に感謝します。
Tab Atkins には Bikeshed作成とその細部まで時間を割いてご指導頂き感謝します。
Lukasz Olejnik、Maryam Mehrnezhad 両氏には、プライバシー・セキュリティ面での貢献に感謝します。
以下の方々もGitHub上の議論を通じ、仕様策定に大いに貢献されました: Anssi Kostiainen, Boris Smus, chaals, Claes Nilsson, Dave Raggett, David Mark Clements, Domenic Denicola, Dominique Hazaël-Massieux (via the HTML5Apps project), Francesco Iovine, Frederick Hirsch, gmandyam, Jafar Husain, Johannes Hund, Kris Kowal, Lukasz Olejnik, Marcos Caceres, Marijn Kruisselbrink, Mark Foltz, Mats Wichmann, Matthew Podwysocki, Olli Pettay, pablochacin, Remy Sharp, Rich Tibbett, Rick Waldron, Rijubrata Bhaumik, robman, Sean T. McBeth, Tab Atkins Jr., Virginie Galindo, zenparsing, および Zoltan Kis.
編集面で Anssi Kostiainen, Dominique Hazaël-Massieux, Erik Wilde, Michael[tm] Smith 各氏にも感謝します。