注意
この記事では、LineageOS19.1の環境下でAux Cameraを任意のアプリに対して開放するというスマホとしても、Androidとしても、アプリの用途としても通常用途とは明らかに外れている用法を扱っています。
LineageベースのカスタムROMでは長時間動作させても端末に問題は発生しないことを確認していますが、実際に使用する際は自己責任でお願いします。
あらすじ
きっかけはvdo.ninjaでスマホに搭載されている広角レンズの映像をストリームしたいと思ったことが始まりでした。
vdo.ninjaを用いて配信を行うには大きく分けて方法が2つあり、任意のブラウザーを用いる方法と、flutter製のネイティブアプリを用いる方法の2つがあります。
ネイティブアプリの方は内カメラ・外カメラの切り替えすらもうまく行かなかったので断念しましたが(まだベータ版のようですので今後に期待しています)、Android版Google Chromeなら任意のカメラを表示してくれそうな気配がします。
しかし、実際にやってみると以下のように2つのカメラしか表示されません。
しかし、上記の画像にはcamera2と記載されています。
頑張れば表示できそうなので、詳しく調べることにしました。
調査
アプリ側からのカメラの制御部分は、androidのframeworkが担っています。
他のカスタムOSやAOSP、メーカー独自実装などではどうなっているか確認していませんが、今回私はLineageOSベースのカスタムOSを使用しているので、LineageOS/android_frameworks_baseを参照してみます。
GitHubの検索機能を使い軽く調べたところ、core/java/android/hardware/Camera.java
に気になる記述を発見しました。
|
|
注意: ここから先の記述はソースコードを読んだ筆者による想像です。
この記述によって、vendor.camera.aux.packagelist
というシステムプロパティにパッケージ名が含まれており、かつvendor.camera.aux.packagelist
にパッケージ名が含まれていない場合のみAux Cameraが開放されるという仕組みになっているようです。
Androidでは一般的にカメラID0がバックのメインカメラ、1がフロントのメインカメラ、その後に所謂Aux Cameraと呼ばれているスマホによって搭載されていたりいなかったりする広角・接写レンズ等が続きます。
このshouldExposeAuxCamera()
は別の関数getNumberOfCameras()
などによって呼ばれています。
|
|
このように、カメラを先頭から2つしか見せない、つまりバックメイン、フロントメインしかないかのように見せかけることによって2つ以上のカメラの搭載を想定していないアプリとの互換性を確保している、ということなのだと思います。
しかし全く使えないのでは困るので、ホワイトリスト・ブラックリストを利用して必要なアプリ(カメラアプリが想定されているのだと思います)のみ開放する、といった処理をしているのでしょう。
実践
話が分かればあとは簡単です。
実際にpropsを見てみましょう。
|
|
|
|
この中身を空にすれば全てのアプリにAux Cameraが開放されます。
が、流石にそれだと困ってしまうので(一部起動しただけでクラッシュするアプリがあるので全開放で常用はおすすめしません)、適切なアプリを指定してあげましょう。
注意: Androidのpropsには91byteの長さ制限があります。パッケージを3個以上など大量に詰め込むと文字数を簡単にオーバーします。回避したい場合、ブラックリスト等の活用を検討してください。
|
|
私の場合は8つの選択肢が表示されていますが、実際はカメラは4つしかありません。
その他の選択肢を選ぼうとすると、Chromeがクラッシュします。(そもそも特殊なカメラを普通のカメラのように読み込もようとしているので当たり前といえば当たり前な気もします)
しかしながら、適切な選択肢を選べばその後の動作に支障はないため、これで目的は達成されたと言って良いと思います。
永続化
setprop
で設定したpropsは再起動すると消えてしまうため、用途によっては永続化を行う必要があります。
方法はたくさんありますが、今回は2つ紹介します。
いずれの方法も、編集後は再起動を行って反映を確認してください。
1. build.propsに直接書き込む
systemパーティション直下にあるbuild.propsに直接変更を書き加えてしまう方法です。
簡単ですが、systemlessな方法ではないので、safetynet等の改造検知ソリューションと相性が悪いかもしれません(未確認)。
ファイルに以下のように必要なパッケージを書き加えるだけですが、すでに項目が存在している場合もあるため注意してください。
vendor.camera.aux.packagelist=com.android.chrome
2. Magisk Moduleを作る
こちらの方がSystemlessでMagiskをお使いの場合はベストな選択肢だと思います。
Magiskにはモジュール直下のsystem.prop
をシステムプロパティとして読み込む機能があるため、新しくモジュールを作成するなり他のモジュールに寄生させるなどしてsystem.prop
を作成します。
内容はbuild.props
の項と同じく以下のようなpropを記述したものになります。
vendor.camera.aux.packagelist=com.android.chrome
正しくロードされていれば、loading [system.prop]
と表示されpropの値が変化しているはずです。