Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
ラベル Firefox の投稿を表示しています。 すべての投稿を表示
ラベル Firefox の投稿を表示しています。 すべての投稿を表示

2024-08-01

Android 14 (Credential Manager) におけるパスキー対応が面倒すぎる

DroidKaigiにココらへんの話をしようと思って、CfP書いたけど落ちたので、自分用の覚書。

Firefox (GeckoView) AndroidでCredentail Managerの対応を入れたのが、GeckoViewとしてはバイナリサイズを大きくしたくないため、JetPackを一切使わずにCredential Manager経由でWebAuthn対応を行うコードをJavaでスクラッチで書いた。おそらくJavaでスクラッチで書いたのはChromeとGeckoViewだけだし、おそらくこの2つの製品以外でスクラッチ実装がされることは今後もないと思う。

しかもGeckoViewはWebブラウザエンジンなわけだから、いろんなWebサイトで実行可能な必要がある (= オリジンを正確に設定する必要がある)。この値を設定するのもおそらくBlinkとGeckoの2つの製品以外でほぼ存在しないであろう。なので、実装にあたって、実装者、すなわち自分しか被害者がいない事例がいろいろあることになるわけだ。自分はGoogleの人じゃないので、社内情報アクセスできないからね。

従来の実装方法

Google Mobile Service (GMS) にFIDO API (https://developers.google.com/android/reference/com/google/android/gms/fido/fido2/package-summary)が提供されていた。これを使うことでWebAuthnの実装が簡単にできるようになっている。またとあるバージョン以降であればパスキーをGoogle Password Managerに登録することが可能。これは古いAndroidでも動作する。

Credential Managerとは

Andorid 14から Credential Managerという仕組みが追加された。このCredential Managerはサービスとして実装されるもので、サードパーティに対して認証要求を移譲できる。ただこのサービスには3つのメソッドしか存在しなくて、登録・認証・削除があるだけだ。幅広い認証情報を扱えるようにAndroidチームの人は考えためであろうけど、この3つのメソッドには引数がBundleしか実質存在しない。すなわちアプリケーションはBundleに各々好き勝手に情報を入れると、OSにインストールされたCredential Managerサービスたちが、登録成功とか返すようになっている。なおBundleに何入れるべきか?なんてものも存在しない

Credential Managerを使ったパスキー実装

パスキーを実装するには、このBundleになにかを入れる必要があるのだが、そんな情報はdeveloper.android.comには一切存在しない。GeckoViewでは一通りのBundle定義をしているが、これらはJetPackのコードとChromeのコードから持ってきている。オープンソースだったからいいようなものだが、これらの謎定義はGoogle社内でしか共有されていないような感じなので、まぁなんというかEU頑張れって感じ。ここには入れていないが、Google Password Managerだけ無視するっぽく見える定義もあったりする

実際問題、JetPackを使った場合はここらのBundle問題はJetPack側で吸収されるので、そこらは問題になりえないのだが、問題はリクエスト用のJSONは自分たちで組み立てないといけないってことだ。 なので、WebAuthnの仕様をちゃんと理解しないといけない。それをアプリケーション開発者に求めるのはどうかと思う。なおレスポンスもJSONむき出しで渡される。検証とかしたい場合は、むき出しで渡されたJSONデータを展開して検証しないといけない。

以前のGMSのFIDO APIではJSONむき出しな仕組みにはなっていない。引数はBuilderが用意されているので、必要なパラメータを設定するだけで行える。ちなみにGeckoViewでいうと、これがCredential Manager版ここがFIDO API版なのだが、Credential Manager版は自分でJSONを組み立てるのに対して、FIDO API版はBuilderで引数を組み立てる。

あと、検証時 (Assertion) には落とし穴が実は存在してて、クライアントサイドで検証する際には、レスポンスのJSONの ClientDataJsonハッシュを使って検証を行うわけだけど、レスポンス内のこの値は正しくない可能性があって、リクエスト時にBundleに入れたClientDataJsonのハッシュが正しい値だったりする (これは2日悩んだ)

現在のCredential Managerがどの認証方法を対応しているか?

そんな方法はない。

とりあえず試してみて、サービスがTYPE_NO_CREATE_OPTIONSを返してくれれば、たぶん対応していないということがわかる。なお、1Passwordは最初のリクエストでサービス自体がクラッシュしたりするので正しく動かなかったりする。GeckoViewだと登録時はResident KeyがRequiredのときだけCrednetial Managerを使うようにしているが、Preferredの場合にどうするかは決めかねている。

また、認証を行おうとしてるクレデンシャルがGoogle Password Managerで認証可能かどうか?みたいなのはFIDO API経由で確認は可能なので、認証可能であればGMSのFIDO2 APIを使って、認証できない場合は Credential Managerを使ういうこともできる。GeckoViewもChromeもそのようなコードを入れている。

結論

GMSのFIDO APIがCredential Manager対応すれば、みんなハッピーだったのでは?やっとサードパーティ製品で対応が増えてきたところだしさ

2023-05-11

Firefox Androidにおけるresident key (Discoverable Credentials) 対応

これの続き

Firefox AndroidにおいてはWebAuthnの実装をGoogleのFIDO2ライブラリを使っている。このライブラリはWebAuthn APIをそのままJavaのインターフェイスにしたようなものなので、Firefox AndroidにおけるWebAuthnの対応はこのライブラリの実装内容に依存している。

今年になってこのライブラリがアップデートされ、resident key (Discoverable Credentials) 対応が含まれた。ただ残念?なことにそのAPIを使うと、CredentialsがGoogle Password Managerで他のデバイスとGoogleアカウントを通じて同期するようになる。要は勝手にPasskey対応になってしまう。もちろん同期しないオプションなんてアプリケーション側が使えるAPIには存在しない。なお、デバイスがGoogleアカウントにサインインしてない場合、Passkeyが作成できないというエラーでWebAuthn APIは失敗する。

このような状況なので、いくつか懸念点はあるんだが、Firefox AndroidのStable版はabout:configを使えるわけではないので、デフォルトオフで実装は入れておいた。Firefox 114のBetaおよびNightlyでabout:configで該当設定を変更すれば使えるようになる。

PasskeysがGoogleアカウント経由で同期されるということは、例えば、ChromeでPasskeyを使ってサインインした場合、そこで利用されたCredentialがFirefoxでも使えてしまう (もちろん逆も同じ)。そのような感じでいろいろどうかと思う動作がいろいろあるので、Bug 1831137に解決しないといけない問題は書いてある。個人的にはAndroid 14以上の場合だけ使えるようにしてもいいかもだけど、まだ最終的な結論は決めてない。なぜAndroid 14以降なのかというと、このバージョンではCredential Provier Serviceというものが導入される予定で、Autofill Serviceのようにシステム側で使うように設定しておけば、Google Passowrd Managerではなく、設定したサードパーティのサービスが使える予定らしい。Android 14が出てから考えよう

2023-03-24

How to build Firefox for Linux/riscv64 on Ubuntu 22.10 + Unmatched

A people asks me about how to build Firefox/riscv64. Since all patches to build it are merged, so the instruction is updated from previous. The following instruction is on Ubuntu 22.10 on riscv64gc

  1. Clone firefox code from mozilla official repository
    • hg clone https://hg.mozilla.org/mozilla-central (Mercurial)
    • git clone https://github.com/mozilla/gecko-dev (git).
  2. Change current directory to cloned directory
    • cd mozilla-central (if using mercurial)
    • cd gecko-dev (if using git)
  3. Create mozconfig file in current dicrectory. File content is the following
    mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir
    mk_add_options AUTOCLOBBER=1
    
    ac_add_options --enable-application=browser
    ac_add_options --disable-debug
    ac_add_options --enable-optimize
    ac_add_options --disable-tests
    ac_add_options --without-wasm-sandboxed-libraries
  4. Install rust. See rustup.rs
  5. Install clang and nodejs
    • sudo apt install clang nodejs
  6. Run ./mach bootstrap and select "2. Firefox for Desktop"
  7. Run ./mach configure
  8. Run ./mach build. It spends 8-9 hours.

Enjoy!

2023-03-22

Google Mobile ServiceのFIDOパッケージを使うと勝手にPasskey対応になる

Google Mobile Service (GMS) にFIDOのパッケージがあるんだが、今年リリースされたVersion 19でWebAuthnにおけるDiscoverable Credentials (Resident key)の対応ができるAPIが追加されている。

Blinkを使っていないとあるWeb BrowserのAndroid版におけるWebAuthn対応はこのGMSのパッケージを使っているおかげで、Resident keyの対応をしていなかったのだが、このパッケージのバージョンにアップデートすれば解決するかも?と考えて、手元で修正コードを書いてみたんだけど、以下のように表示されて勝手にPasskey対応になるっぽい。

上記のように勝手にPasskey対応になってしまい、しかもGoogleアカウント内に同期されちゃうから、とあるWeb Browserの事情だと実装するには、いろんな人たちの許可取らないといけないので、Resident key対応は一時中断することにした。個人的にはPasskeyを使うかどうかのオプションが欲しいのだけどないっぽいし、あの検索会社自体の都合でそれをつけてくれるのはないだろうな、しかもこのパッケージ、GMSだし。

2022-12-06

Firefox for macOS版をLinux上でビルドする

自分用メモ

Firefoxのビルド環境はカスタムビルドされたclangを使っているため、Linux上でmacOS版のビルドができたりする。実際AWS/GCP上のTaskCluster (MozillaのCI) ではmacOS版はLinuxでクロスビルドしてる。問題はSDKのヘッダとかなんだが、まぁここらからもってくるなり別のmacOS環境からSDKのヘッダ・ライブラリ一式を持ってこればどうにかなる。

mozconfigファイルはこんな感じでいけるはず

mk_add_options MACOS_SDK_DIR=/other/MacOS-SDKs/MacOSX11.3.sdk
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir-macos

ac_add_options --target=x86_64-apple-darwin
ac_add_options --enable-debug
ac_add_options --enable-optimize
ac_add_options --enable-tests
ac_add_options --with-macos-sdk=/other/MacOS-SDKs/MacOSX11.3.sdk

2021-11-30

Web Speech APIのSpeechSynthesisEvent.elapsedTimeは秒を返すのだけど

バグレポートを受け取って気づいたのだけど、SpeechSynthesisEvent.elapsedTimeは秒を返すのが正しい。ただほとんどのブラウザがこの値を秒で返していなかった (例外はFirefox for Linuxくらいかも)。なので、Safariも最近直っていたので、Firefox側も直した

ここまでは普通の話なのだが、バグ報告をした人がChromeでも同じ問題が起きるとしてバグを報告したのだが、このバグが滑稽。Chromeはバグを受け付けるとQAが出てくるのだけど、そのQAがまずWeb APIの仕様を理解してないし、理解しようともしない。その人を乗り越えないと、Bug Triageさえちゃんとやってくれないようで、バグを認識させるためにはそのQAが投げ出すまで付き合ってあげないといけなくて、非常に無駄なコストがかかる。google.comじゃなくてchromium.orgのメアドを使っているからどこかのベンダーなんだと予想してるのだけど、そうだったらもっとまともな会社使おうよと、Google。

そもそもWeb Platform test (wpt) でTest failure発生させられる話だったら、そういうテストケースを書いておいて、さくっとwptに入れちゃうのだけど、このissueに関してはwptを書きようがないので、まぁChromeチームはずっと放置すると読んでる。

なお、Bug Triageに関してはMozillaは詳しい人かチームマネージャがやるので、大概ちゃんとした人が見ることになることが多い。こんな感じでBug Triageをちゃんとやらない製品はバグ修正とかにコストかけない (または評価システム上、評価されない) だろうなぁと勝手に思ってる。

2021-10-08

いまさらながらAndroidのAutofill Frameworkの困った話

AndroidのAutofillというのは、カスタムコントロールを使わないアプリにとっては実装は難しくはないのだが、カスタムビューを実装しているアプリでは、自分でいろいろな情報を提供しないといけない。実際には、自動入力用にアプリを最適化するに書かれているように、システムがAutofill用の情報を要求してきたら提供する、フォーカスの状態をシステムに通知するなどを追加実装する必要がある。

全部のアプリケーションでそのような実装しているとは限らないので、実装していないような昔のアプリケーション用にAndroidはおせっかいな機能を追加している。互換モードだ。これはアクセシビリティの実装を用いたautofillのエミュレーションを提供するもので、カスタムビューがアクセシビリティ機能の実装をしている場合は、それを利用してAutofill情報を設定する。そもそもアクセシビリティの実装しててAutofillの実装しないアプリがあるのかと問い詰めたいところではあるが。

この互換モードというのは自動的に切り替わるわけではなくて、Autofillサービス側で事前に設定をする。だから例えばアプリがAutofillの実装を入れたとしても、アプリ側からこの互換モードを無効にする方法は残念ながらない。この互換モードが動作してしまうと、アクセシビリティノードの走査が走ってしまうため、当然ながらパフォーマンス問題を引き起こす。アクセシビリティノードの走査はandroid.view.Viewの実装内で行われているから、該当コードを実行しないようにすれば、アクセシビリティノードの走査が実行されなくなるので、ある程度は回避可能ではある。残念ながらある程度ね。

この互換モードで実行しているかどうかは、こんな感じで調べられると思う。

public boolean isCompatibilityMode(Context context) {
  try {
    final AccessibilityManager manager =
      (AccessibilityManager) context.getSystemService(
                               Context.ACCESSIBILITY_SERVICE);
    if (manager == null) {
      return false;
    }
    final List<AccessibilityServiceInfo> serviceInfoList =
      manager.getEnabledAccessibilityServiceList(0);
    if (serviceInfoList == null) {
      return false;
    }
    for (final AccessibilityServiceInfo info : serviceInfoList) {
      if (info.getId().equals(
        "android/com.android.server.autofill.AutofillCompatAccessibilityService"
      )) {
        return true;
      }
    }
  } catch (final Exception e) {
  }
  return false;
}

アクセシビリティノードを走査させないようにしたとしても、互換モードは引き続きおせっかいなコードを実行する。この互換モードが動作する際には、CompatibilityBridgeと呼ばれるものがアクセシビリティイベントをウォッチするようになる (これについては無効にする方法はない)。そのためアクセシビリティイベントを発火させるとそれに応じて勝手にAutofillの互換コードが実行されてしまう。例えばAccessibilityEvent.TYPE_VIEW_FOCUSEDのイベントを受け取ると、AutofillManager.notifyViewEnteredを呼び指したりする。そのため内部でAutofillフォーカスがアクセシビリティノード上に移動する。たとえアプリケーションがAutofill情報を提供してたとしてもだ。AndroidのAutofillはフォーカスが移った際にAutofill用のリクエストをAutofillサービスに渡すので、互換モードでかつ、もしアプリがAutofillの実装をしてた場合、2度リクエストが飛ぶという困ったことになってる。

今どきのWebブラウザというにはOSのAPIはUI Processで実行される。Webコンテンツ内のアクセシビリティ情報をコンテンツのロード時にContent Processで集められ、集まった後UI Processへ送られる。アクセシビリティ情報の収集というのは非常に重い処理なので、UI Processへ送られるのは、ブラウザにとっては相当後になる。なので下手をするとAutofillフォーカスが予期もしてないアクセシビリティノードに奪われた状態でAutofillサービスがAutofillのUIを出したりしようとするので、ブラウザにとっては予期しない動作になりがちになる。例えば、Bug 1693152とかBug 1715549とか。

このように残念な互換モードを使っているAutofillサービスで有名なのはBitwarden。昔Bitwardenの開発者になんで互換モードに設定しているの?って聞いたけどよくわからない答えを返してきたので、今度こそどうにか止めさせるつもり。このような問題に引っかかるのはたぶん自分だけだと思いたいし、Androidはこの互換モードをアプリ側から止める方法を提供してほしかった。

なお、Bitwardenを使ってて、たまにChromeとかでもAutofillが動かないという話があれば、おそらくこのパターンの話。

2021-09-02

OSのIME関連APIとWebブラウザは相性が悪い

今どきのWebブラウザは複数のプロセスで動くことが前提になっている。Chromeで言えば、メイン(UI)プロセスとレンダラープロセス。Firefox用語であればChromeプロセスとコンテンツプロセスという感じで別れて動作している。Webコンテンツはコンテンツ用のプロセスで表示され、文字入力はUI用プロセスで動作している。だから入力された文字はコンテンツ用のプロセスへプロセス間通信で送られ、コンテンツ用プロセスで内部的に描画されるいることになる (実際に画面上に描画されるのがGPUプロセスだったりUIプロセスだったりするけど)。

今どきのOSで使われるIMEのためのAPIは入力された文字をただアプリケーションに渡すだけではなく、様々なことを要求してくる。例えば文字変換の精度を上げるために現在入力している場所周辺の文字情報をアプリケーションへ要求したり、文字変換用パネルウィンドウの表示位置を決定するために、アプリケーションが文字入力している表示座標の問い合わせをアプリケーションへ行ったりする。

Webブラウザは反応速度を上げるため、基本的にはブロッキングするようなプロセス間通信を許可しない (もちろん例外がないわけではないが)。プロセス間通信は基本的に非同期で行われてる。たとえば、コンテンツ用プロセスがビジーな状況というのは結構ありがちな状況で、その状況下で同期モデルなプロセス間通信を使うと、当然のことながら、そのプロセス間通信が正常終了するまでに長い時間がかかり、反応速度が非常に悪くなる。なので基本的には非同期なプロセス間通信を利用している。

この非同期なプロセス間通信のみを許可するというところが、非常にIME関連APIとの相性を悪くしている。なぜなら多くのケースでこれらのAPIが非同期API (例えば引数で渡されたコールバック関数経由で値を渡す) ではなくて、同期APIになってたりする。または、非同期的なレスポンス (エラーコードとして、今はPendingだからまた問い合わせてねというものを返す) を返すことが可能であっても、そのエラーコードを見てくれなかったりなど、まぁWebブラウザがこういうモデルを要求しているというニーズにIME関連APIがマッチしてない。APIデザインが最後発であるAndroidでさえ、残念ながらここらがすべて非同期になってない。

そんなこと言っていても、OS側がこちらの欲しいAPIを実装してくれるわけでもないので、ChromeもFirefoxもいろんな手を使ってこの状況下でもIMEを動かすようにしている。ただうまく行かないケースになった場合、例えばIMEの候補ウィンドウが間違った場所に表示されてしまったりするのは、これらのブラウザ側のハックがうまく動かなかったケースになる。Android版になると、メインプロセス内でもブラウザのメインスレッドとAndroidのUIスレッドが別になるので、より複雑さを増したりする。

なお、Apple (macOS) はWebKit2のときにこの問題を解決するめに非公開の非同期API群を作って対処した。Appleズルい

2021-07-02

Firefox on Linux/riscv64

This step is out of date since I have merged all patches to trunk. Please read How to build Firefox for Linux/riscv64 on Ubuntu 22.10 + Unmatched instead.

Although I don't land all patches to mozilla-central yet, source code is https://github.com/makotokato/gecko-dev/tree/riscv64.

To build this, you have to build nodejs v16.0 since Firefox build sytem requires it. So I recommend that you setup cross compile environemnt instead of building on Unmatched board host.

Also, this is .mozconfig sample.

mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir
mk_add_options AUTOCLOBBER=1
ac_add_options NODEJS=/home/makoto/node-v16/bin/node

ac_add_options --enable-application=browser
ac_add_options --disable-debug
ac_add_options --enable-optimize

export CC=gcc
export CXX=g++

If using corss compile,

mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir
mk_add_options AUTOCLOBBER=1

ac_add_options --enable-application=browser
ac_add_options --disable-debug
ac_add_options --enable-optimize

ac_add_options --target=riscv64
export CC=riscv64-linux-gnu-gcc
export CXX=riscv64-linux-gnu-g++
export HOST_CC=gcc
export HOST_CXX=g++

2020-09-16

Chat Channels of Web Engine

メジャーブラウザを作っている三者 (Apple、Google、Mozilla) は知ってる限り、各ブラウザプロジェクト用チャットチャンネルを持っている。FreenodeにChromiumとWebKitのチャンネルはあるのだけど、実際そんなに使われているわけではなくて、別のものを使っている。AppleとGoogleはSlackに、MozillaはMatrix上に存在する。Mozillaも社内向けには別のチャンネルがあるし、ずっとIRCサーバーを運用してたのだけど、最近Matrixに移行した

Chromium

https://chromium.slack.com/。chromium.orgアカウントを持っているとか、彼らにとってのパートナー会社であれば、Slackのチャットサーバーに入ることはできる [*]

Gecko

https://chat.mozilla.org/。githubアカウントでもFirefoxアカウントでも入ることが可能

WebKit

https://webkit.slack.com/https://webkit.org/getting-started/に招待リンクがあるから、そこから入ることはできる

メモとして残しておく

2020-09-08

IS_PRIVATE on Windows 10 20H1

昔書いたHow to use Microsoft IME's private mode on not IE/Edigeの続きの話。

このとき調べたようにMicrosoft IMEにおけるPrivate Mode (変換情報を学習しない) という機能は、Microsoft IMEがIE内部の隠しAPIを呼ぶことで実現してた。そのためMicrosoft EdgeやInternet Explorerでのみ使える機能で他社のWeb Browserでは使うことができなかった (というかWeb Browserに限定しないけど)。

で時は過ぎ、Microsoft EdgeがChromiumベースになることになった。Chromiumベースになったということでこれで晴れて公開APIができると思ったけど、全くそんなことはなかった。ただ、非常に面白いパッチがChromiumに入った。

For TSF1 on Windows 10, we need to set input scope to IS_PRIVATE if we
are in "Incognito" or "guest" mode.

Bug: 958054
Change-Id: I35e4adec0fd1800cff1ec2fcfe7983e2a65540e8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1591886
Commit-Queue: Siye Liu 
Reviewed-by: Yohei Yukawa 
Cr-Commit-Position: refs/heads/master@{#657438}

この修正を見たところ、「以前Microsoft IMEはIS_PRIVATEを見てないはずなのに。もしかしてWindows Insiderビルドで直ってたの?」と思ったのだけど、ダウンロード可能なWindows Insiderビルド+Chrome Canaryで全然直ってない。あれ?ということで、MicrosoftのIMEチームへ直接コンタクトしてみたところ、「IMEチームのバグリストには存在してるんですが。。。」的な回答が返ってきた。さすが自分がいたころ (10年以上前) と一緒で、縦割りすぎて横連携できない会社のままだなぁと思ったのだが、それで放置しても誰も得をしないので、IMEチームの人といろいろやり取りして、Windows 10 20H1のMicrosoft IMEではInputScopeのIS_PRIVATEを見るようにしてもらいました。IS_PRIVATEをつけてる場合は、IMEは学習しないようになっているため、もしアプリケーションでIMEの学習機能を無効にしたいのであれば、IS_PRIVATEを使ってください。FirefoxでもWindows 10 20H1を使えばプライベートモードであれば学習しないようにしてます。

2020-06-08

Edge/ARM64の出来をみると、Windows on ARMのx86エミュレーターは結構速い

WebCrypto APIのベンチマークというのは結構難しくて、そもそも現在のWebCrypto APIはPromiseベースの実装のため、下手をするとWebブラウザに実装されたマイクロタスクをテストするだけのものになることもある (≒なのでベンチマークを取るとったとしても正確なデータかというと、、、な時がある。WebCryptoを使ったベンチマークを説明する時にPromiseの話を触れない人は正しいマイクロベンチマークを書くことが出来ない人なのかもしれない)。Promiseで結果を返すようなAPIはベンチマークが正しい結果を出すとは限らないのだが、それを抜きにしても面白いデータが取れたのでここに書いておく。

jsperf.comに簡単なWeb Cryptoのベンチが置いてあったのだけど、まずx86版ChromeをWindows 10 on ARMで動かしたデータが以下になる。


これをARM64版Edgeで実行すると以下になる。


なんとx86版のほうがAESのベンチマークが圧倒的に速いという結果になる。これはx86版はAES-NIをちゃんと使っていて、x86エミュレーターがちゃんとAES-NIをARM専用命令に置き換えているからと思われる。

ARM64にもAESは専用命令があるのだが、OpenSSL/BoringSSLでは、アセンブラで書かれているコードでARMの専用命令を使っていて、これはGNU AS用のアセンブラコードなので、MicrosoftのARM RealView形式のアセンブラと互換性がないから、おそらく無効にされているのだろう。

なお、ARM64版Firefoxだとこういう結果になる


これはちゃんとしたネイティブ実装 (by 自分) をしており、AESとSHA2はARM Crypto Extensionを使った実装になっているので、ちゃんとネイティブの方が速い。

ネイティブ版でも必ずしもエミュレーターよりも常に速いわけではない。というよりも、もっとARMに対してやる気出せよ、Microsoftと。

2019-06-27

New Firefox Preview for Android

自分はちょうど半年前くらいにGeckoView Team (要はAndroid用のGeckoを作るチーム) に移籍してる。Input Systemとかがメインで (Windows + macOS + Linux は自分と中野さんがやってるのでAndroidがそれに加わったようなもの)、それ以外もいろいろバグ対応とかしてる。

GeckoViewってのはモバイルというかAndroid版の戦略変更によってここ2年くらいMozillaが作ってるもので、フロントエンドのUXさえ作ればいろんなバリエーションのブラウザを作りやすくなるという代物。例えばFirefox Focusようなものや、Firefox Reality、Amazon EchoShowでGeckoベースのブラウザを作ったりするなど、いろいろバリエーションが増やせるようになった。

そもそも従来のAndroidに内蔵するWebViewにはいろんな制限があって、簡単に言えば元となってるChromeと同様のWeb APIをサポートしてるわけではない。だからWebViewを使ったブラウザというのはそのバージョンのChromeと同等ではない。(もし同等なものができるのであれば、ChromeがWebView使ってると思う)。GeckoViewはそうではなくて、Geckoで実現可能なものはすべて使えるようにAPIをいろいろ追加してる

超簡単なブラウザを作るのであれば、mozilla-centralのツリーに入ってるGeckoView Exampleのがサンプルになる。見てみればわかるけど、簡単なものを作るだけであれば、非常に少ないコードでブラウザをつくることができる。またこれだとヒストリ機能とか足りないので、Android Components (a-c)というものを使うことでブラウザをより現代のブラウザらしくつくることができる。なおa-cはGeckoViewじゃなくてもServoとかシステムWebViewとかに対しても動作するようになってる。

ということで従来のFirefox for Android (Fennec)はGeckoViewを使ってるわけでなかったのだけど、このGeckoView版といえるFirefoxがFenixと呼ばれてた、このFirefox Previewになる。

GeckoViewになって一番うれしいことは、やっとマルチプロセスであるということ (今後FissionとかWebRenderもあるので、プロセス数は増えると思う)。そのおかげでパフォーマンスはよくなってるはず。Firefox 68からでもあるけど、aarch64への標準対応もかな?

なお、従来のFennecは68で最後になる。ESRブランチに移行するので、セキュリティ修正等は当分行われる (今のところいつまでは決まってない)。

このFirefox Previewはまだ開発版なので、Tracking ProtectionとかPWAとかWeb Extentionのサポートが欠けてるけど、これは正式版までにははいるはず。要望やバグ報告は、Bugzillaではなくて、githubへ。日本語じゃないと無理であれば、Mozillazine.jpのフォーラムへ投稿してください。見ておきます。

2018-07-22

Web Replay

Mozillaとして今年はWeb or アドオン開発者へ向けての機能を充実させようというのがテーマにあるんだけど、Brian Hackett (元々SpiderMonkeyの型推測とかやってた人) がWeb Replayというものを作ってる。まだ本体には入っていないのだけど、これはRecording & Replayデバッガと呼ばれてるもの。

デバッグをしていと誰もが経験すると思うのだけど、ブレークポイントを仕掛けて止まった時に、調べようと思ってた現象 (バグ) がすでに起きてしまってて、「あー、このポイントでは遅かったか。。。」ということは何度も経験あると思う。そうするともう一度デバッグのやり直しになると思う。Recording & Replayデバッガがあると、その際にその現象が起きるところまで巻き戻すことができる。そのためデバッグの効率が非常に高くなる。

またその一連の動作を保存できれば、現象を何度も起こす必要なくそれを再生すればいいだけなので、QAが見つけてきたものを開発者がより効率的に調査できる。

そのような機能をFirefoxに搭載しようとしていて、これがWeb Replayと呼ばれているもの。

ちょうど今月のJSConf EUでJason Lasterがそのプレゼンやっててビデオがここにある。10分くらいからそのデモがある。


こういう機能がブラウザに入ればよりデバッグが楽になるよね!Firefox 63 or 64くらいかなと。

追記

Replyじゃなくて、Replayですね。emkさんありがとうございます。

2016-12-31

Quantum CSS (Stylo)

個人的な持論として、新しいプログラミング言語は自分自身の存在意義の証明をすべしっていうのがある。実際自分が雇用された会社が言語を作った例ってのがいくつもあるんだけど、大体の会社においてそれが行われている。実際ポシャったLonghornのコードなんかはシェルがC# (Avalon)+WinFSゴリゴリで書かれてて、デスクトップ用途におけるC#の存在意義を示すものだった。このプロジェクト自体は失敗したけど。失敗した理由は決して言語のせいだけじゃなかったけどね。完成時におけるハードウェアスペックの想定を間違えていた。

Rustって言語は、同じ時期に出てきたGoと同じ感じと勘違いする人は多いけど、Rust自体は言語仕様としてコーディング時に起きやすいミスを言語仕様的に許さないっていうことがあって、C言語みたいなとりあえずコンパイルは通すみたいなのを許してくれないことが多い。そのため、動いてしまえば問題が起きづらいって感じで、さすが2010年代に出てきた言語だなという感触がある。でもRustって言語の証明をしないといけないとは思うけど、それは?ってところでServoというエンジンがある。

Servoのデモっていくつか残念な話があって、Servoで最速な部分の話を全面に出してて、実際のところよく最適化された現在のいろんなWeb Engineにくらべて速いってことはそんなに多くはない。ただ、局所においてはそうとう速いところはある。

現在のGeckoのCSSパーサーやStyle Systemの設計は相当古い。WebKitやBlink、Edgeに比べれば速いわけでもない。そこでStylo (Quantum CSS)で置き換えて行くってことになる。Stylo自体は去年のMozilla All HandsでRustをどう使うかとかServoどうするのよ的な話から派生した流れで2015年の年末からBobby Hollyがやり始めたもので6月の時点のデモではWikipediaのCSS Parse / Stylingが約5倍くらいになるよって感じでステータスが報告された。Stylo自体は別ツリーでビルドされているので、まぁちょっとずつだけど進んではいる。実際のところは3/4くらいのCSSプロパティの実装は行えてるので、このままだと2017年の春から夏にはNightlyで有効にされるんじゃないかな?

なおBlinkはCSSパーサーをアップデートしたらしいんだけど、そのパーサーをAppleもポーティングしてWebKitに組み込んだらしいんで、2017年は各社のCSSパーサーがいろいろとアップデートされる年なんだろうね。

2016-06-10

自分用async / await functionsメモ

Firefox / SpiderMonkey

Bug 1185106 - Implement async functions (ES7 proposal)

もともとインターンがオーナーだったけど、araiさんが直してる

Safari / JavaScript Core

Bug 156147 - [JSC] implement async functions proposal

IgaliaCaitlinが書いた。でConstさんがReviwer

Chrome / V8

Issue 4483 - V8 - Feature Request: Support async/await functions

InitialコードはIgaliaのCaitlinが書いた。でも今はGoogle自身で直してる。

2015-08-14

WebCompat

MozillaはFirefoxやFirefox OSの開発以外にもいろんなことをしてが、Mozilla社内にはWebCompat Teamってのがある。

何をしているかを説明すると、Firefoxや他のブラウザで表示されないページを解析して、なぜ表示されないのかを調べ、それを製品やWebの標準に活かすことをやってる。場合によってはコンテンツ制作元・会社へ問い合わせをして、具体的な修正方法を提示するってこともする。

今年になって彼らはアジア圏のモバイルWebサイトを集中的にみてる。具体的には中国と日本。日本も見てるけど、日本語がわからない人が見てるんじゃないのって思う人はいるかもしれないけど、チームメンバーの一人は日本に住んでいるので日本の事情もよく知ってる

日本のサイトにおいて彼らはTOP100+のモバイルサイトをすべてチェックして、大体の傾向があるそうだ。

  • CSS flexboxはwebkitプレフィックスを使った古い形式のものが未だに使われている (= Web標準を利用していない)
  • CSS xxx (いろいろ) はwebkitプレフィックスを使った古い形式のまま未だに使われている (= Web標準を利用していない)
  • ユーザーエージェント文字列にWebKit的なのがないとモバイルと見なさない。またAndroidという文字だけでもモバイルとみなしてない。でもAndroid 4.0のようにバージョン番号を含めるとそれが改善するサイトが結構存在するらしい
  • 使われているライブラリがWebKitでしか動かない (CSS TransformがWebKitプレフィックスがないと動作しない。JavaScriptから触る場合も含めて)

Mozillaの解析結果で言えば、Microsoft Edgeのユーザーエージェントの件は、現状のモバイルWebでどうしたら適格に表示できるようにするかということを考えればいたしかたないことだと思う。これをバカにする人たちは現状のモバイルWebを理解していないか、SafariとChromeだけで動けばいいサイトを作るひとのどちらかだ。そういう人たちに限って、Internet Explorer 6でしか動かないサイトを作ってた人たちなんじゃないかな

でもMozillaのやりかたで言えば、Microsoft Edgeのやり方よりももっとすべきことがあると思う

Mozillaで言えば、こういうことをまず最初にやる

  1. 表示できないサイトを調査 (それ用に検出ツールもある)
  2. 原因を特定し、サイトのオーナー (要はその会社) にコンタクト
  3. コンタクト可能であれば、修正方法も含めて提供・アドバイス

MozillaはモバイルWebにおいて強力なシェアを持った会社ではないので、僕らの言うことなんて聞いてくれない・無視する会社も存在する。もちろんコンタクトをとったところ、ちゃんと直してくれるところもあるけどね!。どうしても直してくれない場合にはいくつかメカニズムを用意してる

UserAgentの書き換え

ユーザーエージェントを強制的に別の文字列にすることでモバイルページとして認識させる。https://dxr.mozilla.org/mozilla-central/source/mobile/android/app/ua-update.json.inにリストがある

CSS unprefixing service

webkitプレフィックスとかを強制的に外す。https://dxr.mozilla.org/mozilla-central/source/caps/nsPrincipal.cpp#501ここらへんがそのホワイトリスト。

ということもやって、モバイルWebページに対しても表示改善を行っている。ここ数か月でFirefox for Androidを使った時にページ表示が改善しているはず。

こんなことをブラウザベンダがやらなくてもWeb開発者が標準に即したページを作ってくれればいいんだけど、残念ながらそういうことにはなっていない。プレフィックスというデザインがよくなかったという話は数年前にしていたけど、いまだにこれが現状だ。

またWeb Compatibilityって考えかたはシェアが大きい会社であればあるほど言わない。それは昔のMicrosoftを見てればそうだし、今のシェアの高い会社を見れば、そんな感じ。MozillaもMozilla.orgになってからはここを重要視しているし、各ブラウザの互換性向上には各ベンダーが投資してほしいなと個人では思ってる

最後に、報告先として彼らはサイトを持っているので、https://webcompat.com/ に報告してもらえると助かる。ここはFirefox以外にEdgeの件も報告してもらって構わない。Web全体のComaptibility向上が目的なので。

あ、これらの話はもう少しデータ付きで会社のブログに書くべきだなと今思った

2015-05-05

Adobeが行っている各ブラウザへのコントリビューション

Microsoft EdgeでAdobeがコードの貢献をしたという話があったのだけど、これを見て、EdgeはAdobe、Microsoft連合だ思っている人が多いみたいなので、Adobeが各ベンダに対してやってることを書こうかと。

まず、彼らはSVGとかCSSとかの仕様への貢献をずっと行っていて、SVGの場合ではSVGWGのFace to Faceミーティングの場所を毎年貸し出したりしてる(シアトルのオフィスがそれ)。

そもそもAdobe自体はいろいろとWebに対しても行っているのだけど、彼らにとって、仕様の貢献を行っていても実際ブラウザベンダが実装しない限り絵に書いた餅でしかないので、彼らが必要と思っている(関わっている)仕様に関しては実装まで手を出しているってのがここ数年の状況だ。

Geckoサイドでいうと、CSS Filtersは彼らの貢献なしでは実装が進まなかったというか、その部分に関しては彼らがコード書いている。

WebKitだとCSS ExclusionsとかCSS FiltersとかCSS Regionsらへんが絡んでる。(Feature FlagをAppleがOnにしないとSafariとかで使えないけどね)

BlinkだとBlendingとかCSS Sharpesとか

このようにAdobeという会社は各ベンダーのエンジンに対してコードを書いてたりする。自分たちが必要だから仕様を策定しているのだから、そりゃ当然実装にも手を出すよねってこと。Microsoftの件はそれがOSSでなかったとしても手を出し始めたということだね。

基本的にAdobeのブログとかで触れられるCSSとかの仕様・技術の話は彼らが仕様策定に絡んでいたり、実装を行っていたりするものなので、そういう視点でブログを読むとより楽しく感じる思う。

ちなみにAdobeのMozillaへの貢献としてTamarinというJITエンジンの話を出す人がいるけど、あれパフォーマンス出なくてGeckoへ統合されなかったものなんだよね。しかもその後、現Mozilla CTOのGalがほぼ一人で書いたTracing JITのほうが遥かに速かったというオチまでついた。(JavaVMへのTracing JITの実装を大学でやってた時にBrendanに引きぬかれたのがMozillaに来たきっかけだった記憶がある)

2015-01-25

Firefox Nightlyで位置情報プロバイダがGoogleからMozillaに変更になった

ブラウザ内で位置情報を取得する際、FirefoxではGeoIPとWiFi情報から位置情報を決定している。従来のFirefoxではGoogleの位置情報APIを利用していたのだが、先週末のFirefox NightlyからGoogleの位置情報APIではなくて、Mozilla自身の位置情報APIを使うように変わった。

Mozillaの位置情報サービスはMozilla Location Servicesという名前で開発を行っていて、GoogleのAPI互換かつ、サーバーなどのソース、収集されたデータさえも公開されている。(細かい話は以前書いたエントリを参照のこと。)

ここで参照されるデータというのは、以下のアプリで収集されたものがベースになっている。
  • Mozilla Stumbler
  • Firefox for Android (Mozilla 位置情報サービスへのデータ送信を有効にしている場合)
Firefox for Androidで位置情報データがMozillaへ送信する場合は限定的な条件がついている。それはGeo Location APIを利用した際にGPSベースで位置を取得した場合のみだけになっている。そのため、まとまった量の位置情報のデータを送るためにはMozilla Stumblerを使うのが現状ではベスト。

これらのデータに関しては一年前からコツコツデータ収集をしてきたので、東京の都心に関してはデータの密度は高くはなっている。

ただ、これだと場所によってはデータの品質に問題があるので、Windows版とOSX版のみ別のプロバイダを使うオプションが存在してる。

Microsoft Location API
Windows版上でabout:configgeo.provider.ms-windows-locationtrueにすると、代わりにMicrosoftの位置情報サービスを使うようになる (Windows 7以降)。すなわち位置情報についてはInternet Explorerと同様の品質になる。

Core Location API
OSX版上でabout:configgeo.provider.use_corelocationtrueにすると、代わりにAppleの位置情報サービスを使うようになる。(OSX 10.8以降だったはず)。すなわち位置情報についてはSafariと同様の品質になる。

Firefoxの正式版のころにはいろいろ変わっていると思うけど、今の開発版ではこんな感じになってる。

2015-01-18

XHR({mozSystem: true})がマジで使えない件

XHR (XMLHttpRequest) 自体は、CORS (Cross-Origin Resource Sharing) をサポートしないと自分のドメイン以外へのXHRのリクエストに対してレスポンスヘッダーとかの値を取ることはできない。そのためFirefox OSではmozSystemというオプションを用意して、CORS対象でないサイトへのリクエストであってもXHRが使えるようにはなっている (SystemXHRの権限を与える必要あり)。

また、XHRは302などのリダイレクションに対しては、自動でリダイレクト処理を行う。

CORSが使える環境においては、XHR.withCredentials = true にするとCookieとかも扱えるようになる。CORSじゃない環境 (mozSystem:true) の時はCookieとかは自動的には送らない。

XHRはこんな感じで動作するだが、この前提において、こんなケースにぶち当たった。

POST /abc
Host: example.com
Content-Type: application/x-www-form-urlencoded
Cookie: SESSIONID=ABC

というリクエストをとあるサーバーに投げると

302 redirect HTTP/1.1
Location: https://example.com/def
Set-Cookie: cookie=ABC <----(A)

と返してくるから、XHRは自動的にリダイレクト処理をするので、

GET /def
Host: example.com
Cookie: SESSIONID=ABC

と送るわけだ。ここで重要なのは (A) でSet-Cookieした値は、リダイレクト後のGETには入らないということ (mozSystem: trueだから)。そのCookieがWebサーバー側は必要としてたようで、以下のように返してきた。

404 Not Found HTTP/1.1
Host: example.com

(A) の値さえ取得できれば、自分でリダイレクト処理をすればいいんだけど、当然ここから、(A) を取得する方法なんて存在しないようで。。。XHRでリダイレクトを止めたいという話はstackoverflowでもwell-knownな質問で、答えは「不可能」。

一瞬mozTCPSocketを使って簡易HTTPクライアントを作ろうかと思ったけど、そもそもHTTPSなサイトなんだよねということで諦めた。このXHR({mozSystem: true})自体はちょっと凝ったことはできないよねってこと。そもそもFetch APIが来てればこんな悩みもしなかったのにって話でした。

(後でmozSystem:trueの場合でいいからリダイレクトを止めるオプション作りやがれバグはファイルしておくが)