contentSettings パーミッションを試してみた
manifest.json
で permissions
に contentSettings
を含めておくと拡張インストール時の許可さえ得てしまえば、カメラやポップアップの許可設定を拡張側から確認ナシに変更できる。
拡張ポップアップアクション内でカメラを使う許可を取得する
やりたかったのは拡張のポップアップ内でカメラを使いたかっただけなんだがそれを contentSettings
権限を利用して実現するのをとりあえず試してみた。とりあえず以下のような感じで許可を得られた。
chrome.contentSettings.camera.set({
primaryPattern: chrome.runtime.getURL('/*').replace(/^.*?:\/\//,'*://'),
setting: chrome.contentSettings.CameraContentSetting.ALLOW, // 'allow' という文字列
scope: 'regular'
})
注意点としては primaryPattern
にバカ正直に chrome-extension://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/*
をセットしようとすると Invalid scheme.
と怒られてエラーになってしまう。そこで *://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/*
を指定してみたところこれは通ってしまった(それでいいのか…?)。とりあえずこれで目論見通り自分の拡張のポップアップURLに対してちゃんと許可を得ることが出来た。
結論: contentSettings パーミッションは強力すぎるので使わない事にした
しかし自分の拡張内でカメラ許可を得るためだけだと contentSettings
パーミッションは強力すぎるので他の手段を検討したほうが良いという結論になった。例えば適当な拡張内のURLを新しいタブで開いてそこで確認ダイアログを出して許可を得られれば必要十分の結果が得られる。
そもそも manifest.json の仕様には videoCapture
という定義済みパーミッションがあるとされているが少なくとも現時点(Chrome86)ではこれを指定しても何の意味も無いようだ…。
ちなみに、どのへんが強力すぎるかというと『各種機能の権限設定で https://*/*
に対して allow
を設定とかを確認無しでセットする』とかがあっさり出来てしまうので…。
参考:前提として権限のチェック方法
const permissionStatus = await navigator.permissions.query({name:'camera'})
で PermissionState
オブジェクトが取得できて state プロパティに granted
/ prompt
/ denied
のどれかの値が入ってくる。
navigator.permissions.query
がダイアログを出さずに権限の確認だけを行う方法で、その結果が granted
以外だった場合は権限の要求が必要なので、以下のコードで権限要求のダイアログを出す。
const permissionStatus = await navigator.permissions.request({name:'camera'})
これを実行するとブロックするか許可するかのダイアログが出てくる(ただし拡張のポップアップページなどでは実行してもダイアログは出てこない)ので、何かしらアクションをすると query のときと同じように PermissionState
オブジェクトが返ってくる。許可を押した場合は granted
、ブロックした場合は denied
、バツボタンでダイアログを閉じて終わった場合は prompt
な state が得られる。
一度ブロックされてしまった場合の対処法
ここで問題なのはブロックされた場合で、一度ブロックされるとブラウザの設定画面からブロックの解除をしてもらわないといけないのが非常に面倒。ブロックされたときに再要求をする手立て(API)は用意されていない。なのでわかりやすい説明ページを用意するくらいしか出来ない。
contentSettings権限がある場合はブロックを覆せる
contentSettings 権限を持った拡張の場合は一度 denied されたサイト設定を allow で上書きマスクして覆すことが出来る。(サイトに対するブラウザの設定値を上書きするのではなくブラウザの設定値を無視して拡張で作成したサイト設定を強制的に適用させるイメージ)
その効果は拡張がインストールされている限り有効で、サイト設定を上書きした拡張がアンインストールまたは無効化された場合は拡張による上書きマスクがなくなって、元の値が有効になる。