SlideShare a Scribd company logo
Vibration APIも読んでみた
株式会社グローバルサイバーグループ
マネージャ
藪下 正美
はじめに
自己紹介
• 藪下 正美
• 株式会社グローバルサイバーグループでFirefox OS担当やってます
• Firefox OSコミュニティでイベントとかやってます
• Codezineに記事乗りました!
– http://codezine.jp/article/detail/8540
今日のおはなし
• Vibration APIとは
• お決まりのwebidlから
• navigator探索
• GeckoのHALインターフェイス
• GonkのVibrate
• GonkのRunnableオブジェクト
• ハードウェアの操作
• まとめ
Vibration APIとは
• 端末をぶるぶるするAPI
• ぶるぶるする時間 (ミリ秒) を指定するとその時間だけぶるぶるする
• ぶるぶるする時間 (ミリ秒) ぶるぶる止める時間 (ミリ秒) の配列でパターンを
表現
お決まりのwebidlから
• vibratorはnavigatorに属するAPIなのでNavgator.webidlを見ます
• 鳴動時間を渡すインターフェイスと時間の配列を渡すとパターンで鳴らしてく
れるインターフェイスがあった
• implementsとかの指定もないので見るべきソースはnavigatorのものとわ
かった
// http://www.w3.org/TR/vibration/#vibration-interface
partial interface Navigator {
// We don't support sequences in unions yet
//boolean vibrate ((unsigned long or sequence<unsigned long>) pattern);
boolean vibrate(unsigned long duration);
boolean vibrate(sequence<unsigned long> pattern);
};
navigator探索(1)
• navigatorの実装を見てみましょう
bool
Navigator::Vibrate(uint32_t aDuration)
{
nsAutoTArray<uint32_t, 1> pattern;
pattern.AppendElement(aDuration);
return Vibrate(pattern);
}
navigator探索(2)
bool
Navigator::Vibrate(const nsTArray<uint32_t>& aPattern)
{
if (!mWindow) {
return false;
}
nsCOMPtr<nsIDocument> doc = mWindow->GetExtantDoc();
if (!doc) {
return false;
}
if (doc->Hidden()) {
// Hidden documents cannot start or stop a vibration.
return false;
}
navigator探索(3)
nsTArray<uint32_t> pattern(aPattern);
if (pattern.Length() > sMaxVibrateListLen) {
pattern.SetLength(sMaxVibrateListLen);
}
for (size_t i = 0; i < pattern.Length(); ++i) {
if (pattern[i] > sMaxVibrateMS) {
pattern[i] = sMaxVibrateMS;
}
}
// The spec says we check sVibratorEnabled after we've done the sanity
// checking on the pattern.
if (!sVibratorEnabled) {
return true;
}
navigator探索(4)
// Add a listener to cancel the vibration if the document becomes hidden,
// and remove the old visibility listener, if there was one.
if (!gVibrateWindowListener) {
// If gVibrateWindowListener is null, this is the first time we've vibrated,
// and we need to register a listener to clear gVibrateWindowListener on
// shutdown.
ClearOnShutdown(&gVibrateWindowListener);
}
else {
gVibrateWindowListener->RemoveListener();
}
gVibrateWindowListener = new VibrateWindowListener(mWindow, doc);
hal::Vibrate(pattern, mWindow);
return true;
}
navigator探索(5)
• 長い。。。
• でもまあ要するにやっていることは
• なのでhal名前空間を見に行きます
hal::Vibrate(pattern, mWindow);
GeckoのHALインターフェイス(1)
• hal::Vibrateを見てみます
• これまた長いですが
void
Vibrate(const nsTArray<uint32_t>& pattern, nsIDOMWindow* window)
{
Vibrate(pattern, WindowIdentifier(window));
}
void
Vibrate(const nsTArray<uint32_t>& pattern, const WindowIdentifier &id)
{
AssertMainThread();
GeckoのHALインターフェイス(2)
// Only active windows may start vibrations. If |id| hasn't gone
// through the IPC layer -- that is, if our caller is the outside
// world, not hal_proxy -- check whether the window is active. If
// |id| has gone through IPC, don't check the window's visibility;
// only the window corresponding to the bottommost process has its
// visibility state set correctly.
if (!id.HasTraveledThroughIPC() && !WindowIsActive(id.GetWindow())) {
HAL_LOG("Vibrate: Window is inactive, dropping vibrate.");
return;
}
if (!InSandbox()) {
if (!gLastIDToVibrate) {
InitLastIDToVibrate();
}
*gLastIDToVibrate = id.AsArray();
}
GeckoのHALインターフェイス(3)
// Don't forward our ID if we are not in the sandbox, because hal_impl
// doesn't need it, and we don't want it to be tempted to read it. The
// empty identifier will assert if it's used.
PROXY_IF_SANDBOXED(Vibrate(pattern, InSandbox() ? id : WindowIdentifier()));
}
GeckoのHALインターフェイス(4)
• ここもやってることを要約するとwindowがアクティブかどうかを判定して震わ
せるだけ
• ここでも最後のこれがキモで結局呼ばれるのはGonkのVibrate
• 次からGonkの世界に入っていきます
PROXY_IF_SANDBOXED(Vibrate(pattern, InSandbox() ? id : WindowIdentifier()));
GonkのVibrate(1)
• さっそくVibrateを見てみると
• おや短い
void
Vibrate(const nsTArray<uint32_t> &pattern, const hal::WindowIdentifier &)
{
MOZ_ASSERT(NS_IsMainThread());
if (VibratorRunnable::ShuttingDown()) {
return;
}
EnsureVibratorThreadInitialized();
sVibratorRunnable->Vibrate(pattern);
}
GonkのVibrate(2)
• ざっくり見ていくと
– すでにぶるぶるしていたら止める
– バイブレータ用のスレッドを初期化
– バイブレータスレッドで動くVibrateメソッドの呼び出し
• 震わせてそうなのは sVibratorRunnable->Vibrate(pattern); なので追いかける
と
GonkのRunnableオブジェクト(1)
NS_IMETHODIMP
VibratorRunnable::Run()
{
MonitorAutoLock lock(mMonitor);
(コメント省略)
while (!sShuttingDown) {
if (mIndex < mPattern.Length()) {
uint32_t duration = mPattern[mIndex];
if (mIndex % 2 == 0) {
vibrator_on(duration);
}
mIndex++;
mMonitor.Wait(PR_MillisecondsToInterval(duration));
}
else {
mMonitor.Wait();
}
}
sVibratorRunnable = nullptr;
return NS_OK;
}
GonkのRunnableオブジェクト(2)
• こんな感じで鳴動パターンの制御をしている
• その中でも震わせていそうなのが
– vibrator_on(duration);
• このあたり
• ラストスパートで追いかけて
ハードウェアの操作(1)
• vibrator_onを見てみると
int vibrator_on(int timeout_ms)
{
/* constant on, up to maximum allowed time */
return sendit(timeout_ms);
}
ハードウェアの操作(2)
• sendifも見てみると
static int sendit(int timeout_ms)
{
int nwr, ret, fd;
char value[20];
(エミュレータ用コード省略)
fd = open(THE_DEVICE, O_RDWR);
if(fd < 0)
return errno;
nwr = sprintf(value, "%dn", timeout_ms);
ret = write(fd, value, nwr);
close(fd);
return (ret == nwr) ? 0 : -1;
}
ハードウェアの操作(3)
• エミュレータ向けのコードを無視するとやっているのはファイルのオープン、書
き込み、クローズ
• ここを読むのはLinuxの知識が必要で、openしているのはキャラクタデバイス
と呼ばれるファイルとデバイスがマップされたもの
• キャラクタデバイスへの文字列の書き込みがドライバへの入力となる
まとめ
• 上からざっと
– アプリから呼ばれるとnavigatorでGeckoのHALインターフェイスがたたかれる
– GeckoのHALインターフェイスはGonkのVibrateを叩く
– GonkのVibrateはスレッドの準備をしてVibratorRunnableを鳴動スレッドに渡す
– VibratorRunnableは鳴動パターンを制御しながらvibrator_onを叩く
– vibrator_onはキャラクタデバイスを叩いて鳴動を制御
• vibrateが一番素直な形でハードウェア制御が書かれている
• 他のハードウェア制御APIを追いかけるときにも参考になるはずなので一読し
てみるといいよ!

More Related Content

PPTX
中国Firefox OS勉強会 3rd 組み込み屋さんから見たFirefox OS
PPTX
Firefox OSアーキテクチャクイックツアー - FxOSコードリーディングミートアップ#21向け追記版
PDF
インフラ自動化とHashicorp tools
PDF
RUNNING Smalltalk - 実践Smalltalk
PDF
Werkzeugを使ってみた #osakapy 2016/04
PDF
東京Node学園 今できる通信高速化にトライしてみた
PDF
WatchKitを実際にさわってみてわかったこと
PDF
Serfが面白いと俺の中で話題にwwwwww
中国Firefox OS勉強会 3rd 組み込み屋さんから見たFirefox OS
Firefox OSアーキテクチャクイックツアー - FxOSコードリーディングミートアップ#21向け追記版
インフラ自動化とHashicorp tools
RUNNING Smalltalk - 実践Smalltalk
Werkzeugを使ってみた #osakapy 2016/04
東京Node学園 今できる通信高速化にトライしてみた
WatchKitを実際にさわってみてわかったこと
Serfが面白いと俺の中で話題にwwwwww

What's hot (20)

PDF
"Continuous Publication" with Python: Another Approach
PDF
ご注文は監視自動化ですか?
PDF
Pythonによる非同期プログラミング入門
PDF
2014年を振り返る 今年の技術トレンドとDockerについて
KEY
Bundler kanazawa.rb meetup #2 2012/09/19
PDF
Core Image Tips & Tricks in iOS 9
PDF
Dive into the Cloud with our buddy, lovely PHP!
PDF
Serf2Excel - Serf を実運用に活かす話 + Consul もあるよ
PDF
Pylons ユーザのための Pyramid 移行ガイド
PDF
俺のZabbixがこんなに可愛いわけがない(おかわり)
PDF
WebAssemblyのWeb以外のことぜんぶ話す
PDF
Vagrantと網元で開発環境を作ってみよう
PPTX
Robotium を使った UI テスト
PDF
Apple Watch 間通信
PPTX
ゲームインフラコンテナ実践導入
PPTX
Android 開発, 運用時に使いたいライブラリやサービスの紹介
PDF
What makes pyramid unique
PDF
Start-padrino
PDF
watchOS 2 新機能の細かい話
PDF
20120706-readablecode
"Continuous Publication" with Python: Another Approach
ご注文は監視自動化ですか?
Pythonによる非同期プログラミング入門
2014年を振り返る 今年の技術トレンドとDockerについて
Bundler kanazawa.rb meetup #2 2012/09/19
Core Image Tips & Tricks in iOS 9
Dive into the Cloud with our buddy, lovely PHP!
Serf2Excel - Serf を実運用に活かす話 + Consul もあるよ
Pylons ユーザのための Pyramid 移行ガイド
俺のZabbixがこんなに可愛いわけがない(おかわり)
WebAssemblyのWeb以外のことぜんぶ話す
Vagrantと網元で開発環境を作ってみよう
Robotium を使った UI テスト
Apple Watch 間通信
ゲームインフラコンテナ実践導入
Android 開発, 運用時に使いたいライブラリやサービスの紹介
What makes pyramid unique
Start-padrino
watchOS 2 新機能の細かい話
20120706-readablecode
Ad

Similar to FxOSコードリーディングミートアップ#16 Vibration APIも読んでみた (20)

PPTX
A2 SORACOM API使いこなしレシピ集 | SORACOM Technology Camp 2020
PPT
フィルタドライバ入門
PDF
React native felicaの紹介
PPTX
iPhoneアプリ開発の歩き方〜Swift編〜
PDF
Pyramid + socket.io 人狼を作ってみた
PDF
AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?
PDF
ARでVRアバターを表示するシステムを構築しよう
PDF
NoSQL and JavaScript 2013-02-09
PPTX
6th oct2012 kobeit_webintents
PDF
A Framework for LightUp Applications of Grani
PDF
DAS_202109
PDF
APIMeetup 20170329_ichimura
PDF
IDAの脆弱性とBug Bounty by 千田 雅明
PPTX
イベント駆動プログラミングとI/O多重化
PPTX
Linuxベースのオープンソース フライトコントローラーの概要( #ABC2015S )
PPTX
Androidアプリ解析の基礎 公開用
PDF
Arduino を PHP で制御する
PDF
Firefox mobile for android internals
PDF
ドリコムのインフラCI
PDF
WildFly Swarm - Rightsize Your Java EE Apps
A2 SORACOM API使いこなしレシピ集 | SORACOM Technology Camp 2020
フィルタドライバ入門
React native felicaの紹介
iPhoneアプリ開発の歩き方〜Swift編〜
Pyramid + socket.io 人狼を作ってみた
AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?
ARでVRアバターを表示するシステムを構築しよう
NoSQL and JavaScript 2013-02-09
6th oct2012 kobeit_webintents
A Framework for LightUp Applications of Grani
DAS_202109
APIMeetup 20170329_ichimura
IDAの脆弱性とBug Bounty by 千田 雅明
イベント駆動プログラミングとI/O多重化
Linuxベースのオープンソース フライトコントローラーの概要( #ABC2015S )
Androidアプリ解析の基礎 公開用
Arduino を PHP で制御する
Firefox mobile for android internals
ドリコムのインフラCI
WildFly Swarm - Rightsize Your Java EE Apps
Ad

More from Masami Yabushita (18)

PPTX
Idlリーディング xpidl編
PPTX
Idlリーディング webidl編
PPTX
Firefox OSアーキテクチャクイックツアー
PPTX
FxOSコードリーディングミートアップ#16 Contacts API読んでみた
PDF
Meetup11 contacts api読んでみた
PDF
20141018 osc tokyo_fall_firefox osってなぁに?
PDF
マンガで覚える視線誘導 おかわり
PDF
できる!スマホアプリ:Webからはじまるアプリ for CMU16
PDF
できる!スマホアプリ:Webからはじまるアプリ
PDF
ちょっとapiかいてみた
PDF
Fx OS n2_aoitan_firefox osことはじめ
PDF
T82 aoitan あおいたんのパズルを数学しましょうか_修正版
PDF
わんくま勉強会東京#82 あおいたんのパズルを数学しましょうか
PDF
バッテリー監視の為にバックグラウンドタスクについて調べたらなくなってたから作ってみた話のはずだった
PDF
バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話
PDF
N29 aoitan firefox osことはじめ
PPTX
Fx osコードリーディングの紹介
PPTX
ちょっとapiかいてみた
Idlリーディング xpidl編
Idlリーディング webidl編
Firefox OSアーキテクチャクイックツアー
FxOSコードリーディングミートアップ#16 Contacts API読んでみた
Meetup11 contacts api読んでみた
20141018 osc tokyo_fall_firefox osってなぁに?
マンガで覚える視線誘導 おかわり
できる!スマホアプリ:Webからはじまるアプリ for CMU16
できる!スマホアプリ:Webからはじまるアプリ
ちょっとapiかいてみた
Fx OS n2_aoitan_firefox osことはじめ
T82 aoitan あおいたんのパズルを数学しましょうか_修正版
わんくま勉強会東京#82 あおいたんのパズルを数学しましょうか
バッテリー監視の為にバックグラウンドタスクについて調べたらなくなってたから作ってみた話のはずだった
バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話
N29 aoitan firefox osことはじめ
Fx osコードリーディングの紹介
ちょっとapiかいてみた

FxOSコードリーディングミートアップ#16 Vibration APIも読んでみた