Compare commits
188 Commits
Author | SHA1 | Date |
---|---|---|
Simon1511 | 3462aad493 | 2 weeks ago |
Simon1511 | 1ef977c734 | 2 weeks ago |
Simon1511 | f964b2f115 | 2 weeks ago |
Jenna | 61fd2843d4 | 2 weeks ago |
Ruchit Marathe | 986937e5bf | 2 months ago |
Wolfram Liebchen | a5af26bb80 | 2 months ago |
Simon1511 | dcfa38aef8 | 2 months ago |
Bruno Martins | dd1cbc85a5 | 2 months ago |
Steven Moreland | 63c4611bb1 | 2 months ago |
LuK1337 | 55ac486828 | 2 months ago |
Tomasz Wasilczyk | 98ef5a1b55 | 2 months ago |
Tomasz Wasilczyk | 67c9c40da7 | 2 months ago |
Tomasz Wasilczyk | 675f13312a | 2 months ago |
Cole Faust | 21363945a3 | 2 months ago |
Edwin Moquete | 3056a35d9e | 4 months ago |
Simon1511 | 690bd53e19 | 4 months ago |
Simon1511 | 445d3a0cf2 | 4 months ago |
Danny Baumann | 47732025b2 | 4 months ago |
Omkar Chandorkar | 4df4944c4b | 4 months ago |
Simon1511 | 584bfb3556 | 4 months ago |
Simon1511 | ad4ed687f7 | 5 months ago |
Simon1511 | b4602aea30 | 5 months ago |
Simon1511 | 06aca7e31b | 5 months ago |
Tim Zimmermann | 6526837b69 | 5 months ago |
Bruno Martins | 8a0da21487 | 5 months ago |
Bruno Martins | d799e2809f | 5 months ago |
Andy Hung | 5a7d061dca | 5 months ago |
LuK1337 | 26c9c2eab6 | 5 months ago |
LuK1337 | 45dfa77487 | 5 months ago |
LuK1337 | 4b915ce0da | 5 months ago |
Gabriel Biren | 98cce314c3 | 5 months ago |
Simon1511 | bde98b0bb8 | 5 months ago |
Simon1511 | d134d87a8b | 6 months ago |
Simon1511 | 65761014ad | 6 months ago |
Simon1511 | d15040a62a | 7 months ago |
Simon1511 | 30fc583a77 | 7 months ago |
Simon1511 | 64b507b1cf | 7 months ago |
Simon1511 | 93616b944c | 7 months ago |
Tim Zimmermann | f3fc0d615d | 8 months ago |
Ruchit | 66ba3b48ee | 8 months ago |
Ruchit | e1032754c4 | 8 months ago |
Simon1511 | 8798ac7cad | 8 months ago |
Simon1511 | bb83af7561 | 8 months ago |
Simon1511 | 4c38598d88 | 10 months ago |
Simon1511 | d9ac17a62e | 10 months ago |
Simon1511 | 5005f437cf | 10 months ago |
Simon1511 | 2a88cfa9ac | 10 months ago |
Simon1511 | 19005b2e9a | 11 months ago |
Tim Zimmermann | ea551ed57a | 11 months ago |
Alexander Martinz | f298f5b32d | 11 months ago |
Michael Bestas | 55bc3d36ea | 11 months ago |
Simon1511 | 220a5ee0bb | 12 months ago |
Simon1511 | f835fdde00 | 1 year ago |
Simon1511 | f2978af5cc | 1 year ago |
Simon1511 | 56257042ed | 1 year ago |
Bruno Martins | e6273e85a6 | 1 year ago |
Simon1511 | 2e4f5d511c | 1 year ago |
Tim Zimmermann | 62f0858f85 | 1 year ago |
Simon1511 | 5e735a2f3b | 1 year ago |
Tim Zimmerman | e2e5765bff | 1 year ago |
Simon1511 | 948847204f | 1 year ago |
Ruchit | 6e54a54e6e | 1 year ago |
me-cafebabe | 506b0cde3f | 1 year ago |
Simon1511 | 8fc8d3dc52 | 1 year ago |
Jarl-Penguin | 71ec58ca48 | 1 year ago |
Tim Zimmermann | 7d6b2597b3 | 1 year ago |
SamarV-121 | 672f520c90 | 1 year ago |
LuK1337 | 115d7d8e1e | 1 year ago |
Simon1511 | 46f6c478b5 | 1 year ago |
Georg Veichtlbauer | be4e9dcaa1 | 1 year ago |
Ruchit Marathe | 294bed12dc | 1 year ago |
Simon1511 | 9968055bb8 | 1 year ago |
Simon1511 | 4b4ce8c13a | 1 year ago |
Simon1511 | fb6b87d9e0 | 1 year ago |
Aaron Kling | fd171990bc | 1 year ago |
Simon1511 | 82b1fa0ddf | 2 years ago |
Simon1511 | 5d9f802e48 | 2 years ago |
LibXZR | f8e78c2fff | 2 years ago |
Simon1511 | 17125ac89d | 2 years ago |
Simon1511 | 96d068a98d | 2 years ago |
Simon1511 | 6906b52201 | 2 years ago |
Tim Zimmermann | f314d075f9 | 2 years ago |
Simon1511 | ef2932e0c8 | 2 years ago |
johnmart19 | abdd49f532 | 2 years ago |
Ruchit Marathe | 603a606f4c | 2 years ago |
LuK1337 | c5d4085e36 | 2 years ago |
LuK1337 | 07120f399f | 2 years ago |
Danny Lin | 25ea01056f | 2 years ago |
Simon1511 | da8a1faa28 | 2 years ago |
Simon1511 | c240c60951 | 2 years ago |
LuK1337 | ab161d0cb3 | 2 years ago |
Simon1511 | 7337040426 | 2 years ago |
micky387 | bdd3d870b0 | 2 years ago |
Alexander Koskovich | 6ddf30bfdd | 2 years ago |
Tim Zimmermann | 67a982b379 | 2 years ago |
Bruno Martins | f4ccbb4def | 2 years ago |
Josh Wu | 66311be673 | 2 years ago |
Robert Shih | dbc656213a | 2 years ago |
Bruno Martins | cdbdb6b4aa | 2 years ago |
Simon1511 | 3366e02476 | 2 years ago |
Simon1511 | 6bad22afb5 | 2 years ago |
Simon1511 | 68b360f087 | 2 years ago |
Simon1511 | c869ac6233 | 2 years ago |
Jiyong Park | 242d50c271 | 2 years ago |
Simon1511 | cc9d4c162f | 2 years ago |
LuK1337 | 4f4da649aa | 2 years ago |
Alice Kuo | ab25ca7b83 | 2 years ago |
Sal Savage | f248ec1e3c | 2 years ago |
Sal Savage | 7d2ab62023 | 2 years ago |
Sal Savage | caa418734d | 2 years ago |
Sal Savage | 713572a362 | 2 years ago |
Edwin Moquete | e62a12f6c9 | 2 years ago |
Tim Zimmermann | 8353af6942 | 2 years ago |
Simon1511 | 5890d78048 | 2 years ago |
Simon1511 | bc1823a8e3 | 2 years ago |
Simon1511 | 37bc89d8a6 | 2 years ago |
Simon1511 | 958e91d72d | 2 years ago |
Cosmin Tanislav | c1c4ae8953 | 2 years ago |
Cosmin Tanislav | 7b0b484944 | 2 years ago |
Cosmin Tanislav | e74890f56a | 2 years ago |
Cosmin Tanislav | 19a1c19c93 | 2 years ago |
Cosmin Tanislav | 4fc52ef9ac | 2 years ago |
Cosmin Tanislav | 533dd037bc | 2 years ago |
Cosmin Tanislav | 501a23f674 | 2 years ago |
Cosmin Tanislav | 6c1660e670 | 2 years ago |
Cosmin Tanislav | 555bde18e2 | 2 years ago |
Cosmin Tanislav | d9bb55df16 | 2 years ago |
Ruchit Marathe | 11e04d187e | 2 years ago |
Simon1511 | 8b48bee621 | 2 years ago |
Tim Zimmermann | 68bebd1e10 | 2 years ago |
Simon1511 | 4aa24df88b | 2 years ago |
Simon1511 | e7a4e4dfe2 | 2 years ago |
Simon1511 | 98eada9bc5 | 2 years ago |
Ruchit | b99b92a163 | 2 years ago |
TheStrechh | 389202a11c | 2 years ago |
Simon1511 | 722cf693d6 | 2 years ago |
Simon1511 | 96d5c625ac | 2 years ago |
Angga | d8dd60abf9 | 2 years ago |
Arne Coucheron | 8ac3e487d6 | 2 years ago |
Jan Altensen | fc62df5b70 | 2 years ago |
Christian Oder | 8b51b32677 | 2 years ago |
Simon1511 | 0528e6d2ed | 2 years ago |
Simon1511 | 61ba49dfd5 | 2 years ago |
Simon1511 | 188eab9043 | 2 years ago |
Vaisakh Murali | bef2ef0ffa | 2 years ago |
Simon1511 | 24004358ff | 2 years ago |
Simon1511 | f9464bb353 | 2 years ago |
Simon1511 | 3707617171 | 2 years ago |
Ruchit Marathe | 227ba8995b | 2 years ago |
Ruchit Marathe | 31fc8b7781 | 2 years ago |
jabashque | f5289c2f5c | 2 years ago |
Simon1511 | 539a28de28 | 2 years ago |
Pig | fa5ad7d486 | 2 years ago |
Bruno Martins | 9ec542c3dd | 2 years ago |
Jan Altensen | 4f2013c55e | 2 years ago |
Tim Zimmermann | 7d51bb5b9b | 2 years ago |
Simon1511 | 69e1fdb7a8 | 2 years ago |
Simon1511 | b68dc78b23 | 2 years ago |
Simon1511 | 13707d21a9 | 2 years ago |
LuK1337 | c31482154b | 2 years ago |
Rashed Abdel-Tawab | 1c47751006 | 2 years ago |
LuK1337 | 2f752116d0 | 2 years ago |
SamarV-121 | 4f42661f1a | 2 years ago |
Simon1511 | 78e7d6204d | 2 years ago |
Jesse Chan | b3b9ad6114 | 2 years ago |
Simon1511 | d9eab2b98a | 2 years ago |
Simon1511 | 49c927e6d4 | 2 years ago |
Albert Wang | 4ff7f2bc80 | 2 years ago |
Simon1511 | 7778d96e63 | 2 years ago |
Simon1511 | e9841ab663 | 2 years ago |
Simon1511 | cf30811d8a | 2 years ago |
Simon1511 | 75c9b22acc | 2 years ago |
TheScarastic | 3074635364 | 2 years ago |
Lucchetto | 62d07ec32c | 2 years ago |
Simon1511 | e2fcfdcd76 | 2 years ago |
Simon1511 | 44231a2d68 | 2 years ago |
baddar90 | 2845f98f29 | 2 years ago |
Simon1511 | 814ec612a8 | 2 years ago |
Georg Veichtlbauer | 15a943fb0c | 2 years ago |
Simon1511 | c89ca5eda1 | 2 years ago |
Simon1511 | afaaf884d3 | 2 years ago |
Simon1511 | 9e54f108d9 | 2 years ago |
Simon1511 | 92a42fe9eb | 2 years ago |
Simon1511 | ad88487cd0 | 2 years ago |
Simon1511 | 088b8cec4a | 2 years ago |
Tim Zimmermann | 2464864290 | 2 years ago |
Bruno Martins | d5b43f2f02 | 2 years ago |
Xsavi Xander | f83909ee62 | 2 years ago |
@ -0,0 +1,280 @@ |
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> |
||||
|
||||
<audioPolicyConfiguration version="7.0" xmlns:xi="http://www.w3.org/2001/XInclude"> |
||||
|
||||
<globalConfiguration speaker_drc_enabled="false" call_screen_mode_supported="true"/> |
||||
|
||||
<modules> |
||||
<module name="primary" halVersion="2.0"> |
||||
<attachedDevices> |
||||
<item>Earpiece</item> |
||||
<item>Speaker</item> |
||||
<item>Telephony Tx</item> |
||||
<item>Built-In Mic</item> |
||||
<item>Built-In Back Mic</item> |
||||
<item>Telephony Rx</item> |
||||
</attachedDevices> |
||||
|
||||
<defaultOutputDevice>Speaker</defaultOutputDevice> |
||||
|
||||
<mixPorts> |
||||
<mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> |
||||
</mixPort> |
||||
<mixPort name="fast" role="source" flags="AUDIO_OUTPUT_FLAG_FAST"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> |
||||
</mixPort> |
||||
<mixPort name="deep_buffer" role="source" |
||||
flags="AUDIO_OUTPUT_FLAG_DEEP_BUFFER"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_8_24_BIT" |
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> |
||||
</mixPort> |
||||
<mixPort name="mmap_no_irq_out" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_MMAP_NOIRQ"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> |
||||
</mixPort> |
||||
<mixPort name="direct_pcm" role="source" |
||||
flags="AUDIO_OUTPUT_FLAG_DIRECT"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 176400 192000 352800 384000" |
||||
channelMasks="AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_24_BIT_PACKED" |
||||
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 176400 192000 352800 384000" |
||||
channelMasks="AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_8_24_BIT" |
||||
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 176400 192000 352800 384000" |
||||
channelMasks="AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_32_BIT" |
||||
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 176400 192000 352800 384000" |
||||
channelMasks="AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/> |
||||
</mixPort> |
||||
<mixPort name="compressed_offload" role="source" |
||||
flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD AUDIO_OUTPUT_FLAG_NON_BLOCKING"> |
||||
<profile name="" format="AUDIO_FORMAT_MP3" |
||||
samplingRates="11025 16000 22050 32000 44100 48000" |
||||
channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/> |
||||
<profile name="" format="AUDIO_FORMAT_AAC_LC" |
||||
samplingRates="11025 16000 22050 32000 44100 48000" |
||||
channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/> |
||||
<profile name="" format="AUDIO_FORMAT_AAC_HE_V1" |
||||
samplingRates="11025 16000 22050 32000 44100 48000" |
||||
channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/> |
||||
<profile name="" format="AUDIO_FORMAT_AAC_HE_V2" |
||||
samplingRates="11025 16000 22050 32000 44100 48000" |
||||
channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/> |
||||
<profile name="" format="AUDIO_FORMAT_FLAC" |
||||
samplingRates="11025 16000 22050 32000 44100 48000" |
||||
channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/> |
||||
</mixPort> |
||||
<mixPort name="primary input" role="sink"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000" |
||||
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/> |
||||
</mixPort> |
||||
<mixPort name="usb_surround_sound" role="sink"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 88200 96000 176400 192000" |
||||
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_INDEX_MASK_3 AUDIO_CHANNEL_INDEX_MASK_4 AUDIO_CHANNEL_IN_5POINT1 AUDIO_CHANNEL_INDEX_MASK_6 AUDIO_CHANNEL_IN_7POINT1 AUDIO_CHANNEL_INDEX_MASK_8"/> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_32_BIT" |
||||
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 88200 96000 176400 192000" |
||||
channelMasks="AUDIO_CHANNEL_IN_5POINT1 AUDIO_CHANNEL_INDEX_MASK_6 AUDIO_CHANNEL_IN_7POINT1 AUDIO_CHANNEL_INDEX_MASK_8"/> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_FLOAT" |
||||
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 88200 96000 176400 192000" |
||||
channelMasks="AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_INDEX_MASK_2 AUDIO_CHANNEL_IN_5POINT1 AUDIO_CHANNEL_INDEX_MASK_6 AUDIO_CHANNEL_IN_7POINT1 AUDIO_CHANNEL_INDEX_MASK_8"/> |
||||
</mixPort> |
||||
<mixPort name="voice_tx" role="source"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000 16000 48000" channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO"/> |
||||
</mixPort> |
||||
<mixPort name="incall_music_uplink" role="source" flags="AUDIO_OUTPUT_FLAG_INCALL_MUSIC"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000 16000 48000" |
||||
channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> |
||||
</mixPort> |
||||
<mixPort name="mmap_no_irq_in" role="sink" flags="AUDIO_INPUT_FLAG_MMAP_NOIRQ"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000" |
||||
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_INDEX_MASK_3"/> |
||||
</mixPort> |
||||
<mixPort name="voip_rx" role="source" |
||||
flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_VOIP_RX"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000 16000 32000 48000" channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO"/> |
||||
</mixPort> |
||||
<mixPort name="voip_tx" role="sink" |
||||
flags="AUDIO_INPUT_FLAG_VOIP_TX"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000 16000 32000 48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/> |
||||
</mixPort> |
||||
<mixPort name="voice_rx" role="sink"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000 16000 48000" channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO"/> |
||||
</mixPort> |
||||
<mixPort name="hifi_playback" role="source" /> |
||||
<mixPort name="hifi_input" role="sink" /> |
||||
</mixPorts> |
||||
<devicePorts> |
||||
<!-- Output devices declaration, i.e. Sink DEVICE PORT --> |
||||
<devicePort tagName="Earpiece" role="sink" type="AUDIO_DEVICE_OUT_EARPIECE"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/> |
||||
</devicePort> |
||||
<devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> |
||||
</devicePort> |
||||
<devicePort tagName="Wired Headset" role="sink" type="AUDIO_DEVICE_OUT_WIRED_HEADSET"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> |
||||
</devicePort> |
||||
<devicePort tagName="Wired Headphones" role="sink" type="AUDIO_DEVICE_OUT_WIRED_HEADPHONE"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> |
||||
</devicePort> |
||||
<devicePort tagName="BT SCO" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO" role="sink"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> |
||||
</devicePort> |
||||
<devicePort tagName="BT SCO Headset" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET" role="sink"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> |
||||
</devicePort> |
||||
<devicePort tagName="BT SCO Car Kit" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT" role="sink"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> |
||||
</devicePort> |
||||
<devicePort tagName="Telephony Tx" type="AUDIO_DEVICE_OUT_TELEPHONY_TX" role="sink"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000 16000" channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO"/> |
||||
</devicePort> |
||||
<devicePort tagName="Aux Device Out" role="sink" type="AUDIO_DEVICE_OUT_AUX_DIGITAL"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="44100 48000 64000 88200 96000 128000 176400 192000" |
||||
channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/> |
||||
</devicePort> |
||||
<devicePort tagName="USB Device Out" type="AUDIO_DEVICE_OUT_USB_DEVICE" role="sink"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="44100 48000 64000 88200 96000 128000 176400 192000"/> |
||||
</devicePort> |
||||
<devicePort tagName="USB Headset Out" type="AUDIO_DEVICE_OUT_USB_HEADSET" role="sink"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="44100 48000 64000 88200 96000 128000 176400 192000"/> |
||||
</devicePort> |
||||
<!-- Input devices declaration, i.e. source DEVICE PORT --> |
||||
<devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000" |
||||
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_IN_VOICE_UPLINK AUDIO_CHANNEL_IN_VOICE_DNLINK"/> |
||||
</devicePort> |
||||
<devicePort tagName="Built-In Back Mic" type="AUDIO_DEVICE_IN_BACK_MIC" role="source"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000" |
||||
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_IN_VOICE_UPLINK AUDIO_CHANNEL_IN_VOICE_DNLINK"/> |
||||
</devicePort> |
||||
<devicePort tagName="Wired Headset Mic" type="AUDIO_DEVICE_IN_WIRED_HEADSET" role="source"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000" |
||||
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_IN_VOICE_UPLINK AUDIO_CHANNEL_IN_VOICE_DNLINK"/> |
||||
</devicePort> |
||||
<devicePort tagName="Bt Sco Headset Mic" type="AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET" role="source"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000" |
||||
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_IN_VOICE_UPLINK AUDIO_CHANNEL_IN_VOICE_DNLINK"/> |
||||
</devicePort> |
||||
<devicePort tagName="Aux Device In" type="AUDIO_DEVICE_IN_AUX_DIGITAL" role="source"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000" |
||||
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_IN_VOICE_UPLINK AUDIO_CHANNEL_IN_VOICE_DNLINK"/> |
||||
</devicePort> |
||||
<devicePort tagName="Telephony Rx" type="AUDIO_DEVICE_IN_TELEPHONY_RX" role="source"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000" |
||||
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_IN_VOICE_UPLINK AUDIO_CHANNEL_IN_VOICE_DNLINK"/> |
||||
</devicePort> |
||||
<devicePort tagName="FM Tuner" type="AUDIO_DEVICE_IN_FM_TUNER" role="source"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000" |
||||
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_IN_VOICE_UPLINK AUDIO_CHANNEL_IN_VOICE_DNLINK"/> |
||||
</devicePort> |
||||
<devicePort tagName="USB Device In" type="AUDIO_DEVICE_IN_USB_DEVICE" role="source"> |
||||
</devicePort> |
||||
<devicePort tagName="USB Headset In" type="AUDIO_DEVICE_IN_USB_HEADSET" role="source"> |
||||
</devicePort> |
||||
</devicePorts> |
||||
<!-- route declaration, i.e. list all available sources for a given sink --> |
||||
<routes> |
||||
<route type="mix" sink="Earpiece" |
||||
sources="primary output,deep_buffer,fast,compressed_offload"/> |
||||
<route type="mix" sink="Speaker" |
||||
sources="primary output,deep_buffer,fast,compressed_offload,mmap_no_irq_out"/> |
||||
<route type="mix" sink="Wired Headset" |
||||
sources="primary output,deep_buffer,fast,compressed_offload,mmap_no_irq_out"/> |
||||
<route type="mix" sink="Wired Headphones" |
||||
sources="primary output,deep_buffer,fast,compressed_offload,mmap_no_irq_out"/> |
||||
<route type="mix" sink="USB Device Out" |
||||
sources="primary output,deep_buffer,fast,direct_pcm,compressed_offload,mmap_no_irq_out,hifi_playback"/> |
||||
<route type="mix" sink="USB Headset Out" |
||||
sources="primary output,deep_buffer,fast,direct_pcm,compressed_offload,mmap_no_irq_out,hifi_playback"/> |
||||
<route type="mix" sink="usb_surround_sound" |
||||
sources="USB Device In,USB Headset In"/> |
||||
<route type="mix" sink="hifi_input" |
||||
sources="USB Device In,USB Headset In"/> |
||||
<route type="mix" sink="BT SCO" |
||||
sources="primary output,deep_buffer,fast,voip_rx"/> |
||||
<route type="mix" sink="BT SCO Headset" |
||||
sources="primary output,deep_buffer,fast,voip_rx"/> |
||||
<route type="mix" sink="BT SCO Car Kit" |
||||
sources="primary output,deep_buffer,fast,voip_rx"/> |
||||
<route type="mix" sink="Telephony Tx" |
||||
sources="voice_tx,incall_music_uplink"/> |
||||
<route type="mix" sink="voice_rx" |
||||
sources="Telephony Rx"/> |
||||
<route type="mix" sink="voip_tx" |
||||
sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,Bt Sco Headset Mic,Aux Device In,FM Tuner,USB Device In,USB Headset In"/> |
||||
<route type="mix" sink="primary input" |
||||
sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,Bt Sco Headset Mic,Aux Device In,FM Tuner,USB Device In,USB Headset In,Telephony Rx"/> |
||||
<route type="mix" sink="mmap_no_irq_in" |
||||
sources="Built-In Mic,Built-In Back Mic,USB Device In,USB Headset In"/> |
||||
</routes> |
||||
|
||||
</module> |
||||
|
||||
<!-- Remote Submix Audio HAL --> |
||||
<xi:include href="r_submix_audio_policy_configuration.xml"/> |
||||
|
||||
<!-- Bluetooth Audio HAL --> |
||||
<xi:include href="bluetooth_audio_policy_configuration_7_0.xml"/> |
||||
|
||||
<!-- USB Audio HAL --> |
||||
<module name="usb" halVersion="2.0"> |
||||
<mixPorts> |
||||
<mixPort name="usb_accessory output" role="source"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="44100" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> |
||||
</mixPort> |
||||
</mixPorts> |
||||
<devicePorts> |
||||
<devicePort tagName="USB Host Out" type="AUDIO_DEVICE_OUT_USB_ACCESSORY" role="sink"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="44100" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> |
||||
</devicePort> |
||||
</devicePorts> |
||||
<routes> |
||||
<route type="mix" sink="USB Host Out" |
||||
sources="usb_accessory output"/> |
||||
</routes> |
||||
</module> |
||||
|
||||
</modules> |
||||
<!-- End of Modules section --> |
||||
|
||||
<!-- Volume section --> |
||||
|
||||
<xi:include href="audio_policy_volumes.xml"/> |
||||
<xi:include href="default_volume_tables.xml"/> |
||||
|
||||
<!-- End of Volume section --> |
||||
|
||||
</audioPolicyConfiguration> |
@ -0,0 +1,171 @@ |
||||
filegroup { |
||||
name: "android.hardware.audio-impl_sm7125_srcs", |
||||
srcs: [ |
||||
"Device.cpp", |
||||
"DevicesFactory.cpp", |
||||
"ParametersUtil.cpp", |
||||
"PrimaryDevice.cpp", |
||||
"Stream.cpp", |
||||
"StreamIn.cpp", |
||||
"StreamOut.cpp", |
||||
], |
||||
} |
||||
|
||||
cc_library_headers { |
||||
name: "android.hardware.audio-impl_sm7125_headers", |
||||
proprietary: true, |
||||
vendor: true, |
||||
export_include_dirs: ["include"], |
||||
} |
||||
|
||||
cc_defaults { |
||||
name: "android.hardware.audio-impl_sm7125", |
||||
relative_install_path: "hw", |
||||
proprietary: true, |
||||
vendor: true, |
||||
srcs: [":android.hardware.audio-impl_sm7125_srcs"], |
||||
|
||||
defaults: ["hidl_defaults"], |
||||
|
||||
static_libs: [ |
||||
"libaudiofoundation", |
||||
], |
||||
|
||||
shared_libs: [ |
||||
"libbase", |
||||
"libcutils", |
||||
"libfmq", |
||||
"libhardware", |
||||
"libhidlbase", |
||||
"liblog", |
||||
"libmedia_helper", |
||||
"libmediautils_vendor", |
||||
"libmemunreachable", |
||||
"libutils", |
||||
"android.hardware.audio.common-util", |
||||
], |
||||
|
||||
header_libs: [ |
||||
"android.hardware.audio-impl_sm7125_headers", |
||||
"android.hardware.audio.common.util@all-versions", |
||||
"libaudioutils_headers", |
||||
"libaudio_system_headers", |
||||
"libhardware_headers", |
||||
"libmedia_headers", |
||||
"libmediautils_headers", |
||||
], |
||||
|
||||
export_header_lib_headers: [ |
||||
"android.hardware.audio-impl_sm7125_headers", |
||||
], |
||||
} |
||||
|
||||
cc_library_shared { |
||||
name: "android.hardware.audio@2.0-impl.sm7125", |
||||
defaults: ["android.hardware.audio-impl_sm7125"], |
||||
shared_libs: [ |
||||
"android.hardware.audio@2.0", |
||||
"android.hardware.audio@2.0-util", |
||||
"android.hardware.audio.common@2.0", |
||||
"android.hardware.audio.common@2.0-util", |
||||
"libcutils", |
||||
], |
||||
cflags: [ |
||||
"-DMAJOR_VERSION=2", |
||||
"-DMINOR_VERSION=0", |
||||
"-include common/all-versions/VersionMacro.h", |
||||
], |
||||
} |
||||
|
||||
cc_library_shared { |
||||
name: "android.hardware.audio@4.0-impl.sm7125", |
||||
defaults: ["android.hardware.audio-impl_sm7125"], |
||||
|
||||
shared_libs: [ |
||||
"android.hardware.audio@4.0", |
||||
"android.hardware.audio@4.0-util", |
||||
"android.hardware.audio.common@4.0", |
||||
"android.hardware.audio.common@4.0-util", |
||||
"libcutils", |
||||
], |
||||
cflags: [ |
||||
"-DMAJOR_VERSION=4", |
||||
"-DMINOR_VERSION=0", |
||||
"-include common/all-versions/VersionMacro.h", |
||||
], |
||||
} |
||||
|
||||
cc_library_shared { |
||||
name: "android.hardware.audio@5.0-impl.sm7125", |
||||
defaults: ["android.hardware.audio-impl_sm7125"], |
||||
shared_libs: [ |
||||
"android.hardware.audio@5.0", |
||||
"android.hardware.audio@5.0-util", |
||||
"android.hardware.audio.common@5.0", |
||||
"android.hardware.audio.common@5.0-util", |
||||
"libcutils", |
||||
], |
||||
cflags: [ |
||||
"-DMAJOR_VERSION=5", |
||||
"-DMINOR_VERSION=0", |
||||
"-include common/all-versions/VersionMacro.h", |
||||
], |
||||
} |
||||
|
||||
cc_library_shared { |
||||
name: "android.hardware.audio@6.0-impl.sm7125", |
||||
defaults: ["android.hardware.audio-impl_sm7125"], |
||||
shared_libs: [ |
||||
"android.hardware.audio@6.0", |
||||
"android.hardware.audio@6.0-util", |
||||
"android.hardware.audio.common@6.0", |
||||
"android.hardware.audio.common@6.0-util", |
||||
"libcutils", |
||||
], |
||||
cflags: [ |
||||
"-DMAJOR_VERSION=6", |
||||
"-DMINOR_VERSION=0", |
||||
"-include common/all-versions/VersionMacro.h", |
||||
], |
||||
} |
||||
|
||||
cc_library_shared { |
||||
name: "android.hardware.audio@7.0-impl.sm7125", |
||||
defaults: ["android.hardware.audio-impl_sm7125"], |
||||
shared_libs: [ |
||||
"android.hardware.audio@7.0", |
||||
"android.hardware.audio@7.0-util", |
||||
"android.hardware.audio.common@7.0", |
||||
"android.hardware.audio.common@7.0-enums", |
||||
"android.hardware.audio.common@7.0-util", |
||||
"libbase", |
||||
"libcutils", |
||||
], |
||||
cflags: [ |
||||
"-DMAJOR_VERSION=7", |
||||
"-DMINOR_VERSION=0", |
||||
"-include common/all-versions/VersionMacro.h", |
||||
], |
||||
} |
||||
|
||||
cc_library_shared { |
||||
name: "android.hardware.audio@7.1-impl.sm7125", |
||||
defaults: ["android.hardware.audio-impl_sm7125"], |
||||
shared_libs: [ |
||||
"android.hardware.audio@7.0", |
||||
"android.hardware.audio@7.1", |
||||
"android.hardware.audio@7.1-util", |
||||
"android.hardware.audio.common@7.0", |
||||
"android.hardware.audio.common@7.1-enums", |
||||
"android.hardware.audio.common@7.1-util", |
||||
"libbase", |
||||
"libcutils", |
||||
], |
||||
cflags: [ |
||||
"-DMAJOR_VERSION=7", |
||||
"-DMINOR_VERSION=1", |
||||
"-DCOMMON_TYPES_MINOR_VERSION=0", |
||||
"-DCORE_TYPES_MINOR_VERSION=0", |
||||
"-include common/all-versions/VersionMacro.h", |
||||
], |
||||
} |
@ -0,0 +1,635 @@ |
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#define LOG_TAG "DeviceHAL" |
||||
|
||||
#include "core/default/Device.h" |
||||
#include "common/all-versions/default/EffectMap.h" |
||||
#include "core/default/StreamIn.h" |
||||
#include "core/default/StreamOut.h" |
||||
#include "core/default/Util.h" |
||||
|
||||
//#define LOG_NDEBUG 0
|
||||
|
||||
#include <inttypes.h> |
||||
#include <memory.h> |
||||
#include <string.h> |
||||
#include <algorithm> |
||||
|
||||
#include <android/log.h> |
||||
#include <hidl/HidlTransportSupport.h> |
||||
#include <mediautils/MemoryLeakTrackUtil.h> |
||||
#include <memunreachable/memunreachable.h> |
||||
|
||||
#include <HidlUtils.h> |
||||
|
||||
namespace android { |
||||
namespace hardware { |
||||
namespace audio { |
||||
namespace CPP_VERSION { |
||||
namespace implementation { |
||||
|
||||
using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils; |
||||
namespace util { |
||||
using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::util; |
||||
} |
||||
|
||||
Device::Device(audio_hw_device_t* device) : mIsClosed(false), mDevice(device) {} |
||||
|
||||
Device::~Device() { |
||||
(void)doClose(); |
||||
mDevice = nullptr; |
||||
} |
||||
|
||||
Result Device::analyzeStatus(const char* funcName, int status, |
||||
const std::vector<int>& ignoreErrors) { |
||||
return util::analyzeStatus("Device", funcName, status, ignoreErrors); |
||||
} |
||||
|
||||
void Device::closeInputStream(audio_stream_in_t* stream) { |
||||
mDevice->close_input_stream(mDevice, stream); |
||||
LOG_ALWAYS_FATAL_IF(mOpenedStreamsCount == 0, "mOpenedStreamsCount is already 0"); |
||||
--mOpenedStreamsCount; |
||||
} |
||||
|
||||
void Device::closeOutputStream(audio_stream_out_t* stream) { |
||||
mDevice->close_output_stream(mDevice, stream); |
||||
LOG_ALWAYS_FATAL_IF(mOpenedStreamsCount == 0, "mOpenedStreamsCount is already 0"); |
||||
--mOpenedStreamsCount; |
||||
} |
||||
|
||||
char* Device::halGetParameters(const char* keys) { |
||||
return mDevice->get_parameters(mDevice, keys); |
||||
} |
||||
|
||||
int Device::halSetParameters(const char* keysAndValues) { |
||||
return mDevice->set_parameters(mDevice, keysAndValues); |
||||
} |
||||
|
||||
// Methods from ::android::hardware::audio::CPP_VERSION::IDevice follow.
|
||||
Return<Result> Device::initCheck() { |
||||
return analyzeStatus("init_check", mDevice->init_check(mDevice)); |
||||
} |
||||
|
||||
Return<Result> Device::setMasterVolume(float volume) { |
||||
if (mDevice->set_master_volume == NULL) { |
||||
return Result::NOT_SUPPORTED; |
||||
} |
||||
if (!util::isGainNormalized(volume)) { |
||||
ALOGW("Can not set a master volume (%f) outside [0,1]", volume); |
||||
return Result::INVALID_ARGUMENTS; |
||||
} |
||||
return analyzeStatus("set_master_volume", mDevice->set_master_volume(mDevice, volume), |
||||
{ENOSYS} /*ignore*/); |
||||
} |
||||
|
||||
Return<void> Device::getMasterVolume(getMasterVolume_cb _hidl_cb) { |
||||
Result retval(Result::NOT_SUPPORTED); |
||||
float volume = 0; |
||||
if (mDevice->get_master_volume != NULL) { |
||||
retval = analyzeStatus("get_master_volume", mDevice->get_master_volume(mDevice, &volume), |
||||
{ENOSYS} /*ignore*/); |
||||
} |
||||
_hidl_cb(retval, volume); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<Result> Device::setMicMute(bool mute) { |
||||
return analyzeStatus("set_mic_mute", mDevice->set_mic_mute(mDevice, mute), {ENOSYS} /*ignore*/); |
||||
} |
||||
|
||||
Return<void> Device::getMicMute(getMicMute_cb _hidl_cb) { |
||||
bool mute = false; |
||||
Result retval = analyzeStatus("get_mic_mute", mDevice->get_mic_mute(mDevice, &mute), |
||||
{ENOSYS} /*ignore*/); |
||||
_hidl_cb(retval, mute); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<Result> Device::setMasterMute(bool mute) { |
||||
Result retval(Result::NOT_SUPPORTED); |
||||
if (mDevice->set_master_mute != NULL) { |
||||
retval = analyzeStatus("set_master_mute", mDevice->set_master_mute(mDevice, mute), |
||||
{ENOSYS} /*ignore*/); |
||||
} |
||||
return retval; |
||||
} |
||||
|
||||
Return<void> Device::getMasterMute(getMasterMute_cb _hidl_cb) { |
||||
Result retval(Result::NOT_SUPPORTED); |
||||
bool mute = false; |
||||
if (mDevice->get_master_mute != NULL) { |
||||
retval = analyzeStatus("get_master_mute", mDevice->get_master_mute(mDevice, &mute), |
||||
{ENOSYS} /*ignore*/); |
||||
} |
||||
_hidl_cb(retval, mute); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<void> Device::getInputBufferSize(const AudioConfig& config, getInputBufferSize_cb _hidl_cb) { |
||||
audio_config_t halConfig; |
||||
Result retval(Result::INVALID_ARGUMENTS); |
||||
uint64_t bufferSize = 0; |
||||
if (HidlUtils::audioConfigToHal(config, &halConfig) == NO_ERROR) { |
||||
size_t halBufferSize = mDevice->get_input_buffer_size(mDevice, &halConfig); |
||||
if (halBufferSize != 0) { |
||||
retval = Result::OK; |
||||
bufferSize = halBufferSize; |
||||
} |
||||
} |
||||
_hidl_cb(retval, bufferSize); |
||||
return Void(); |
||||
} |
||||
|
||||
std::tuple<Result, sp<IStreamOut>> Device::openOutputStreamCore(int32_t ioHandle, |
||||
const DeviceAddress& device, |
||||
const AudioConfig& config, |
||||
const AudioOutputFlags& flags, |
||||
AudioConfig* suggestedConfig) { |
||||
audio_config_t halConfig; |
||||
if (HidlUtils::audioConfigToHal(config, &halConfig) != NO_ERROR) { |
||||
return {Result::INVALID_ARGUMENTS, nullptr}; |
||||
} |
||||
audio_stream_out_t* halStream; |
||||
audio_devices_t halDevice; |
||||
char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN]; |
||||
if (CoreUtils::deviceAddressToHal(device, &halDevice, halDeviceAddress) != NO_ERROR) { |
||||
return {Result::INVALID_ARGUMENTS, nullptr}; |
||||
} |
||||
audio_output_flags_t halFlags; |
||||
if (CoreUtils::audioOutputFlagsToHal(flags, &halFlags) != NO_ERROR) { |
||||
return {Result::INVALID_ARGUMENTS, nullptr}; |
||||
} |
||||
ALOGV("open_output_stream handle: %d devices: %x flags: %#x " |
||||
"srate: %d format %#x channels %x address %s", |
||||
ioHandle, halDevice, halFlags, halConfig.sample_rate, halConfig.format, |
||||
halConfig.channel_mask, halDeviceAddress); |
||||
int status = mDevice->open_output_stream(mDevice, ioHandle, halDevice, halFlags, &halConfig, |
||||
&halStream, halDeviceAddress); |
||||
ALOGV("open_output_stream status %d stream %p", status, halStream); |
||||
sp<IStreamOut> streamOut; |
||||
if (status == OK) { |
||||
streamOut = new StreamOut(this, halStream); |
||||
++mOpenedStreamsCount; |
||||
android::hardware::setMinSchedulerPolicy(streamOut, SCHED_NORMAL, ANDROID_PRIORITY_AUDIO); |
||||
} |
||||
status_t convertStatus = |
||||
HidlUtils::audioConfigFromHal(halConfig, false /*isInput*/, suggestedConfig); |
||||
ALOGW_IF(convertStatus != OK, "%s: suggested config with incompatible fields", __func__); |
||||
return {analyzeStatus("open_output_stream", status, {EINVAL} /*ignore*/), streamOut}; |
||||
} |
||||
|
||||
std::tuple<Result, sp<IStreamIn>> Device::openInputStreamCore( |
||||
int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config, |
||||
const AudioInputFlags& flags, AudioSource source, AudioConfig* suggestedConfig) { |
||||
audio_config_t halConfig; |
||||
if (HidlUtils::audioConfigToHal(config, &halConfig) != NO_ERROR) { |
||||
return {Result::INVALID_ARGUMENTS, nullptr}; |
||||
} |
||||
audio_stream_in_t* halStream; |
||||
audio_devices_t halDevice; |
||||
char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN]; |
||||
if (CoreUtils::deviceAddressToHal(device, &halDevice, halDeviceAddress) != NO_ERROR) { |
||||
return {Result::INVALID_ARGUMENTS, nullptr}; |
||||
} |
||||
audio_input_flags_t halFlags; |
||||
audio_source_t halSource; |
||||
if (CoreUtils::audioInputFlagsToHal(flags, &halFlags) != NO_ERROR || |
||||
HidlUtils::audioSourceToHal(source, &halSource) != NO_ERROR) { |
||||
return {Result::INVALID_ARGUMENTS, nullptr}; |
||||
} |
||||
ALOGV("open_input_stream handle: %d devices: %x flags: %#x " |
||||
"srate: %d format %#x channels %x address %s source %d", |
||||
ioHandle, halDevice, halFlags, halConfig.sample_rate, halConfig.format, |
||||
halConfig.channel_mask, halDeviceAddress, halSource); |
||||
int status = mDevice->open_input_stream(mDevice, ioHandle, halDevice, &halConfig, &halStream, |
||||
halFlags, halDeviceAddress, halSource); |
||||
ALOGV("open_input_stream status %d stream %p", status, halStream); |
||||
sp<IStreamIn> streamIn; |
||||
if (status == OK) { |
||||
streamIn = new StreamIn(this, halStream); |
||||
++mOpenedStreamsCount; |
||||
android::hardware::setMinSchedulerPolicy(streamIn, SCHED_NORMAL, ANDROID_PRIORITY_AUDIO); |
||||
} |
||||
status_t convertStatus = |
||||
HidlUtils::audioConfigFromHal(halConfig, true /*isInput*/, suggestedConfig); |
||||
ALOGW_IF(convertStatus != OK, "%s: suggested config with incompatible fields", __func__); |
||||
return {analyzeStatus("open_input_stream", status, {EINVAL} /*ignore*/), streamIn}; |
||||
} |
||||
|
||||
#if MAJOR_VERSION == 2 |
||||
Return<void> Device::openOutputStream(int32_t ioHandle, const DeviceAddress& device, |
||||
const AudioConfig& config, AudioOutputFlags flags, |
||||
openOutputStream_cb _hidl_cb) { |
||||
AudioConfig suggestedConfig; |
||||
auto [result, streamOut] = |
||||
openOutputStreamCore(ioHandle, device, config, flags, &suggestedConfig); |
||||
_hidl_cb(result, streamOut, suggestedConfig); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<void> Device::openInputStream(int32_t ioHandle, const DeviceAddress& device, |
||||
const AudioConfig& config, AudioInputFlags flags, |
||||
AudioSource source, openInputStream_cb _hidl_cb) { |
||||
AudioConfig suggestedConfig; |
||||
auto [result, streamIn] = |
||||
openInputStreamCore(ioHandle, device, config, flags, source, &suggestedConfig); |
||||
_hidl_cb(result, streamIn, suggestedConfig); |
||||
return Void(); |
||||
} |
||||
|
||||
#elif MAJOR_VERSION >= 4 |
||||
std::tuple<Result, sp<IStreamOut>, AudioConfig> Device::openOutputStreamImpl( |
||||
int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config, |
||||
const SourceMetadata& sourceMetadata, |
||||
#if MAJOR_VERSION <= 6 |
||||
AudioOutputFlags flags) { |
||||
if (status_t status = CoreUtils::sourceMetadataToHal(sourceMetadata, nullptr); |
||||
status != NO_ERROR) { |
||||
#else |
||||
const AudioOutputFlags& flags) { |
||||
if (status_t status = CoreUtils::sourceMetadataToHalV7(sourceMetadata, |
||||
false /*ignoreNonVendorTags*/, nullptr); |
||||
status != NO_ERROR) { |
||||
#endif |
||||
return {analyzeStatus("sourceMetadataToHal", status), nullptr, {}}; |
||||
} |
||||
AudioConfig suggestedConfig; |
||||
auto [result, streamOut] = |
||||
openOutputStreamCore(ioHandle, device, config, flags, &suggestedConfig); |
||||
if (streamOut) { |
||||
streamOut->updateSourceMetadata(sourceMetadata); |
||||
} |
||||
return {result, streamOut, suggestedConfig}; |
||||
} |
||||
|
||||
Return<void> Device::openOutputStream(int32_t ioHandle, const DeviceAddress& device, |
||||
const AudioConfig& config, |
||||
#if MAJOR_VERSION <= 6 |
||||
AudioOutputFlags flags, |
||||
#else |
||||
const AudioOutputFlags& flags, |
||||
#endif |
||||
const SourceMetadata& sourceMetadata, |
||||
openOutputStream_cb _hidl_cb) { |
||||
auto [result, streamOut, suggestedConfig] = |
||||
openOutputStreamImpl(ioHandle, device, config, sourceMetadata, flags); |
||||
_hidl_cb(result, streamOut, suggestedConfig); |
||||
return Void(); |
||||
} |
||||
|
||||
std::tuple<Result, sp<IStreamIn>, AudioConfig> Device::openInputStreamImpl( |
||||
int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config, |
||||
#if MAJOR_VERSION <= 6 |
||||
AudioInputFlags flags, |
||||
#else |
||||
const AudioInputFlags& flags, |
||||
#endif |
||||
const SinkMetadata& sinkMetadata) { |
||||
if (sinkMetadata.tracks.size() == 0) { |
||||
// This should never happen, the framework must not create as stream
|
||||
// if there is no client
|
||||
ALOGE("openInputStream called without tracks connected"); |
||||
return {Result::INVALID_ARGUMENTS, nullptr, AudioConfig{}}; |
||||
} |
||||
#if MAJOR_VERSION <= 6 |
||||
if (status_t status = CoreUtils::sinkMetadataToHal(sinkMetadata, nullptr); status != NO_ERROR) { |
||||
#else |
||||
if (status_t status = CoreUtils::sinkMetadataToHalV7(sinkMetadata, |
||||
false /*ignoreNonVendorTags*/, nullptr); |
||||
status != NO_ERROR) { |
||||
#endif |
||||
return {analyzeStatus("sinkMetadataToHal", status), nullptr, AudioConfig{}}; |
||||
} |
||||
// Pick the first one as the main.
|
||||
AudioSource source = sinkMetadata.tracks[0].source; |
||||
AudioConfig suggestedConfig; |
||||
auto [result, streamIn] = |
||||
openInputStreamCore(ioHandle, device, config, flags, source, &suggestedConfig); |
||||
if (streamIn) { |
||||
streamIn->updateSinkMetadata(sinkMetadata); |
||||
} |
||||
return {result, streamIn, suggestedConfig}; |
||||
} |
||||
|
||||
Return<void> Device::openInputStream(int32_t ioHandle, const DeviceAddress& device, |
||||
const AudioConfig& config, |
||||
#if MAJOR_VERSION <= 6 |
||||
AudioInputFlags flags, |
||||
#else |
||||
const AudioInputFlags& flags, |
||||
#endif |
||||
const SinkMetadata& sinkMetadata, |
||||
openInputStream_cb _hidl_cb) { |
||||
auto [result, streamIn, suggestedConfig] = |
||||
openInputStreamImpl(ioHandle, device, config, flags, sinkMetadata); |
||||
_hidl_cb(result, streamIn, suggestedConfig); |
||||
return Void(); |
||||
} |
||||
#endif /* MAJOR_VERSION */ |
||||
|
||||
#if MAJOR_VERSION == 7 && MINOR_VERSION == 1 |
||||
Return<void> Device::openOutputStream_7_1(int32_t ioHandle, const DeviceAddress& device, |
||||
const AudioConfig& config, const AudioOutputFlags& flags, |
||||
const SourceMetadata& sourceMetadata, |
||||
openOutputStream_7_1_cb _hidl_cb) { |
||||
auto [result, streamOut, suggestedConfig] = |
||||
openOutputStreamImpl(ioHandle, device, config, sourceMetadata, flags); |
||||
_hidl_cb(result, streamOut, suggestedConfig); |
||||
return Void(); |
||||
} |
||||
#endif // V7.1
|
||||
|
||||
Return<bool> Device::supportsAudioPatches() { |
||||
return version() >= AUDIO_DEVICE_API_VERSION_3_0; |
||||
} |
||||
|
||||
Return<void> Device::createAudioPatch(const hidl_vec<AudioPortConfig>& sources, |
||||
const hidl_vec<AudioPortConfig>& sinks, |
||||
createAudioPatch_cb _hidl_cb) { |
||||
auto [retval, patch] = createOrUpdateAudioPatch(AudioPatchHandle{}, sources, sinks); |
||||
_hidl_cb(retval, patch); |
||||
return Void(); |
||||
} |
||||
|
||||
std::tuple<Result, AudioPatchHandle> Device::createOrUpdateAudioPatch( |
||||
AudioPatchHandle patch, const hidl_vec<AudioPortConfig>& sources, |
||||
const hidl_vec<AudioPortConfig>& sinks) { |
||||
Result retval(Result::NOT_SUPPORTED); |
||||
if (version() >= AUDIO_DEVICE_API_VERSION_3_0) { |
||||
audio_patch_handle_t halPatch = static_cast<audio_patch_handle_t>(patch); |
||||
std::unique_ptr<audio_port_config[]> halSources; |
||||
if (status_t status = HidlUtils::audioPortConfigsToHal(sources, &halSources); |
||||
status != NO_ERROR) { |
||||
return {analyzeStatus("audioPortConfigsToHal;sources", status), patch}; |
||||
} |
||||
std::unique_ptr<audio_port_config[]> halSinks; |
||||
if (status_t status = HidlUtils::audioPortConfigsToHal(sinks, &halSinks); |
||||
status != NO_ERROR) { |
||||
return {analyzeStatus("audioPortConfigsToHal;sinks", status), patch}; |
||||
} |
||||
retval = analyzeStatus("create_audio_patch", |
||||
mDevice->create_audio_patch(mDevice, sources.size(), &halSources[0], |
||||
sinks.size(), &halSinks[0], &halPatch)); |
||||
if (retval == Result::OK) { |
||||
patch = static_cast<AudioPatchHandle>(halPatch); |
||||
} |
||||
} |
||||
return {retval, patch}; |
||||
} |
||||
|
||||
Return<Result> Device::releaseAudioPatch(int32_t patch) { |
||||
if (version() >= AUDIO_DEVICE_API_VERSION_3_0) { |
||||
return analyzeStatus( |
||||
"release_audio_patch", |
||||
mDevice->release_audio_patch(mDevice, static_cast<audio_patch_handle_t>(patch))); |
||||
} |
||||
return Result::NOT_SUPPORTED; |
||||
} |
||||
|
||||
template <typename HalPort> |
||||
Return<void> Device::getAudioPortImpl(const AudioPort& port, getAudioPort_cb _hidl_cb, |
||||
int (*halGetter)(audio_hw_device_t*, HalPort*), |
||||
const char* halGetterName) { |
||||
if (halGetter == nullptr) { |
||||
_hidl_cb(Result::NOT_SUPPORTED, port); |
||||
return Void(); |
||||
} |
||||
HalPort halPort; |
||||
if (status_t status = HidlUtils::audioPortToHal(port, &halPort); status != NO_ERROR) { |
||||
_hidl_cb(analyzeStatus("audioPortToHal", status), port); |
||||
return Void(); |
||||
} |
||||
Result retval = analyzeStatus(halGetterName, halGetter(mDevice, &halPort)); |
||||
AudioPort resultPort = port; |
||||
if (retval == Result::OK) { |
||||
if (status_t status = HidlUtils::audioPortFromHal(halPort, &resultPort); |
||||
status != NO_ERROR) { |
||||
_hidl_cb(analyzeStatus("audioPortFromHal", status), port); |
||||
return Void(); |
||||
} |
||||
} |
||||
_hidl_cb(retval, resultPort); |
||||
return Void(); |
||||
} |
||||
|
||||
#if MAJOR_VERSION <= 6 |
||||
Return<void> Device::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) { |
||||
return getAudioPortImpl(port, _hidl_cb, mDevice->get_audio_port, "get_audio_port"); |
||||
} |
||||
#else |
||||
Return<void> Device::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) { |
||||
if (version() >= AUDIO_DEVICE_API_VERSION_3_2) { |
||||
// get_audio_port_v7 is mandatory if legacy HAL support this API version.
|
||||
return getAudioPortImpl(port, _hidl_cb, mDevice->get_audio_port_v7, "get_audio_port_v7"); |
||||
} else { |
||||
return getAudioPortImpl(port, _hidl_cb, mDevice->get_audio_port, "get_audio_port"); |
||||
} |
||||
} |
||||
#endif |
||||
|
||||
Return<Result> Device::setAudioPortConfig(const AudioPortConfig& config) { |
||||
if (version() >= AUDIO_DEVICE_API_VERSION_3_0) { |
||||
struct audio_port_config halPortConfig; |
||||
if (status_t status = HidlUtils::audioPortConfigToHal(config, &halPortConfig); |
||||
status != NO_ERROR) { |
||||
return analyzeStatus("audioPortConfigToHal", status); |
||||
} |
||||
return analyzeStatus("set_audio_port_config", |
||||
mDevice->set_audio_port_config(mDevice, &halPortConfig)); |
||||
} |
||||
return Result::NOT_SUPPORTED; |
||||
} |
||||
|
||||
#if MAJOR_VERSION == 2 |
||||
Return<AudioHwSync> Device::getHwAvSync() { |
||||
int halHwAvSync; |
||||
Result retval = getParam(AudioParameter::keyHwAvSync, &halHwAvSync); |
||||
return retval == Result::OK ? halHwAvSync : AUDIO_HW_SYNC_INVALID; |
||||
} |
||||
#elif MAJOR_VERSION >= 4 |
||||
Return<void> Device::getHwAvSync(getHwAvSync_cb _hidl_cb) { |
||||
int halHwAvSync; |
||||
Result retval = getParam(AudioParameter::keyHwAvSync, &halHwAvSync); |
||||
_hidl_cb(retval, halHwAvSync); |
||||
return Void(); |
||||
} |
||||
#endif |
||||
|
||||
Return<Result> Device::setScreenState(bool turnedOn) { |
||||
return setParam(AudioParameter::keyScreenState, turnedOn); |
||||
} |
||||
|
||||
#if MAJOR_VERSION == 2 |
||||
Return<void> Device::getParameters(const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) { |
||||
getParametersImpl({}, keys, _hidl_cb); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<Result> Device::setParameters(const hidl_vec<ParameterValue>& parameters) { |
||||
return setParametersImpl({} /* context */, parameters); |
||||
} |
||||
#elif MAJOR_VERSION >= 4 |
||||
Return<void> Device::getParameters(const hidl_vec<ParameterValue>& context, |
||||
const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) { |
||||
getParametersImpl(context, keys, _hidl_cb); |
||||
return Void(); |
||||
} |
||||
Return<Result> Device::setParameters(const hidl_vec<ParameterValue>& context, |
||||
const hidl_vec<ParameterValue>& parameters) { |
||||
return setParametersImpl(context, parameters); |
||||
} |
||||
#endif |
||||
|
||||
#if MAJOR_VERSION == 2 |
||||
Return<void> Device::debugDump(const hidl_handle& fd) { |
||||
return debug(fd, {}); |
||||
} |
||||
#endif |
||||
|
||||
Return<void> Device::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) { |
||||
if (fd.getNativeHandle() != nullptr && fd->numFds == 1) { |
||||
const int fd0 = fd->data[0]; |
||||
bool dumpMem = false; |
||||
bool unreachableMemory = false; |
||||
for (const auto& option : options) { |
||||
if (option == "-m") { |
||||
dumpMem = true; |
||||
} else if (option == "--unreachable") { |
||||
unreachableMemory = true; |
||||
} |
||||
} |
||||
|
||||
if (dumpMem) { |
||||
dprintf(fd0, "\nDumping memory:\n"); |
||||
std::string s = dumpMemoryAddresses(100 /* limit */); |
||||
write(fd0, s.c_str(), s.size()); |
||||
} |
||||
if (unreachableMemory) { |
||||
dprintf(fd0, "\nDumping unreachable memory:\n"); |
||||
// TODO - should limit be an argument parameter?
|
||||
std::string s = GetUnreachableMemoryString(true /* contents */, 100 /* limit */); |
||||
write(fd0, s.c_str(), s.size()); |
||||
} |
||||
|
||||
analyzeStatus("dump", mDevice->dump(mDevice, fd0)); |
||||
} |
||||
return Void(); |
||||
} |
||||
|
||||
#if MAJOR_VERSION >= 4 |
||||
Return<void> Device::getMicrophones(getMicrophones_cb _hidl_cb) { |
||||
Result retval = Result::NOT_SUPPORTED; |
||||
size_t actual_mics = AUDIO_MICROPHONE_MAX_COUNT; |
||||
audio_microphone_characteristic_t mic_array[AUDIO_MICROPHONE_MAX_COUNT]; |
||||
|
||||
hidl_vec<MicrophoneInfo> microphones; |
||||
if (mDevice->get_microphones != NULL && |
||||
mDevice->get_microphones(mDevice, &mic_array[0], &actual_mics) == 0) { |
||||
microphones.resize(actual_mics); |
||||
for (size_t i = 0; i < actual_mics; ++i) { |
||||
(void)CoreUtils::microphoneInfoFromHal(mic_array[i], µphones[i]); |
||||
} |
||||
retval = Result::OK; |
||||
} |
||||
_hidl_cb(retval, microphones); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<Result> Device::setConnectedState(const DeviceAddress& address, bool connected) { |
||||
auto key = connected ? AudioParameter::keyDeviceConnect : AudioParameter::keyDeviceDisconnect; |
||||
return setParam(key, address); |
||||
} |
||||
#endif |
||||
|
||||
Result Device::doClose() { |
||||
if (mIsClosed || mOpenedStreamsCount != 0) return Result::INVALID_STATE; |
||||
mIsClosed = true; |
||||
return analyzeStatus("close", audio_hw_device_close(mDevice)); |
||||
} |
||||
|
||||
#if MAJOR_VERSION >= 6 |
||||
Return<Result> Device::close() { |
||||
return doClose(); |
||||
} |
||||
|
||||
Return<Result> Device::addDeviceEffect(AudioPortHandle device, uint64_t effectId) { |
||||
if (version() < AUDIO_DEVICE_API_VERSION_3_1 || mDevice->add_device_effect == nullptr) { |
||||
return Result::NOT_SUPPORTED; |
||||
} |
||||
|
||||
effect_handle_t halEffect = EffectMap::getInstance().get(effectId); |
||||
if (halEffect != NULL) { |
||||
return analyzeStatus("add_device_effect", |
||||
mDevice->add_device_effect( |
||||
mDevice, static_cast<audio_port_handle_t>(device), halEffect)); |
||||
} else { |
||||
ALOGW("%s Invalid effect ID passed from client: %" PRIu64 "", __func__, effectId); |
||||
return Result::INVALID_ARGUMENTS; |
||||
} |
||||
} |
||||
|
||||
Return<Result> Device::removeDeviceEffect(AudioPortHandle device, uint64_t effectId) { |
||||
if (version() < AUDIO_DEVICE_API_VERSION_3_1 || mDevice->remove_device_effect == nullptr) { |
||||
return Result::NOT_SUPPORTED; |
||||
} |
||||
|
||||
effect_handle_t halEffect = EffectMap::getInstance().get(effectId); |
||||
if (halEffect != NULL) { |
||||
return analyzeStatus("remove_device_effect", |
||||
mDevice->remove_device_effect( |
||||
mDevice, static_cast<audio_port_handle_t>(device), halEffect)); |
||||
} else { |
||||
ALOGW("%s Invalid effect ID passed from client: %" PRIu64 "", __func__, effectId); |
||||
return Result::INVALID_ARGUMENTS; |
||||
} |
||||
} |
||||
|
||||
Return<void> Device::updateAudioPatch(int32_t previousPatch, |
||||
const hidl_vec<AudioPortConfig>& sources, |
||||
const hidl_vec<AudioPortConfig>& sinks, |
||||
createAudioPatch_cb _hidl_cb) { |
||||
if (previousPatch != static_cast<int32_t>(AudioPatchHandle{})) { |
||||
auto [retval, patch] = createOrUpdateAudioPatch(previousPatch, sources, sinks); |
||||
_hidl_cb(retval, patch); |
||||
} else { |
||||
_hidl_cb(Result::INVALID_ARGUMENTS, previousPatch); |
||||
} |
||||
return Void(); |
||||
} |
||||
|
||||
#endif |
||||
|
||||
#if MAJOR_VERSION == 7 && MINOR_VERSION == 1 |
||||
Return<Result> Device::setConnectedState_7_1(const AudioPort& devicePort, bool connected) { |
||||
if (version() >= AUDIO_DEVICE_API_VERSION_3_2 && |
||||
mDevice->set_device_connected_state_v7 != nullptr) { |
||||
audio_port_v7 halPort; |
||||
if (status_t status = HidlUtils::audioPortToHal(devicePort, &halPort); status != NO_ERROR) { |
||||
return analyzeStatus("audioPortToHal", status); |
||||
} |
||||
return analyzeStatus("set_device_connected_state_v7", |
||||
mDevice->set_device_connected_state_v7(mDevice, &halPort, connected)); |
||||
} |
||||
return Result::NOT_SUPPORTED; |
||||
} |
||||
#endif |
||||
|
||||
} // namespace implementation
|
||||
} // namespace CPP_VERSION
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
@ -0,0 +1,155 @@ |
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#define LOG_TAG "DevicesFactoryHAL" |
||||
|
||||
#include "core/default/DevicesFactory.h" |
||||
#include "core/default/Device.h" |
||||
#include "core/default/PrimaryDevice.h" |
||||
|
||||
#include <string.h> |
||||
|
||||
#include <android/log.h> |
||||
#include <hidl/HidlTransportSupport.h> |
||||
#include <system/thread_defs.h> |
||||
|
||||
namespace android { |
||||
namespace hardware { |
||||
namespace audio { |
||||
namespace CPP_VERSION { |
||||
namespace implementation { |
||||
|
||||
#if MAJOR_VERSION == 2 |
||||
Return<void> DevicesFactory::openDevice(IDevicesFactory::Device device, openDevice_cb _hidl_cb) { |
||||
switch (device) { |
||||
case IDevicesFactory::Device::PRIMARY: |
||||
return openDevice<PrimaryDevice>(AUDIO_HARDWARE_MODULE_ID_PRIMARY, _hidl_cb); |
||||
case IDevicesFactory::Device::A2DP: |
||||
return openDevice(AUDIO_HARDWARE_MODULE_ID_A2DP, _hidl_cb); |
||||
case IDevicesFactory::Device::USB: |
||||
return openDevice(AUDIO_HARDWARE_MODULE_ID_USB, _hidl_cb); |
||||
case IDevicesFactory::Device::R_SUBMIX: |
||||
return openDevice(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, _hidl_cb); |
||||
case IDevicesFactory::Device::STUB: |
||||
return openDevice(AUDIO_HARDWARE_MODULE_ID_STUB, _hidl_cb); |
||||
} |
||||
_hidl_cb(Result::INVALID_ARGUMENTS, nullptr); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<void> DevicesFactory::openDevice(const char* moduleName, openDevice_cb _hidl_cb) { |
||||
return openDevice<implementation::Device>(moduleName, _hidl_cb); |
||||
} |
||||
#elif MAJOR_VERSION >= 4 |
||||
Return<void> DevicesFactory::openDevice(const hidl_string& moduleName, openDevice_cb _hidl_cb) { |
||||
if (moduleName == AUDIO_HARDWARE_MODULE_ID_PRIMARY) { |
||||
return openDevice<PrimaryDevice>(moduleName.c_str(), _hidl_cb); |
||||
} |
||||
return openDevice<implementation::Device>(moduleName.c_str(), _hidl_cb); |
||||
} |
||||
Return<void> DevicesFactory::openPrimaryDevice(openPrimaryDevice_cb _hidl_cb) { |
||||
return openDevice<PrimaryDevice>(AUDIO_HARDWARE_MODULE_ID_PRIMARY, _hidl_cb); |
||||
} |
||||
#endif |
||||
|
||||
#if MAJOR_VERSION == 7 && MINOR_VERSION == 1 |
||||
Return<void> DevicesFactory::openDevice_7_1(const hidl_string& moduleName, |
||||
openDevice_7_1_cb _hidl_cb) { |
||||
if (moduleName == AUDIO_HARDWARE_MODULE_ID_PRIMARY) { |
||||
Result result; |
||||
sp<IPrimaryDevice> primary; |
||||
auto ret = openDevice<PrimaryDevice>( |
||||
AUDIO_HARDWARE_MODULE_ID_PRIMARY, |
||||
[&result, &primary](Result r, const sp<IPrimaryDevice>& p) { |
||||
result = r; |
||||
primary = p; |
||||
}); |
||||
if (ret.isOk() && result == Result::OK && primary != nullptr) { |
||||
auto getDeviceRet = primary->getDevice(); |
||||
if (getDeviceRet.isOk()) { |
||||
_hidl_cb(result, getDeviceRet); |
||||
} else { |
||||
_hidl_cb(Result::NOT_INITIALIZED, nullptr); |
||||
} |
||||
} else { |
||||
_hidl_cb(result, nullptr); |
||||
} |
||||
return Void(); |
||||
} |
||||
return openDevice<implementation::Device>(moduleName.c_str(), _hidl_cb); |
||||
} |
||||
|
||||
Return<void> DevicesFactory::openPrimaryDevice_7_1(openPrimaryDevice_7_1_cb _hidl_cb) { |
||||
return openDevice<PrimaryDevice>(AUDIO_HARDWARE_MODULE_ID_PRIMARY, _hidl_cb); |
||||
} |
||||
#endif // V7.1
|
||||
|
||||
template <class DeviceShim, class Callback> |
||||
Return<void> DevicesFactory::openDevice(const char* moduleName, Callback _hidl_cb) { |
||||
audio_hw_device_t* halDevice; |
||||
Result retval(Result::INVALID_ARGUMENTS); |
||||
sp<DeviceShim> result; |
||||
int halStatus = loadAudioInterface(moduleName, &halDevice); |
||||
if (halStatus == OK) { |
||||
result = new DeviceShim(halDevice); |
||||
android::hardware::setMinSchedulerPolicy(result, SCHED_NORMAL, ANDROID_PRIORITY_AUDIO); |
||||
retval = Result::OK; |
||||
} else if (halStatus == -EINVAL) { |
||||
retval = Result::NOT_INITIALIZED; |
||||
} |
||||
_hidl_cb(retval, result); |
||||
return Void(); |
||||
} |
||||
|
||||
// static
|
||||
int DevicesFactory::loadAudioInterface(const char* if_name, audio_hw_device_t** dev) { |
||||
const hw_module_t* mod; |
||||
int rc; |
||||
|
||||
rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod); |
||||
if (rc) { |
||||
ALOGE("%s couldn't load audio hw module %s.%s (%s)", __func__, AUDIO_HARDWARE_MODULE_ID, |
||||
if_name, strerror(-rc)); |
||||
goto out; |
||||
} |
||||
rc = audio_hw_device_open(mod, dev); |
||||
if (rc) { |
||||
ALOGE("%s couldn't open audio hw device in %s.%s (%s)", __func__, AUDIO_HARDWARE_MODULE_ID, |
||||
if_name, strerror(-rc)); |
||||
goto out; |
||||
} |
||||
if ((*dev)->common.version < AUDIO_DEVICE_API_VERSION_MIN) { |
||||
ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version); |
||||
rc = -EINVAL; |
||||
audio_hw_device_close(*dev); |
||||
goto out; |
||||
} |
||||
return OK; |
||||
|
||||
out: |
||||
*dev = NULL; |
||||
return rc; |
||||
} |
||||
|
||||
IDevicesFactory* HIDL_FETCH_IDevicesFactory(const char* name) { |
||||
return strcmp(name, "default") == 0 ? new DevicesFactory() : nullptr; |
||||
} |
||||
|
||||
} // namespace implementation
|
||||
} // namespace CPP_VERSION
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
@ -0,0 +1,178 @@ |
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#include "core/default/ParametersUtil.h" |
||||
#include "core/default/Util.h" |
||||
|
||||
#include <system/audio.h> |
||||
|
||||
#include <util/CoreUtils.h> |
||||
|
||||
namespace android { |
||||
namespace hardware { |
||||
namespace audio { |
||||
namespace CORE_TYPES_CPP_VERSION { |
||||
namespace implementation { |
||||
|
||||
/** Converts a status_t in Result according to the rules of AudioParameter::get*
|
||||
* Note: Static method and not private method to avoid leaking status_t dependency |
||||
*/ |
||||
static Result getHalStatusToResult(status_t status) { |
||||
switch (status) { |
||||
case OK: |
||||
return Result::OK; |
||||
case BAD_VALUE: // Nothing was returned, probably because the HAL does
|
||||
// not handle it
|
||||
return Result::NOT_SUPPORTED; |
||||
case INVALID_OPERATION: // Conversion from string to the requested type
|
||||
// failed
|
||||
return Result::INVALID_ARGUMENTS; |
||||
default: // Should not happen
|
||||
ALOGW("Unexpected status returned by getParam: %u", status); |
||||
return Result::INVALID_ARGUMENTS; |
||||
} |
||||
} |
||||
|
||||
Result ParametersUtil::getParam(const char* name, bool* value) { |
||||
String8 halValue; |
||||
Result retval = getParam(name, &halValue); |
||||
*value = false; |
||||
if (retval == Result::OK) { |
||||
if (halValue.empty()) { |
||||
return Result::NOT_SUPPORTED; |
||||
} |
||||
*value = !(halValue == AudioParameter::valueOff); |
||||
} |
||||
return retval; |
||||
} |
||||
|
||||
Result ParametersUtil::getParam(const char* name, int* value) { |
||||
const String8 halName(name); |
||||
AudioParameter keys; |
||||
keys.addKey(halName); |
||||
std::unique_ptr<AudioParameter> params = getParams(keys); |
||||
return getHalStatusToResult(params->getInt(halName, *value)); |
||||
} |
||||
|
||||
Result ParametersUtil::getParam(const char* name, String8* value, AudioParameter context) { |
||||
const String8 halName(name); |
||||
context.addKey(halName); |
||||
std::unique_ptr<AudioParameter> params = getParams(context); |
||||
return getHalStatusToResult(params->get(halName, *value)); |
||||
} |
||||
|
||||
void ParametersUtil::getParametersImpl( |
||||
const hidl_vec<ParameterValue>& context, const hidl_vec<hidl_string>& keys, |
||||
std::function<void(Result retval, const hidl_vec<ParameterValue>& parameters)> cb) { |
||||
AudioParameter halKeys; |
||||
for (auto& pair : context) { |
||||
halKeys.add(String8(pair.key.c_str()), String8(pair.value.c_str())); |
||||
} |
||||
for (size_t i = 0; i < keys.size(); ++i) { |
||||
halKeys.addKey(String8(keys[i].c_str())); |
||||
} |
||||
std::unique_ptr<AudioParameter> halValues = getParams(halKeys); |
||||
Result retval = |
||||
(keys.size() == 0 || halValues->size() != 0) ? Result::OK : Result::NOT_SUPPORTED; |
||||
hidl_vec<ParameterValue> result; |
||||
result.resize(halValues->size()); |
||||
String8 halKey, halValue; |
||||
for (size_t i = 0; i < halValues->size(); ++i) { |
||||
status_t status = halValues->getAt(i, halKey, halValue); |
||||
if (status != OK) { |
||||
result.resize(0); |
||||
retval = getHalStatusToResult(status); |
||||
break; |
||||
} |
||||
result[i].key = halKey.c_str(); |
||||
result[i].value = halValue.c_str(); |
||||
} |
||||
cb(retval, result); |
||||
} |
||||
|
||||
std::unique_ptr<AudioParameter> ParametersUtil::getParams(const AudioParameter& keys) { |
||||
String8 paramsAndValues; |
||||
char* halValues = halGetParameters(keys.keysToString().c_str()); |
||||
if (halValues != NULL) { |
||||
paramsAndValues = halValues; |
||||
free(halValues); |
||||
} else { |
||||
paramsAndValues.clear(); |
||||
} |
||||
return std::unique_ptr<AudioParameter>(new AudioParameter(paramsAndValues)); |
||||
} |
||||
|
||||
Result ParametersUtil::setParam(const char* name, const char* value) { |
||||
AudioParameter param; |
||||
param.add(String8(name), String8(value)); |
||||
return setParams(param); |
||||
} |
||||
|
||||
Result ParametersUtil::setParam(const char* name, bool value) { |
||||
AudioParameter param; |
||||
param.add(String8(name), String8(value ? AudioParameter::valueOn : AudioParameter::valueOff)); |
||||
return setParams(param); |
||||
} |
||||
|
||||
Result ParametersUtil::setParam(const char* name, int value) { |
||||
AudioParameter param; |
||||
param.addInt(String8(name), value); |
||||
return setParams(param); |
||||
} |
||||
|
||||
Result ParametersUtil::setParam(const char* name, float value) { |
||||
AudioParameter param; |
||||
param.addFloat(String8(name), value); |
||||
return setParams(param); |
||||
} |
||||
|
||||
Result ParametersUtil::setParametersImpl(const hidl_vec<ParameterValue>& context, |
||||
const hidl_vec<ParameterValue>& parameters) { |
||||
AudioParameter params; |
||||
for (auto& pair : context) { |
||||
params.add(String8(pair.key.c_str()), String8(pair.value.c_str())); |
||||
} |
||||
for (size_t i = 0; i < parameters.size(); ++i) { |
||||
if (parameters[i].key == "bt_wbs") { |
||||
params.add(String8("g_sco_samplerate"), |
||||
String8(parameters[i].value == AudioParameter::valueOn ? "16000" : "8000")); |
||||
} |
||||
params.add(String8(parameters[i].key.c_str()), String8(parameters[i].value.c_str())); |
||||
} |
||||
return setParams(params); |
||||
} |
||||
|
||||
Result ParametersUtil::setParam(const char* name, const DeviceAddress& address) { |
||||
audio_devices_t halDeviceType; |
||||
char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN]; |
||||
if (CoreUtils::deviceAddressToHal(address, &halDeviceType, halDeviceAddress) != NO_ERROR) { |
||||
return Result::INVALID_ARGUMENTS; |
||||
} |
||||
AudioParameter params{String8(halDeviceAddress)}; |
||||
params.addInt(String8(name), halDeviceType); |
||||
return setParams(params); |
||||
} |
||||
|
||||
Result ParametersUtil::setParams(const AudioParameter& param) { |
||||
int halStatus = halSetParameters(param.toString().c_str()); |
||||
return util::analyzeStatus(halStatus); |
||||
} |
||||
|
||||
} // namespace implementation
|
||||
} // namespace CORE_TYPES_CPP_VERSION
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
@ -0,0 +1,384 @@ |
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#define LOG_TAG "PrimaryDeviceHAL" |
||||
|
||||
#include "core/default/PrimaryDevice.h" |
||||
#include "core/default/Util.h" |
||||
|
||||
#include <cutils/properties.h> |
||||
#include <string.h> |
||||
|
||||
#if MAJOR_VERSION >= 4 |
||||
#include <cmath> |
||||
#endif |
||||
|
||||
namespace android { |
||||
namespace hardware { |
||||
namespace audio { |
||||
namespace CPP_VERSION { |
||||
namespace implementation { |
||||
|
||||
namespace util { |
||||
using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::util; |
||||
} |
||||
|
||||
PrimaryDevice::PrimaryDevice(audio_hw_device_t* device) : mDevice(new Device(device)) {} |
||||
|
||||
PrimaryDevice::~PrimaryDevice() { |
||||
// Do not call mDevice->close here. If there are any unclosed streams,
|
||||
// they only hold IDevice instance, not IPrimaryDevice, thus IPrimaryDevice
|
||||
// "part" of a device can be destroyed before the streams.
|
||||
} |
||||
|
||||
// Methods from ::android::hardware::audio::CPP_VERSION::IDevice follow.
|
||||
Return<Result> PrimaryDevice::initCheck() { |
||||
return mDevice->initCheck(); |
||||
} |
||||
|
||||
Return<Result> PrimaryDevice::setMasterVolume(float volume) { |
||||
return mDevice->setMasterVolume(volume); |
||||
} |
||||
|
||||
Return<void> PrimaryDevice::getMasterVolume(getMasterVolume_cb _hidl_cb) { |
||||
return mDevice->getMasterVolume(_hidl_cb); |
||||
} |
||||
|
||||
Return<Result> PrimaryDevice::setMicMute(bool mute) { |
||||
return mDevice->setMicMute(mute); |
||||
} |
||||
|
||||
Return<void> PrimaryDevice::getMicMute(getMicMute_cb _hidl_cb) { |
||||
return mDevice->getMicMute(_hidl_cb); |
||||
} |
||||
|
||||
Return<Result> PrimaryDevice::setMasterMute(bool mute) { |
||||
return mDevice->setMasterMute(mute); |
||||
} |
||||
|
||||
Return<void> PrimaryDevice::getMasterMute(getMasterMute_cb _hidl_cb) { |
||||
return mDevice->getMasterMute(_hidl_cb); |
||||
} |
||||
|
||||
Return<void> PrimaryDevice::getInputBufferSize(const AudioConfig& config, |
||||
getInputBufferSize_cb _hidl_cb) { |
||||
return mDevice->getInputBufferSize(config, _hidl_cb); |
||||
} |
||||
|
||||
#if MAJOR_VERSION == 2 |
||||
Return<void> PrimaryDevice::openOutputStream(int32_t ioHandle, const DeviceAddress& device, |
||||
const AudioConfig& config, AudioOutputFlags flags, |
||||
openOutputStream_cb _hidl_cb) { |
||||
return mDevice->openOutputStream(ioHandle, device, config, flags, _hidl_cb); |
||||
} |
||||
|
||||
Return<void> PrimaryDevice::openInputStream(int32_t ioHandle, const DeviceAddress& device, |
||||
const AudioConfig& config, AudioInputFlags flags, |
||||
AudioSource source, openInputStream_cb _hidl_cb) { |
||||
return mDevice->openInputStream(ioHandle, device, config, flags, source, _hidl_cb); |
||||
} |
||||
#elif MAJOR_VERSION >= 4 |
||||
Return<void> PrimaryDevice::openOutputStream(int32_t ioHandle, const DeviceAddress& device, |
||||
const AudioConfig& config, |
||||
#if MAJOR_VERSION <= 6 |
||||
AudioOutputFlags flags, |
||||
#else |
||||
const AudioOutputFlags& flags, |
||||
#endif |
||||
const SourceMetadata& sourceMetadata, |
||||
openOutputStream_cb _hidl_cb) { |
||||
return mDevice->openOutputStream(ioHandle, device, config, flags, sourceMetadata, _hidl_cb); |
||||
} |
||||
|
||||
Return<void> PrimaryDevice::openInputStream(int32_t ioHandle, const DeviceAddress& device, |
||||
const AudioConfig& config, |
||||
#if MAJOR_VERSION <= 6 |
||||
AudioInputFlags flags, |
||||
#else |
||||
const AudioInputFlags& flags, |
||||
#endif |
||||
const SinkMetadata& sinkMetadata, |
||||
openInputStream_cb _hidl_cb) { |
||||
return mDevice->openInputStream(ioHandle, device, config, flags, sinkMetadata, _hidl_cb); |
||||
} |
||||
#endif |
||||
|
||||
Return<bool> PrimaryDevice::supportsAudioPatches() { |
||||
return mDevice->supportsAudioPatches(); |
||||
} |
||||
|
||||
Return<void> PrimaryDevice::createAudioPatch(const hidl_vec<AudioPortConfig>& sources, |
||||
const hidl_vec<AudioPortConfig>& sinks, |
||||
createAudioPatch_cb _hidl_cb) { |
||||
return mDevice->createAudioPatch(sources, sinks, _hidl_cb); |
||||
} |
||||
|
||||
Return<Result> PrimaryDevice::releaseAudioPatch(int32_t patch) { |
||||
return mDevice->releaseAudioPatch(patch); |
||||
} |
||||
|
||||
Return<void> PrimaryDevice::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) { |
||||
return mDevice->getAudioPort(port, _hidl_cb); |
||||
} |
||||
|
||||
Return<Result> PrimaryDevice::setAudioPortConfig(const AudioPortConfig& config) { |
||||
return mDevice->setAudioPortConfig(config); |
||||
} |
||||
|
||||
Return<Result> PrimaryDevice::setScreenState(bool turnedOn) { |
||||
return mDevice->setScreenState(turnedOn); |
||||
} |
||||
|
||||
#if MAJOR_VERSION == 2 |
||||
Return<AudioHwSync> PrimaryDevice::getHwAvSync() { |
||||
return mDevice->getHwAvSync(); |
||||
} |
||||
|
||||
Return<void> PrimaryDevice::getParameters(const hidl_vec<hidl_string>& keys, |
||||
getParameters_cb _hidl_cb) { |
||||
return mDevice->getParameters(keys, _hidl_cb); |
||||
} |
||||
|
||||
Return<Result> PrimaryDevice::setParameters(const hidl_vec<ParameterValue>& parameters) { |
||||
return mDevice->setParameters(parameters); |
||||
} |
||||
|
||||
Return<void> PrimaryDevice::debugDump(const hidl_handle& fd) { |
||||
return mDevice->debugDump(fd); |
||||
} |
||||
#elif MAJOR_VERSION >= 4 |
||||
Return<void> PrimaryDevice::getHwAvSync(getHwAvSync_cb _hidl_cb) { |
||||
return mDevice->getHwAvSync(_hidl_cb); |
||||
} |
||||
Return<void> PrimaryDevice::getParameters(const hidl_vec<ParameterValue>& context, |
||||
const hidl_vec<hidl_string>& keys, |
||||
getParameters_cb _hidl_cb) { |
||||
return mDevice->getParameters(context, keys, _hidl_cb); |
||||
} |
||||
Return<Result> PrimaryDevice::setParameters(const hidl_vec<ParameterValue>& context, |
||||
const hidl_vec<ParameterValue>& parameters) { |
||||
return mDevice->setParameters(context, parameters); |
||||
} |
||||
Return<void> PrimaryDevice::getMicrophones(getMicrophones_cb _hidl_cb) { |
||||
return mDevice->getMicrophones(_hidl_cb); |
||||
} |
||||
Return<Result> PrimaryDevice::setConnectedState(const DeviceAddress& address, bool connected) { |
||||
return mDevice->setConnectedState(address, connected); |
||||
} |
||||
#endif |
||||
#if MAJOR_VERSION >= 6 |
||||
Return<Result> PrimaryDevice::close() { |
||||
return mDevice->close(); |
||||
} |
||||
|
||||
Return<Result> PrimaryDevice::addDeviceEffect(AudioPortHandle device, uint64_t effectId) { |
||||
return mDevice->addDeviceEffect(device, effectId); |
||||
} |
||||
|
||||
Return<Result> PrimaryDevice::removeDeviceEffect(AudioPortHandle device, uint64_t effectId) { |
||||
return mDevice->removeDeviceEffect(device, effectId); |
||||
} |
||||
|
||||
Return<void> PrimaryDevice::updateAudioPatch(int32_t previousPatch, |
||||
const hidl_vec<AudioPortConfig>& sources, |
||||
const hidl_vec<AudioPortConfig>& sinks, |
||||
updateAudioPatch_cb _hidl_cb) { |
||||
return mDevice->updateAudioPatch(previousPatch, sources, sinks, _hidl_cb); |
||||
} |
||||
#endif |
||||
|
||||
// Methods from ::android::hardware::audio::CPP_VERSION::IPrimaryDevice follow.
|
||||
Return<Result> PrimaryDevice::setVoiceVolume(float volume) { |
||||
if (!util::isGainNormalized(volume)) { |
||||
ALOGW("Can not set a voice volume (%f) outside [0,1]", volume); |
||||
return Result::INVALID_ARGUMENTS; |
||||
} |
||||
return mDevice->analyzeStatus("set_voice_volume", |
||||
mDevice->device()->set_voice_volume(mDevice->device(), volume)); |
||||
} |
||||
|
||||
Return<Result> PrimaryDevice::setMode(AudioMode mode) { |
||||
/* On stock ROM Samsung sets the g_call_state and g_call_sim_slot audio parameters
|
||||
* in the framework, breaking it on AOSP ROMs. |
||||
* For the g_call_sim_slot parameter 0x01 describes SIM1 and 0x02 SIM2. |
||||
*/ |
||||
|
||||
char simSlot[92]; |
||||
|
||||
// These props return either -1 (not calling),
|
||||
// 0 (SIM1 is calling) or 1 (SIM2 is calling)
|
||||
property_get("vendor.calls.slotid", simSlot, ""); |
||||
|
||||
// Wait until one sim slot reports a call
|
||||
if (mode == AudioMode::IN_CALL) { |
||||
while (strcmp(simSlot, "-1") == 0) { |
||||
property_get("vendor.calls.slotid", simSlot, ""); |
||||
} |
||||
} |
||||
|
||||
if (strcmp(simSlot, "0") == 0) { |
||||
// SIM1
|
||||
mDevice->halSetParameters("g_call_sim_slot=0x01"); |
||||
} else if (strcmp(simSlot, "1") == 0) { |
||||
// SIM2
|
||||
mDevice->halSetParameters("g_call_sim_slot=0x02"); |
||||
} |
||||
|
||||
// INVALID, CURRENT, CNT, MAX are reserved for internal use.
|
||||
// TODO: remove the values from the HIDL interface
|
||||
switch (mode) { |
||||
case AudioMode::NORMAL: |
||||
case AudioMode::RINGTONE: |
||||
case AudioMode::IN_CALL: |
||||
case AudioMode::IN_COMMUNICATION: |
||||
#if MAJOR_VERSION >= 6 |
||||
case AudioMode::CALL_SCREEN: |
||||
#endif |
||||
break; // Valid values
|
||||
default: |
||||
return Result::INVALID_ARGUMENTS; |
||||
}; |
||||
|
||||
return mDevice->analyzeStatus( |
||||
"set_mode", |
||||
mDevice->device()->set_mode(mDevice->device(), static_cast<audio_mode_t>(mode))); |
||||
} |
||||
|
||||
Return<void> PrimaryDevice::getBtScoNrecEnabled(getBtScoNrecEnabled_cb _hidl_cb) { |
||||
bool enabled; |
||||
Result retval = mDevice->getParam(AudioParameter::keyBtNrec, &enabled); |
||||
_hidl_cb(retval, enabled); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<Result> PrimaryDevice::setBtScoNrecEnabled(bool enabled) { |
||||
return mDevice->setParam(AudioParameter::keyBtNrec, enabled); |
||||
} |
||||
|
||||
Return<void> PrimaryDevice::getBtScoWidebandEnabled(getBtScoWidebandEnabled_cb _hidl_cb) { |
||||
bool enabled; |
||||
Result retval = mDevice->getParam(AUDIO_PARAMETER_KEY_BT_SCO_WB, &enabled); |
||||
_hidl_cb(retval, enabled); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<Result> PrimaryDevice::setBtScoWidebandEnabled(bool enabled) { |
||||
return mDevice->setParam(AUDIO_PARAMETER_KEY_BT_SCO_WB, enabled); |
||||
} |
||||
|
||||
static const char* convertTtyModeFromHIDL(IPrimaryDevice::TtyMode mode) { |
||||
switch (mode) { |
||||
case IPrimaryDevice::TtyMode::OFF: |
||||
return AUDIO_PARAMETER_VALUE_TTY_OFF; |
||||
case IPrimaryDevice::TtyMode::VCO: |
||||
return AUDIO_PARAMETER_VALUE_TTY_VCO; |
||||
case IPrimaryDevice::TtyMode::HCO: |
||||
return AUDIO_PARAMETER_VALUE_TTY_HCO; |
||||
case IPrimaryDevice::TtyMode::FULL: |
||||
return AUDIO_PARAMETER_VALUE_TTY_FULL; |
||||
default: |
||||
return nullptr; |
||||
} |
||||
} |
||||
static IPrimaryDevice::TtyMode convertTtyModeToHIDL(const char* halMode) { |
||||
if (strcmp(halMode, AUDIO_PARAMETER_VALUE_TTY_OFF) == 0) |
||||
return IPrimaryDevice::TtyMode::OFF; |
||||
else if (strcmp(halMode, AUDIO_PARAMETER_VALUE_TTY_VCO) == 0) |
||||
return IPrimaryDevice::TtyMode::VCO; |
||||
else if (strcmp(halMode, AUDIO_PARAMETER_VALUE_TTY_HCO) == 0) |
||||
return IPrimaryDevice::TtyMode::HCO; |
||||
else if (strcmp(halMode, AUDIO_PARAMETER_VALUE_TTY_FULL) == 0) |
||||
return IPrimaryDevice::TtyMode::FULL; |
||||
return IPrimaryDevice::TtyMode(-1); |
||||
} |
||||
|
||||
Return<void> PrimaryDevice::getTtyMode(getTtyMode_cb _hidl_cb) { |
||||
String8 halMode; |
||||
Result retval = mDevice->getParam(AUDIO_PARAMETER_KEY_TTY_MODE, &halMode); |
||||
if (retval != Result::OK) { |
||||
_hidl_cb(retval, TtyMode::OFF); |
||||
return Void(); |
||||
} |
||||
TtyMode mode = convertTtyModeToHIDL(halMode.c_str()); |
||||
if (mode == TtyMode(-1)) { |
||||
ALOGE("HAL returned invalid TTY value: %s", halMode.c_str()); |
||||
_hidl_cb(Result::INVALID_STATE, TtyMode::OFF); |
||||
return Void(); |
||||
} |
||||
_hidl_cb(Result::OK, mode); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<Result> PrimaryDevice::setTtyMode(IPrimaryDevice::TtyMode mode) { |
||||
const char* modeStr = convertTtyModeFromHIDL(mode); |
||||
if (modeStr == nullptr) { |
||||
ALOGW("Can not set an invalid TTY value: %d", mode); |
||||
return Result::INVALID_ARGUMENTS; |
||||
} |
||||
return mDevice->setParam(AUDIO_PARAMETER_KEY_TTY_MODE, modeStr); |
||||
} |
||||
|
||||
Return<void> PrimaryDevice::getHacEnabled(getHacEnabled_cb _hidl_cb) { |
||||
bool enabled; |
||||
Result retval = mDevice->getParam(AUDIO_PARAMETER_KEY_HAC, &enabled); |
||||
_hidl_cb(retval, enabled); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<Result> PrimaryDevice::setHacEnabled(bool enabled) { |
||||
return mDevice->setParam(AUDIO_PARAMETER_KEY_HAC, enabled); |
||||
} |
||||
|
||||
#if MAJOR_VERSION >= 4 |
||||
Return<Result> PrimaryDevice::setBtScoHeadsetDebugName(const hidl_string& name) { |
||||
return mDevice->setParam(AUDIO_PARAMETER_KEY_BT_SCO_HEADSET_NAME, name.c_str()); |
||||
} |
||||
Return<void> PrimaryDevice::getBtHfpEnabled(getBtHfpEnabled_cb _hidl_cb) { |
||||
bool enabled; |
||||
Result retval = mDevice->getParam(AUDIO_PARAMETER_KEY_HFP_ENABLE, &enabled); |
||||
_hidl_cb(retval, enabled); |
||||
return Void(); |
||||
} |
||||
Return<Result> PrimaryDevice::setBtHfpEnabled(bool enabled) { |
||||
return mDevice->setParam(AUDIO_PARAMETER_KEY_HFP_ENABLE, enabled); |
||||
} |
||||
Return<Result> PrimaryDevice::setBtHfpSampleRate(uint32_t sampleRateHz) { |
||||
return mDevice->setParam(AUDIO_PARAMETER_KEY_HFP_SET_SAMPLING_RATE, int(sampleRateHz)); |
||||
} |
||||
Return<Result> PrimaryDevice::setBtHfpVolume(float volume) { |
||||
if (!util::isGainNormalized(volume)) { |
||||
ALOGW("Can not set BT HFP volume (%f) outside [0,1]", volume); |
||||
return Result::INVALID_ARGUMENTS; |
||||
} |
||||
// Map the normalized volume onto the range of [0, 15]
|
||||
return mDevice->setParam(AUDIO_PARAMETER_KEY_HFP_VOLUME, |
||||
static_cast<int>(std::round(volume * 15))); |
||||
} |
||||
Return<Result> PrimaryDevice::updateRotation(IPrimaryDevice::Rotation rotation) { |
||||
// legacy API expects the rotation in degree
|
||||
return mDevice->setParam(AUDIO_PARAMETER_KEY_ROTATION, int(rotation) * 90); |
||||
} |
||||
#endif |
||||
|
||||
Return<void> PrimaryDevice::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) { |
||||
return mDevice->debug(fd, options); |
||||
} |
||||
|
||||
} // namespace implementation
|
||||
} // namespace CPP_VERSION
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
@ -0,0 +1,457 @@ |
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#define LOG_TAG "StreamHAL" |
||||
|
||||
#include "core/default/Stream.h" |
||||
#include "common/all-versions/HidlSupport.h" |
||||
#include "common/all-versions/default/EffectMap.h" |
||||
#include "core/default/Util.h" |
||||
|
||||
#include <inttypes.h> |
||||
|
||||
#include <HidlUtils.h> |
||||
#include <android/log.h> |
||||
#include <hardware/audio.h> |
||||
#include <hardware/audio_effect.h> |
||||
#include <media/AudioContainers.h> |
||||
#include <media/TypeConverter.h> |
||||
#include <util/CoreUtils.h> |
||||
|
||||
namespace android { |
||||
namespace hardware { |
||||
namespace audio { |
||||
namespace CPP_VERSION { |
||||
namespace implementation { |
||||
|
||||
using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils; |
||||
using ::android::hardware::audio::common::utils::splitString; |
||||
using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::CoreUtils; |
||||
namespace util { |
||||
using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::util; |
||||
} |
||||
|
||||
Stream::Stream(bool isInput, audio_stream_t* stream) : mIsInput(isInput), mStream(stream) { |
||||
(void)mIsInput; // prevent 'unused field' warnings in pre-V7 versions.
|
||||
} |
||||
|
||||
Stream::~Stream() { |
||||
mStream = nullptr; |
||||
} |
||||
|
||||
// static
|
||||
Result Stream::analyzeStatus(const char* funcName, int status) { |
||||
return util::analyzeStatus("stream", funcName, status); |
||||
} |
||||
|
||||
// static
|
||||
Result Stream::analyzeStatus(const char* funcName, int status, |
||||
const std::vector<int>& ignoreErrors) { |
||||
return util::analyzeStatus("stream", funcName, status, ignoreErrors); |
||||
} |
||||
|
||||
char* Stream::halGetParameters(const char* keys) { |
||||
return mStream->get_parameters(mStream, keys); |
||||
} |
||||
|
||||
int Stream::halSetParameters(const char* keysAndValues) { |
||||
return mStream->set_parameters(mStream, keysAndValues); |
||||
} |
||||
|
||||
// Methods from ::android::hardware::audio::CPP_VERSION::IStream follow.
|
||||
Return<uint64_t> Stream::getFrameSize() { |
||||
// Needs to be implemented by interface subclasses. But can't be declared as pure virtual,
|
||||
// since interface subclasses implementation do not inherit from this class.
|
||||
LOG_ALWAYS_FATAL("Stream::getFrameSize is pure abstract"); |
||||
return uint64_t{}; |
||||
} |
||||
|
||||
Return<uint64_t> Stream::getFrameCount() { |
||||
int halFrameCount; |
||||
Result retval = getParam(AudioParameter::keyFrameCount, &halFrameCount); |
||||
return retval == Result::OK ? halFrameCount : 0; |
||||
} |
||||
|
||||
Return<uint64_t> Stream::getBufferSize() { |
||||
return mStream->get_buffer_size(mStream); |
||||
} |
||||
|
||||
#if MAJOR_VERSION <= 6 |
||||
Return<uint32_t> Stream::getSampleRate() { |
||||
return mStream->get_sample_rate(mStream); |
||||
} |
||||
|
||||
#if MAJOR_VERSION == 2 |
||||
Return<void> Stream::getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) { |
||||
return getSupportedSampleRates(getFormat(), _hidl_cb); |
||||
} |
||||
Return<void> Stream::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) { |
||||
return getSupportedChannelMasks(getFormat(), _hidl_cb); |
||||
} |
||||
#endif |
||||
|
||||
Return<void> Stream::getSupportedSampleRates(AudioFormat format, |
||||
getSupportedSampleRates_cb _hidl_cb) { |
||||
AudioParameter context; |
||||
context.addInt(String8(AUDIO_PARAMETER_STREAM_FORMAT), int(format)); |
||||
String8 halListValue; |
||||
Result result = |
||||
getParam(AudioParameter::keyStreamSupportedSamplingRates, &halListValue, context); |
||||
hidl_vec<uint32_t> sampleRates; |
||||
SampleRateSet halSampleRates; |
||||
if (result == Result::OK) { |
||||
halSampleRates = |
||||
samplingRatesFromString(halListValue.c_str(), AudioParameter::valueListSeparator); |
||||
sampleRates = hidl_vec<uint32_t>(halSampleRates.begin(), halSampleRates.end()); |
||||
// Legacy get_parameter does not return a status_t, thus can not advertise of failure.
|
||||
// Note that this method must succeed (non empty list) if the format is supported.
|
||||
if (sampleRates.size() == 0) { |
||||
result = Result::NOT_SUPPORTED; |
||||
} |
||||
} |
||||
#if MAJOR_VERSION == 2 |
||||
_hidl_cb(sampleRates); |
||||
#elif MAJOR_VERSION >= 4 |
||||
_hidl_cb(result, sampleRates); |
||||
#endif |
||||
return Void(); |
||||
} |
||||
|
||||
Return<void> Stream::getSupportedChannelMasks(AudioFormat format, |
||||
getSupportedChannelMasks_cb _hidl_cb) { |
||||
AudioParameter context; |
||||
context.addInt(String8(AUDIO_PARAMETER_STREAM_FORMAT), int(format)); |
||||
String8 halListValue; |
||||
Result result = getParam(AudioParameter::keyStreamSupportedChannels, &halListValue, context); |
||||
hidl_vec<AudioChannelBitfield> channelMasks; |
||||
ChannelMaskSet halChannelMasks; |
||||
if (result == Result::OK) { |
||||
halChannelMasks = |
||||
channelMasksFromString(halListValue.c_str(), AudioParameter::valueListSeparator); |
||||
channelMasks.resize(halChannelMasks.size()); |
||||
size_t i = 0; |
||||
for (auto channelMask : halChannelMasks) { |
||||
channelMasks[i++] = AudioChannelBitfield(channelMask); |
||||
} |
||||
// Legacy get_parameter does not return a status_t, thus can not advertise of failure.
|
||||
// Note that this method must succeed (non empty list) if the format is supported.
|
||||
if (channelMasks.size() == 0) { |
||||
result = Result::NOT_SUPPORTED; |
||||
} |
||||
} |
||||
#if MAJOR_VERSION == 2 |
||||
_hidl_cb(channelMasks); |
||||
#elif MAJOR_VERSION >= 4 |
||||
_hidl_cb(result, channelMasks); |
||||
#endif |
||||
return Void(); |
||||
} |
||||
|
||||
Return<Result> Stream::setSampleRate(uint32_t sampleRateHz) { |
||||
return setParam(AudioParameter::keySamplingRate, static_cast<int>(sampleRateHz)); |
||||
} |
||||
|
||||
Return<AudioChannelBitfield> Stream::getChannelMask() { |
||||
return AudioChannelBitfield(mStream->get_channels(mStream)); |
||||
} |
||||
|
||||
Return<Result> Stream::setChannelMask(AudioChannelBitfield mask) { |
||||
return setParam(AudioParameter::keyChannels, static_cast<int>(mask)); |
||||
} |
||||
|
||||
Return<AudioFormat> Stream::getFormat() { |
||||
return AudioFormat(mStream->get_format(mStream)); |
||||
} |
||||
|
||||
Return<void> Stream::getSupportedFormats(getSupportedFormats_cb _hidl_cb) { |
||||
String8 halListValue; |
||||
Result result = getParam(AudioParameter::keyStreamSupportedFormats, &halListValue); |
||||
hidl_vec<AudioFormat> formats; |
||||
FormatVector halFormats; |
||||
if (result == Result::OK) { |
||||
halFormats = formatsFromString(halListValue.c_str(), AudioParameter::valueListSeparator); |
||||
formats.resize(halFormats.size()); |
||||
for (size_t i = 0; i < halFormats.size(); ++i) { |
||||
formats[i] = AudioFormat(halFormats[i]); |
||||
} |
||||
// Legacy get_parameter does not return a status_t, thus can not advertise of failure.
|
||||
// Note that the method must not return an empty list if this capability is supported.
|
||||
if (formats.size() == 0) { |
||||
result = Result::NOT_SUPPORTED; |
||||
} |
||||
} |
||||
#if MAJOR_VERSION <= 5 |
||||
_hidl_cb(formats); |
||||
#elif MAJOR_VERSION >= 6 |
||||
_hidl_cb(result, formats); |
||||
#endif |
||||
return Void(); |
||||
} |
||||
|
||||
Return<Result> Stream::setFormat(AudioFormat format) { |
||||
return setParam(AudioParameter::keyFormat, static_cast<int>(format)); |
||||
} |
||||
|
||||
Return<void> Stream::getAudioProperties(getAudioProperties_cb _hidl_cb) { |
||||
uint32_t halSampleRate = mStream->get_sample_rate(mStream); |
||||
audio_channel_mask_t halMask = mStream->get_channels(mStream); |
||||
audio_format_t halFormat = mStream->get_format(mStream); |
||||
_hidl_cb(halSampleRate, AudioChannelBitfield(halMask), AudioFormat(halFormat)); |
||||
return Void(); |
||||
} |
||||
|
||||
#else // MAJOR_VERSION <= 6
|
||||
|
||||
Return<void> Stream::getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) { |
||||
String8 halListValue; |
||||
Result result = getParam(AudioParameter::keyStreamSupportedFormats, &halListValue); |
||||
hidl_vec<AudioProfile> profiles; |
||||
if (result != Result::OK) { |
||||
_hidl_cb(result, profiles); |
||||
return Void(); |
||||
} |
||||
// Ensure that the separator is one character, despite that it's defined as a C string.
|
||||
static_assert(sizeof(AUDIO_PARAMETER_VALUE_LIST_SEPARATOR) == 2); |
||||
std::vector<std::string> halFormats = |
||||
splitString(halListValue.c_str(), AUDIO_PARAMETER_VALUE_LIST_SEPARATOR[0]); |
||||
hidl_vec<AudioFormat> formats; |
||||
(void)HidlUtils::audioFormatsFromHal(halFormats, &formats); |
||||
std::vector<AudioProfile> tempProfiles; |
||||
for (const auto& format : formats) { |
||||
audio_format_t halFormat; |
||||
if (status_t status = HidlUtils::audioFormatToHal(format, &halFormat); status != NO_ERROR) { |
||||
continue; |
||||
} |
||||
AudioParameter context; |
||||
context.addInt(String8(AUDIO_PARAMETER_STREAM_FORMAT), int(halFormat)); |
||||
// Query supported sample rates for the format.
|
||||
result = getParam(AudioParameter::keyStreamSupportedSamplingRates, &halListValue, context); |
||||
if (result != Result::OK) break; |
||||
std::vector<std::string> halSampleRates = |
||||
splitString(halListValue.c_str(), AUDIO_PARAMETER_VALUE_LIST_SEPARATOR[0]); |
||||
hidl_vec<uint32_t> sampleRates; |
||||
sampleRates.resize(halSampleRates.size()); |
||||
for (size_t i = 0; i < sampleRates.size(); ++i) { |
||||
sampleRates[i] = std::stoi(halSampleRates[i]); |
||||
} |
||||
// Query supported channel masks for the format.
|
||||
result = getParam(AudioParameter::keyStreamSupportedChannels, &halListValue, context); |
||||
if (result != Result::OK) break; |
||||
std::vector<std::string> halChannelMasks = |
||||
splitString(halListValue.c_str(), AUDIO_PARAMETER_VALUE_LIST_SEPARATOR[0]); |
||||
hidl_vec<AudioChannelMask> channelMasks; |
||||
(void)HidlUtils::audioChannelMasksFromHal(halChannelMasks, &channelMasks); |
||||
// Create a profile.
|
||||
if (channelMasks.size() != 0 && sampleRates.size() != 0) { |
||||
tempProfiles.push_back({.format = format, |
||||
.sampleRates = std::move(sampleRates), |
||||
.channelMasks = std::move(channelMasks)}); |
||||
} |
||||
} |
||||
// Legacy get_parameter does not return a status_t, thus can not advertise of failure.
|
||||
// Note that the method must not return an empty list if this capability is supported.
|
||||
if (!tempProfiles.empty()) { |
||||
profiles = tempProfiles; |
||||
} else { |
||||
result = Result::NOT_SUPPORTED; |
||||
} |
||||
_hidl_cb(result, profiles); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<void> Stream::getAudioProperties(getAudioProperties_cb _hidl_cb) { |
||||
audio_config_base_t halConfigBase = {mStream->get_sample_rate(mStream), |
||||
mStream->get_channels(mStream), |
||||
mStream->get_format(mStream)}; |
||||
AudioConfigBase configBase = {}; |
||||
status_t status = HidlUtils::audioConfigBaseFromHal(halConfigBase, mIsInput, &configBase); |
||||
_hidl_cb(Stream::analyzeStatus("get_audio_properties", status), configBase); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<Result> Stream::setAudioProperties(const AudioConfigBaseOptional& config) { |
||||
audio_config_base_t halConfigBase = AUDIO_CONFIG_BASE_INITIALIZER; |
||||
bool formatSpecified, sRateSpecified, channelMaskSpecified; |
||||
status_t status = HidlUtils::audioConfigBaseOptionalToHal( |
||||
config, &halConfigBase, &formatSpecified, &sRateSpecified, &channelMaskSpecified); |
||||
if (status != NO_ERROR) { |
||||
return Stream::analyzeStatus("set_audio_properties", status); |
||||
} |
||||
if (sRateSpecified) { |
||||
if (Result result = setParam(AudioParameter::keySamplingRate, |
||||
static_cast<int>(halConfigBase.sample_rate)); |
||||
result != Result::OK) { |
||||
return result; |
||||
} |
||||
} |
||||
if (channelMaskSpecified) { |
||||
if (Result result = setParam(AudioParameter::keyChannels, |
||||
static_cast<int>(halConfigBase.channel_mask)); |
||||
result != Result::OK) { |
||||
return result; |
||||
} |
||||
} |
||||
if (formatSpecified) { |
||||
if (Result result = |
||||
setParam(AudioParameter::keyFormat, static_cast<int>(halConfigBase.format)); |
||||
result != Result::OK) { |
||||
return result; |
||||
} |
||||
} |
||||
return Result::OK; |
||||
} |
||||
|
||||
#endif // MAJOR_VERSION <= 6
|
||||
|
||||
Return<Result> Stream::addEffect(uint64_t effectId) { |
||||
effect_handle_t halEffect = EffectMap::getInstance().get(effectId); |
||||
if (halEffect != NULL) { |
||||
return analyzeStatus("add_audio_effect", mStream->add_audio_effect(mStream, halEffect)); |
||||
} else { |
||||
ALOGW("Invalid effect ID passed from client: %" PRIu64, effectId); |
||||
return Result::INVALID_ARGUMENTS; |
||||
} |
||||
} |
||||
|
||||
Return<Result> Stream::removeEffect(uint64_t effectId) { |
||||
effect_handle_t halEffect = EffectMap::getInstance().get(effectId); |
||||
if (halEffect != NULL) { |
||||
return analyzeStatus("remove_audio_effect", |
||||
mStream->remove_audio_effect(mStream, halEffect)); |
||||
} else { |
||||
ALOGW("Invalid effect ID passed from client: %" PRIu64, effectId); |
||||
return Result::INVALID_ARGUMENTS; |
||||
} |
||||
} |
||||
|
||||
Return<Result> Stream::standby() { |
||||
return analyzeStatus("standby", mStream->standby(mStream)); |
||||
} |
||||
|
||||
Return<Result> Stream::setHwAvSync(uint32_t hwAvSync) { |
||||
return setParam(AudioParameter::keyStreamHwAvSync, static_cast<int>(hwAvSync)); |
||||
} |
||||
|
||||
#if MAJOR_VERSION == 2 |
||||
Return<AudioDevice> Stream::getDevice() { |
||||
int device = 0; |
||||
Result retval = getParam(AudioParameter::keyRouting, &device); |
||||
return retval == Result::OK ? static_cast<AudioDevice>(device) : AudioDevice::NONE; |
||||
} |
||||
|
||||
Return<Result> Stream::setDevice(const DeviceAddress& address) { |
||||
return setParam(AudioParameter::keyRouting, address); |
||||
} |
||||
|
||||
Return<void> Stream::getParameters(const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) { |
||||
getParametersImpl({} /* context */, keys, _hidl_cb); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<Result> Stream::setParameters(const hidl_vec<ParameterValue>& parameters) { |
||||
return setParametersImpl({} /* context */, parameters); |
||||
} |
||||
|
||||
Return<Result> Stream::setConnectedState(const DeviceAddress& address, bool connected) { |
||||
return setParam( |
||||
connected ? AudioParameter::keyDeviceConnect : AudioParameter::keyDeviceDisconnect, |
||||
address); |
||||
} |
||||
#elif MAJOR_VERSION >= 4 |
||||
Return<void> Stream::getDevices(getDevices_cb _hidl_cb) { |
||||
int halDevice = 0; |
||||
Result retval = getParam(AudioParameter::keyRouting, &halDevice); |
||||
hidl_vec<DeviceAddress> devices; |
||||
if (retval == Result::OK) { |
||||
devices.resize(1); |
||||
retval = Stream::analyzeStatus( |
||||
"get_devices", |
||||
CoreUtils::deviceAddressFromHal(static_cast<audio_devices_t>(halDevice), nullptr, |
||||
&devices[0])); |
||||
} |
||||
_hidl_cb(retval, devices); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<Result> Stream::setDevices(const hidl_vec<DeviceAddress>& devices) { |
||||
// FIXME: can the legacy API set multiple device with address ?
|
||||
if (devices.size() > 1) { |
||||
return Result::NOT_SUPPORTED; |
||||
} |
||||
DeviceAddress address{}; |
||||
if (devices.size() == 1) { |
||||
address = devices[0]; |
||||
} |
||||
return setParam(AudioParameter::keyRouting, address); |
||||
} |
||||
|
||||
Return<void> Stream::getParameters(const hidl_vec<ParameterValue>& context, |
||||
const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) { |
||||
getParametersImpl(context, keys, _hidl_cb); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<Result> Stream::setParameters(const hidl_vec<ParameterValue>& context, |
||||
const hidl_vec<ParameterValue>& parameters) { |
||||
return setParametersImpl(context, parameters); |
||||
} |
||||
#endif |
||||
|
||||
Return<Result> Stream::start() { |
||||
return Result::NOT_SUPPORTED; |
||||
} |
||||
|
||||
Return<Result> Stream::stop() { |
||||
return Result::NOT_SUPPORTED; |
||||
} |
||||
|
||||
Return<void> Stream::createMmapBuffer(int32_t minSizeFrames __unused, |
||||
createMmapBuffer_cb _hidl_cb) { |
||||
Result retval(Result::NOT_SUPPORTED); |
||||
MmapBufferInfo info; |
||||
_hidl_cb(retval, info); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<void> Stream::getMmapPosition(getMmapPosition_cb _hidl_cb) { |
||||
Result retval(Result::NOT_SUPPORTED); |
||||
MmapPosition position; |
||||
_hidl_cb(retval, position); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<Result> Stream::close() { |
||||
return Result::NOT_SUPPORTED; |
||||
} |
||||
|
||||
Return<void> Stream::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& /* options */) { |
||||
if (fd.getNativeHandle() != nullptr && fd->numFds == 1) { |
||||
analyzeStatus("dump", mStream->dump(mStream, fd->data[0])); |
||||
} |
||||
return Void(); |
||||
} |
||||
|
||||
#if MAJOR_VERSION == 2 |
||||
Return<void> Stream::debugDump(const hidl_handle& fd) { |
||||
return debug(fd, {} /* options */); |
||||
} |
||||
#endif |
||||
|
||||
} // namespace implementation
|
||||
} // namespace CPP_VERSION
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
@ -0,0 +1,607 @@ |
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#define LOG_TAG "StreamInHAL" |
||||
|
||||
#include "core/default/StreamIn.h" |
||||
#include "core/default/Util.h" |
||||
#include "common/all-versions/HidlSupport.h" |
||||
|
||||
//#define LOG_NDEBUG 0
|
||||
#define ATRACE_TAG ATRACE_TAG_AUDIO |
||||
|
||||
#include <HidlUtils.h> |
||||
#include <android/log.h> |
||||
#include <hardware/audio.h> |
||||
#include <util/CoreUtils.h> |
||||
#include <utils/Trace.h> |
||||
#include <cmath> |
||||
#include <memory> |
||||
|
||||
namespace android { |
||||
namespace hardware { |
||||
namespace audio { |
||||
namespace CPP_VERSION { |
||||
namespace implementation { |
||||
|
||||
using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils; |
||||
using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::CoreUtils; |
||||
namespace util { |
||||
using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::util; |
||||
} |
||||
|
||||
namespace { |
||||
|
||||
class ReadThread : public Thread { |
||||
public: |
||||
// ReadThread's lifespan never exceeds StreamIn's lifespan.
|
||||
ReadThread(std::atomic<bool>* stop, audio_stream_in_t* stream, StreamIn::CommandMQ* commandMQ, |
||||
StreamIn::DataMQ* dataMQ, StreamIn::StatusMQ* statusMQ, EventFlag* efGroup) |
||||
: Thread(false /*canCallJava*/), |
||||
mStop(stop), |
||||
mStream(stream), |
||||
mCommandMQ(commandMQ), |
||||
mDataMQ(dataMQ), |
||||
mStatusMQ(statusMQ), |
||||
mEfGroup(efGroup), |
||||
mBuffer(nullptr) {} |
||||
bool init() { |
||||
mBuffer.reset(new (std::nothrow) uint8_t[mDataMQ->getQuantumCount()]); |
||||
return mBuffer != nullptr; |
||||
} |
||||
virtual ~ReadThread() {} |
||||
|
||||
private: |
||||
std::atomic<bool>* mStop; |
||||
audio_stream_in_t* mStream; |
||||
StreamIn::CommandMQ* mCommandMQ; |
||||
StreamIn::DataMQ* mDataMQ; |
||||
StreamIn::StatusMQ* mStatusMQ; |
||||
EventFlag* mEfGroup; |
||||
std::unique_ptr<uint8_t[]> mBuffer; |
||||
IStreamIn::ReadParameters mParameters; |
||||
IStreamIn::ReadStatus mStatus; |
||||
|
||||
bool threadLoop() override; |
||||
|
||||
void doGetCapturePosition(); |
||||
void doRead(); |
||||
}; |
||||
|
||||
void ReadThread::doRead() { |
||||
size_t availableToWrite = mDataMQ->availableToWrite(); |
||||
size_t requestedToRead = mParameters.params.read; |
||||
if (requestedToRead > availableToWrite) { |
||||
ALOGW( |
||||
"truncating read data from %d to %d due to insufficient data queue " |
||||
"space", |
||||
(int32_t)requestedToRead, (int32_t)availableToWrite); |
||||
requestedToRead = availableToWrite; |
||||
} |
||||
ssize_t readResult = mStream->read(mStream, &mBuffer[0], requestedToRead); |
||||
mStatus.retval = Result::OK; |
||||
if (readResult >= 0) { |
||||
mStatus.reply.read = readResult; |
||||
if (!mDataMQ->write(&mBuffer[0], readResult)) { |
||||
ALOGW("data message queue write failed"); |
||||
} |
||||
} else { |
||||
mStatus.retval = Stream::analyzeStatus("read", readResult); |
||||
} |
||||
} |
||||
|
||||
void ReadThread::doGetCapturePosition() { |
||||
mStatus.retval = StreamIn::getCapturePositionImpl( |
||||
mStream, &mStatus.reply.capturePosition.frames, &mStatus.reply.capturePosition.time); |
||||
} |
||||
|
||||
bool ReadThread::threadLoop() { |
||||
// This implementation doesn't return control back to the Thread until it
|
||||
// decides to stop,
|
||||
// as the Thread uses mutexes, and this can lead to priority inversion.
|
||||
while (!std::atomic_load_explicit(mStop, std::memory_order_acquire)) { |
||||
uint32_t efState = 0; |
||||
mEfGroup->wait(static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL), &efState); |
||||
if (!(efState & static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL))) { |
||||
continue; // Nothing to do.
|
||||
} |
||||
if (!mCommandMQ->read(&mParameters)) { |
||||
continue; // Nothing to do.
|
||||
} |
||||
mStatus.replyTo = mParameters.command; |
||||
switch (mParameters.command) { |
||||
case IStreamIn::ReadCommand::READ: |
||||
doRead(); |
||||
break; |
||||
case IStreamIn::ReadCommand::GET_CAPTURE_POSITION: |
||||
doGetCapturePosition(); |
||||
break; |
||||
default: |
||||
ALOGE("Unknown read thread command code %d", mParameters.command); |
||||
mStatus.retval = Result::NOT_SUPPORTED; |
||||
break; |
||||
} |
||||
if (!mStatusMQ->write(&mStatus)) { |
||||
ALOGW("status message queue write failed"); |
||||
} |
||||
mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY)); |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
} // namespace
|
||||
|
||||
StreamIn::StreamIn(const sp<Device>& device, audio_stream_in_t* stream) |
||||
: mDevice(device), |
||||
mStream(stream), |
||||
mStreamCommon(new Stream(true /*isInput*/, &stream->common)), |
||||
mStreamMmap(new StreamMmap<audio_stream_in_t>(stream)), |
||||
mEfGroup(nullptr), |
||||
mStopReadThread(false) {} |
||||
|
||||
StreamIn::~StreamIn() { |
||||
ATRACE_CALL(); |
||||
close(); |
||||
if (mReadThread.get()) { |
||||
ATRACE_NAME("mReadThread->join"); |
||||
status_t status = mReadThread->join(); |
||||
ALOGE_IF(status, "read thread exit error: %s", strerror(-status)); |
||||
} |
||||
if (mEfGroup) { |
||||
status_t status = EventFlag::deleteEventFlag(&mEfGroup); |
||||
ALOGE_IF(status, "read MQ event flag deletion error: %s", strerror(-status)); |
||||
} |
||||
#if MAJOR_VERSION <= 5 |
||||
mDevice->closeInputStream(mStream); |
||||
#endif |
||||
mStream = nullptr; |
||||
} |
||||
|
||||
// Methods from ::android::hardware::audio::CPP_VERSION::IStream follow.
|
||||
Return<uint64_t> StreamIn::getFrameSize() { |
||||
return audio_stream_in_frame_size(mStream); |
||||
} |
||||
|
||||
Return<uint64_t> StreamIn::getFrameCount() { |
||||
return mStreamCommon->getFrameCount(); |
||||
} |
||||
|
||||
Return<uint64_t> StreamIn::getBufferSize() { |
||||
return mStreamCommon->getBufferSize(); |
||||
} |
||||
|
||||
#if MAJOR_VERSION <= 6 |
||||
Return<uint32_t> StreamIn::getSampleRate() { |
||||
return mStreamCommon->getSampleRate(); |
||||
} |
||||
|
||||
#if MAJOR_VERSION == 2 |
||||
Return<void> StreamIn::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) { |
||||
return mStreamCommon->getSupportedChannelMasks(_hidl_cb); |
||||
} |
||||
Return<void> StreamIn::getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) { |
||||
return mStreamCommon->getSupportedSampleRates(_hidl_cb); |
||||
} |
||||
#endif |
||||
|
||||
Return<void> StreamIn::getSupportedChannelMasks(AudioFormat format, |
||||
getSupportedChannelMasks_cb _hidl_cb) { |
||||
return mStreamCommon->getSupportedChannelMasks(format, _hidl_cb); |
||||
} |
||||
Return<void> StreamIn::getSupportedSampleRates(AudioFormat format, |
||||
getSupportedSampleRates_cb _hidl_cb) { |
||||
return mStreamCommon->getSupportedSampleRates(format, _hidl_cb); |
||||
} |
||||
|
||||
Return<Result> StreamIn::setSampleRate(uint32_t sampleRateHz) { |
||||
return mStreamCommon->setSampleRate(sampleRateHz); |
||||
} |
||||
|
||||
Return<AudioChannelBitfield> StreamIn::getChannelMask() { |
||||
return mStreamCommon->getChannelMask(); |
||||
} |
||||
|
||||
Return<Result> StreamIn::setChannelMask(AudioChannelBitfield mask) { |
||||
return mStreamCommon->setChannelMask(mask); |
||||
} |
||||
|
||||
Return<AudioFormat> StreamIn::getFormat() { |
||||
return mStreamCommon->getFormat(); |
||||
} |
||||
|
||||
Return<void> StreamIn::getSupportedFormats(getSupportedFormats_cb _hidl_cb) { |
||||
return mStreamCommon->getSupportedFormats(_hidl_cb); |
||||
} |
||||
|
||||
Return<Result> StreamIn::setFormat(AudioFormat format) { |
||||
return mStreamCommon->setFormat(format); |
||||
} |
||||
|
||||
#else |
||||
|
||||
Return<void> StreamIn::getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) { |
||||
return mStreamCommon->getSupportedProfiles(_hidl_cb); |
||||
} |
||||
|
||||
Return<Result> StreamIn::setAudioProperties(const AudioConfigBaseOptional& config) { |
||||
return mStreamCommon->setAudioProperties(config); |
||||
} |
||||
|
||||
#endif // MAJOR_VERSION <= 6
|
||||
|
||||
Return<void> StreamIn::getAudioProperties(getAudioProperties_cb _hidl_cb) { |
||||
return mStreamCommon->getAudioProperties(_hidl_cb); |
||||
} |
||||
|
||||
Return<Result> StreamIn::addEffect(uint64_t effectId) { |
||||
return mStreamCommon->addEffect(effectId); |
||||
} |
||||
|
||||
Return<Result> StreamIn::removeEffect(uint64_t effectId) { |
||||
return mStreamCommon->removeEffect(effectId); |
||||
} |
||||
|
||||
Return<Result> StreamIn::standby() { |
||||
return mStreamCommon->standby(); |
||||
} |
||||
|
||||
Return<Result> StreamIn::setHwAvSync(uint32_t hwAvSync) { |
||||
return mStreamCommon->setHwAvSync(hwAvSync); |
||||
} |
||||
|
||||
#if MAJOR_VERSION == 2 |
||||
Return<Result> StreamIn::setConnectedState(const DeviceAddress& address, bool connected) { |
||||
return mStreamCommon->setConnectedState(address, connected); |
||||
} |
||||
|
||||
Return<AudioDevice> StreamIn::getDevice() { |
||||
return mStreamCommon->getDevice(); |
||||
} |
||||
|
||||
Return<Result> StreamIn::setDevice(const DeviceAddress& address) { |
||||
return mStreamCommon->setDevice(address); |
||||
} |
||||
|
||||
Return<void> StreamIn::getParameters(const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) { |
||||
return mStreamCommon->getParameters(keys, _hidl_cb); |
||||
} |
||||
|
||||
Return<Result> StreamIn::setParameters(const hidl_vec<ParameterValue>& parameters) { |
||||
return mStreamCommon->setParameters(parameters); |
||||
} |
||||
|
||||
Return<void> StreamIn::debugDump(const hidl_handle& fd) { |
||||
return mStreamCommon->debugDump(fd); |
||||
} |
||||
#elif MAJOR_VERSION >= 4 |
||||
Return<void> StreamIn::getDevices(getDevices_cb _hidl_cb) { |
||||
return mStreamCommon->getDevices(_hidl_cb); |
||||
} |
||||
|
||||
Return<Result> StreamIn::setDevices(const hidl_vec<DeviceAddress>& devices) { |
||||
return mStreamCommon->setDevices(devices); |
||||
} |
||||
Return<void> StreamIn::getParameters(const hidl_vec<ParameterValue>& context, |
||||
const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) { |
||||
return mStreamCommon->getParameters(context, keys, _hidl_cb); |
||||
} |
||||
|
||||
Return<Result> StreamIn::setParameters(const hidl_vec<ParameterValue>& context, |
||||
const hidl_vec<ParameterValue>& parameters) { |
||||
return mStreamCommon->setParameters(context, parameters); |
||||
} |
||||
#endif |
||||
|
||||
Return<Result> StreamIn::start() { |
||||
return mStreamMmap->start(); |
||||
} |
||||
|
||||
Return<Result> StreamIn::stop() { |
||||
return mStreamMmap->stop(); |
||||
} |
||||
|
||||
Return<void> StreamIn::createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) { |
||||
return mStreamMmap->createMmapBuffer(minSizeFrames, audio_stream_in_frame_size(mStream), |
||||
_hidl_cb); |
||||
} |
||||
|
||||
Return<void> StreamIn::getMmapPosition(getMmapPosition_cb _hidl_cb) { |
||||
return mStreamMmap->getMmapPosition(_hidl_cb); |
||||
} |
||||
|
||||
Return<Result> StreamIn::close() { |
||||
if (mStopReadThread.load(std::memory_order_relaxed)) { // only this thread writes
|
||||
return Result::INVALID_STATE; |
||||
} |
||||
mStopReadThread.store(true, std::memory_order_release); |
||||
if (mEfGroup) { |
||||
mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL)); |
||||
} |
||||
#if MAJOR_VERSION >= 6 |
||||
mDevice->closeInputStream(mStream); |
||||
#endif |
||||
return Result::OK; |
||||
} |
||||
|
||||
// Methods from ::android::hardware::audio::CPP_VERSION::IStreamIn follow.
|
||||
Return<void> StreamIn::getAudioSource(getAudioSource_cb _hidl_cb) { |
||||
int halSource; |
||||
Result retval = mStreamCommon->getParam(AudioParameter::keyInputSource, &halSource); |
||||
AudioSource source = {}; |
||||
if (retval == Result::OK) { |
||||
retval = Stream::analyzeStatus( |
||||
"get_audio_source", |
||||
HidlUtils::audioSourceFromHal(static_cast<audio_source_t>(halSource), &source)); |
||||
} |
||||
_hidl_cb(retval, source); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<Result> StreamIn::setGain(float gain) { |
||||
if (!util::isGainNormalized(gain)) { |
||||
ALOGW("Can not set a stream input gain (%f) outside [0,1]", gain); |
||||
return Result::INVALID_ARGUMENTS; |
||||
} |
||||
return Stream::analyzeStatus("set_gain", mStream->set_gain(mStream, gain)); |
||||
} |
||||
|
||||
Return<void> StreamIn::prepareForReading(uint32_t frameSize, uint32_t framesCount, |
||||
prepareForReading_cb _hidl_cb) { |
||||
status_t status; |
||||
#if MAJOR_VERSION <= 6 |
||||
ThreadInfo threadInfo = {0, 0}; |
||||
#else |
||||
int32_t threadInfo = 0; |
||||
#endif |
||||
|
||||
// Wrap the _hidl_cb to return an error
|
||||
auto sendError = [&threadInfo, &_hidl_cb](Result result) { |
||||
_hidl_cb(result, CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), |
||||
threadInfo); |
||||
}; |
||||
|
||||
// Create message queues.
|
||||
if (mDataMQ) { |
||||
ALOGE("the client attempts to call prepareForReading twice"); |
||||
sendError(Result::INVALID_STATE); |
||||
return Void(); |
||||
} |
||||
std::unique_ptr<CommandMQ> tempCommandMQ(new CommandMQ(1)); |
||||
|
||||
// Check frameSize and framesCount
|
||||
if (frameSize == 0 || framesCount == 0) { |
||||
ALOGE("Null frameSize (%u) or framesCount (%u)", frameSize, framesCount); |
||||
sendError(Result::INVALID_ARGUMENTS); |
||||
return Void(); |
||||
} |
||||
|
||||
if (frameSize > Stream::MAX_BUFFER_SIZE / framesCount) { |
||||
ALOGE("Buffer too big: %u*%u bytes > MAX_BUFFER_SIZE (%u)", frameSize, framesCount, |
||||
Stream::MAX_BUFFER_SIZE); |
||||
sendError(Result::INVALID_ARGUMENTS); |
||||
return Void(); |
||||
} |
||||
std::unique_ptr<DataMQ> tempDataMQ(new DataMQ(frameSize * framesCount, true /* EventFlag */)); |
||||
|
||||
std::unique_ptr<StatusMQ> tempStatusMQ(new StatusMQ(1)); |
||||
if (!tempCommandMQ->isValid() || !tempDataMQ->isValid() || !tempStatusMQ->isValid()) { |
||||
ALOGE_IF(!tempCommandMQ->isValid(), "command MQ is invalid"); |
||||
ALOGE_IF(!tempDataMQ->isValid(), "data MQ is invalid"); |
||||
ALOGE_IF(!tempStatusMQ->isValid(), "status MQ is invalid"); |
||||
sendError(Result::INVALID_ARGUMENTS); |
||||
return Void(); |
||||
} |
||||
EventFlag* tempRawEfGroup{}; |
||||
status = EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &tempRawEfGroup); |
||||
std::unique_ptr<EventFlag, void (*)(EventFlag*)> tempElfGroup( |
||||
tempRawEfGroup, [](auto* ef) { EventFlag::deleteEventFlag(&ef); }); |
||||
if (status != OK || !tempElfGroup) { |
||||
ALOGE("failed creating event flag for data MQ: %s", strerror(-status)); |
||||
sendError(Result::INVALID_ARGUMENTS); |
||||
return Void(); |
||||
} |
||||
|
||||
// Create and launch the thread.
|
||||
auto tempReadThread = |
||||
sp<ReadThread>::make(&mStopReadThread, mStream, tempCommandMQ.get(), tempDataMQ.get(), |
||||
tempStatusMQ.get(), tempElfGroup.get()); |
||||
if (!tempReadThread->init()) { |
||||
ALOGW("failed to start reader thread: %s", strerror(-status)); |
||||
sendError(Result::INVALID_ARGUMENTS); |
||||
return Void(); |
||||
} |
||||
status = tempReadThread->run("reader", PRIORITY_URGENT_AUDIO); |
||||
if (status != OK) { |
||||
ALOGW("failed to start reader thread: %s", strerror(-status)); |
||||
sendError(Result::INVALID_ARGUMENTS); |
||||
return Void(); |
||||
} |
||||
|
||||
mCommandMQ = std::move(tempCommandMQ); |
||||
mDataMQ = std::move(tempDataMQ); |
||||
mStatusMQ = std::move(tempStatusMQ); |
||||
mReadThread = tempReadThread; |
||||
mEfGroup = tempElfGroup.release(); |
||||
#if MAJOR_VERSION <= 6 |
||||
threadInfo.pid = getpid(); |
||||
threadInfo.tid = mReadThread->getTid(); |
||||
#else |
||||
threadInfo = mReadThread->getTid(); |
||||
#endif |
||||
_hidl_cb(Result::OK, *mCommandMQ->getDesc(), *mDataMQ->getDesc(), *mStatusMQ->getDesc(), |
||||
threadInfo); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<uint32_t> StreamIn::getInputFramesLost() { |
||||
return mStream->get_input_frames_lost(mStream); |
||||
} |
||||
|
||||
// static
|
||||
Result StreamIn::getCapturePositionImpl(audio_stream_in_t* stream, uint64_t* frames, |
||||
uint64_t* time) { |
||||
// HAL may have a stub function, always returning ENOSYS, don't
|
||||
// spam the log in this case.
|
||||
static const std::vector<int> ignoredErrors{ENOSYS}; |
||||
Result retval(Result::NOT_SUPPORTED); |
||||
if (stream->get_capture_position == NULL) return retval; |
||||
int64_t halFrames, halTime; |
||||
retval = Stream::analyzeStatus("get_capture_position", |
||||
stream->get_capture_position(stream, &halFrames, &halTime), |
||||
ignoredErrors); |
||||
if (retval == Result::OK) { |
||||
*frames = halFrames; |
||||
*time = halTime; |
||||
} |
||||
return retval; |
||||
}; |
||||
|
||||
Return<void> StreamIn::getCapturePosition(getCapturePosition_cb _hidl_cb) { |
||||
uint64_t frames = 0, time = 0; |
||||
Result retval = getCapturePositionImpl(mStream, &frames, &time); |
||||
_hidl_cb(retval, frames, time); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<void> StreamIn::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) { |
||||
return mStreamCommon->debug(fd, options); |
||||
} |
||||
|
||||
#if MAJOR_VERSION >= 4 |
||||
Result StreamIn::doUpdateSinkMetadata(const SinkMetadata& sinkMetadata) { |
||||
std::vector<record_track_metadata> halTracks; |
||||
#if MAJOR_VERSION <= 6 |
||||
(void)CoreUtils::sinkMetadataToHal(sinkMetadata, &halTracks); |
||||
#else |
||||
// Validate whether a conversion to V7 is possible. This is needed
|
||||
// to have a consistent behavior of the HAL regardless of the API
|
||||
// version of the legacy HAL (and also to be consistent with openInputStream).
|
||||
std::vector<record_track_metadata_v7> halTracksV7; |
||||
if (status_t status = CoreUtils::sinkMetadataToHalV7( |
||||
sinkMetadata, false /*ignoreNonVendorTags*/, &halTracksV7); |
||||
status == NO_ERROR) { |
||||
halTracks.reserve(halTracksV7.size()); |
||||
for (auto metadata_v7 : halTracksV7) { |
||||
halTracks.push_back(std::move(metadata_v7.base)); |
||||
} |
||||
} else { |
||||
return Stream::analyzeStatus("sinkMetadataToHal", status); |
||||
} |
||||
#endif // MAJOR_VERSION <= 6
|
||||
const sink_metadata_t halMetadata = { |
||||
.track_count = halTracks.size(), |
||||
.tracks = halTracks.data(), |
||||
}; |
||||
mStream->update_sink_metadata(mStream, &halMetadata); |
||||
return Result::OK; |
||||
} |
||||
|
||||
#if MAJOR_VERSION >= 7 |
||||
Result StreamIn::doUpdateSinkMetadataV7(const SinkMetadata& sinkMetadata) { |
||||
std::vector<record_track_metadata_v7> halTracks; |
||||
if (status_t status = CoreUtils::sinkMetadataToHalV7(sinkMetadata, |
||||
false /*ignoreNonVendorTags*/, &halTracks); |
||||
status != NO_ERROR) { |
||||
return Stream::analyzeStatus("sinkMetadataToHal", status); |
||||
} |
||||
const sink_metadata_v7_t halMetadata = { |
||||
.track_count = halTracks.size(), |
||||
.tracks = halTracks.data(), |
||||
}; |
||||
mStream->update_sink_metadata_v7(mStream, &halMetadata); |
||||
return Result::OK; |
||||
} |
||||
#endif // MAJOR_VERSION >= 7
|
||||
|
||||
#if MAJOR_VERSION <= 6 |
||||
Return<void> StreamIn::updateSinkMetadata(const SinkMetadata& sinkMetadata) { |
||||
if (mStream->update_sink_metadata == nullptr) { |
||||
return Void(); // not supported by the HAL
|
||||
} |
||||
(void)doUpdateSinkMetadata(sinkMetadata); |
||||
return Void(); |
||||
} |
||||
#elif MAJOR_VERSION >= 7 |
||||
Return<Result> StreamIn::updateSinkMetadata(const SinkMetadata& sinkMetadata) { |
||||
if (mDevice->version() < AUDIO_DEVICE_API_VERSION_3_2) { |
||||
if (mStream->update_sink_metadata == nullptr) { |
||||
return Result::NOT_SUPPORTED; |
||||
} |
||||
return doUpdateSinkMetadata(sinkMetadata); |
||||
} else { |
||||
if (mStream->update_sink_metadata_v7 == nullptr) { |
||||
return Result::NOT_SUPPORTED; |
||||
} |
||||
return doUpdateSinkMetadataV7(sinkMetadata); |
||||
} |
||||
} |
||||
#endif |
||||
|
||||
Return<void> StreamIn::getActiveMicrophones(getActiveMicrophones_cb _hidl_cb) { |
||||
Result retval = Result::NOT_SUPPORTED; |
||||
size_t actual_mics = AUDIO_MICROPHONE_MAX_COUNT; |
||||
audio_microphone_characteristic_t mic_array[AUDIO_MICROPHONE_MAX_COUNT]; |
||||
|
||||
hidl_vec<MicrophoneInfo> microphones; |
||||
if (mStream->get_active_microphones != NULL && |
||||
mStream->get_active_microphones(mStream, &mic_array[0], &actual_mics) == 0) { |
||||
microphones.resize(actual_mics); |
||||
for (size_t i = 0; i < actual_mics; ++i) { |
||||
(void)CoreUtils::microphoneInfoFromHal(mic_array[i], µphones[i]); |
||||
} |
||||
retval = Result::OK; |
||||
} |
||||
|
||||
_hidl_cb(retval, microphones); |
||||
return Void(); |
||||
} |
||||
#endif |
||||
|
||||
#if MAJOR_VERSION >= 5 |
||||
Return<Result> StreamIn::setMicrophoneDirection(MicrophoneDirection direction) { |
||||
if (mStream->set_microphone_direction == nullptr) { |
||||
return Result::NOT_SUPPORTED; |
||||
} |
||||
if (!common::utils::isValidHidlEnum(direction)) { |
||||
ALOGE("%s: Invalid direction %d", __func__, direction); |
||||
return Result::INVALID_ARGUMENTS; |
||||
} |
||||
return Stream::analyzeStatus( |
||||
"set_microphone_direction", |
||||
mStream->set_microphone_direction( |
||||
mStream, static_cast<audio_microphone_direction_t>(direction))); |
||||
} |
||||
|
||||
Return<Result> StreamIn::setMicrophoneFieldDimension(float zoom) { |
||||
if (mStream->set_microphone_field_dimension == nullptr) { |
||||
return Result::NOT_SUPPORTED; |
||||
} |
||||
if (std::isnan(zoom) || zoom < -1 || zoom > 1) { |
||||
ALOGE("%s: Invalid zoom %f", __func__, zoom); |
||||
return Result::INVALID_ARGUMENTS; |
||||
} |
||||
return Stream::analyzeStatus("set_microphone_field_dimension", |
||||
mStream->set_microphone_field_dimension(mStream, zoom)); |
||||
} |
||||
|
||||
#endif |
||||
|
||||
} // namespace implementation
|
||||
} // namespace CPP_VERSION
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
@ -0,0 +1,837 @@ |
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#define LOG_TAG "StreamOutHAL" |
||||
|
||||
#include "core/default/StreamOut.h" |
||||
#include "core/default/Util.h" |
||||
|
||||
//#define LOG_NDEBUG 0
|
||||
#define ATRACE_TAG ATRACE_TAG_AUDIO |
||||
|
||||
#include <string.h> |
||||
|
||||
#include <memory> |
||||
|
||||
#include <HidlUtils.h> |
||||
#include <android/log.h> |
||||
#include <audio_utils/Metadata.h> |
||||
#include <hardware/audio.h> |
||||
#include <util/CoreUtils.h> |
||||
#include <utils/Trace.h> |
||||
|
||||
namespace android { |
||||
namespace hardware { |
||||
namespace audio { |
||||
namespace CPP_VERSION { |
||||
namespace implementation { |
||||
|
||||
using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils; |
||||
using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::CoreUtils; |
||||
namespace util { |
||||
using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::util; |
||||
} |
||||
|
||||
namespace { |
||||
|
||||
class WriteThread : public Thread { |
||||
public: |
||||
// WriteThread's lifespan never exceeds StreamOut's lifespan.
|
||||
WriteThread(std::atomic<bool>* stop, audio_stream_out_t* stream, |
||||
StreamOut::CommandMQ* commandMQ, StreamOut::DataMQ* dataMQ, |
||||
StreamOut::StatusMQ* statusMQ, EventFlag* efGroup) |
||||
: Thread(false /*canCallJava*/), |
||||
mStop(stop), |
||||
mStream(stream), |
||||
mCommandMQ(commandMQ), |
||||
mDataMQ(dataMQ), |
||||
mStatusMQ(statusMQ), |
||||
mEfGroup(efGroup), |
||||
mBuffer(nullptr) {} |
||||
bool init() { |
||||
mBuffer.reset(new (std::nothrow) uint8_t[mDataMQ->getQuantumCount()]); |
||||
return mBuffer != nullptr; |
||||
} |
||||
virtual ~WriteThread() {} |
||||
|
||||
private: |
||||
std::atomic<bool>* mStop; |
||||
audio_stream_out_t* mStream; |
||||
StreamOut::CommandMQ* mCommandMQ; |
||||
StreamOut::DataMQ* mDataMQ; |
||||
StreamOut::StatusMQ* mStatusMQ; |
||||
EventFlag* mEfGroup; |
||||
std::unique_ptr<uint8_t[]> mBuffer; |
||||
IStreamOut::WriteStatus mStatus; |
||||
|
||||
bool threadLoop() override; |
||||
|
||||
void doGetLatency(); |
||||
void doGetPresentationPosition(); |
||||
void doWrite(); |
||||
}; |
||||
|
||||
void WriteThread::doWrite() { |
||||
const size_t availToRead = mDataMQ->availableToRead(); |
||||
mStatus.retval = Result::OK; |
||||
mStatus.reply.written = 0; |
||||
if (mDataMQ->read(&mBuffer[0], availToRead)) { |
||||
ssize_t writeResult = mStream->write(mStream, &mBuffer[0], availToRead); |
||||
if (writeResult >= 0) { |
||||
mStatus.reply.written = writeResult; |
||||
} else { |
||||
mStatus.retval = Stream::analyzeStatus("write", writeResult); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void WriteThread::doGetPresentationPosition() { |
||||
mStatus.retval = |
||||
StreamOut::getPresentationPositionImpl(mStream, &mStatus.reply.presentationPosition.frames, |
||||
&mStatus.reply.presentationPosition.timeStamp); |
||||
} |
||||
|
||||
void WriteThread::doGetLatency() { |
||||
mStatus.retval = Result::OK; |
||||
mStatus.reply.latencyMs = mStream->get_latency(mStream); |
||||
} |
||||
|
||||
bool WriteThread::threadLoop() { |
||||
// This implementation doesn't return control back to the Thread until it
|
||||
// decides to stop,
|
||||
// as the Thread uses mutexes, and this can lead to priority inversion.
|
||||
while (!std::atomic_load_explicit(mStop, std::memory_order_acquire)) { |
||||
uint32_t efState = 0; |
||||
mEfGroup->wait(static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY), &efState); |
||||
if (!(efState & static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY))) { |
||||
continue; // Nothing to do.
|
||||
} |
||||
if (!mCommandMQ->read(&mStatus.replyTo)) { |
||||
continue; // Nothing to do.
|
||||
} |
||||
switch (mStatus.replyTo) { |
||||
case IStreamOut::WriteCommand::WRITE: |
||||
doWrite(); |
||||
break; |
||||
case IStreamOut::WriteCommand::GET_PRESENTATION_POSITION: |
||||
doGetPresentationPosition(); |
||||
break; |
||||
case IStreamOut::WriteCommand::GET_LATENCY: |
||||
doGetLatency(); |
||||
break; |
||||
default: |
||||
ALOGE("Unknown write thread command code %d", mStatus.replyTo); |
||||
mStatus.retval = Result::NOT_SUPPORTED; |
||||
break; |
||||
} |
||||
if (!mStatusMQ->write(&mStatus)) { |
||||
ALOGE("status message queue write failed"); |
||||
} |
||||
mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL)); |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
} // namespace
|
||||
|
||||
StreamOut::StreamOut(const sp<Device>& device, audio_stream_out_t* stream) |
||||
: mDevice(device), |
||||
mStream(stream), |
||||
mStreamCommon(new Stream(false /*isInput*/, &stream->common)), |
||||
mStreamMmap(new StreamMmap<audio_stream_out_t>(stream)), |
||||
mEfGroup(nullptr), |
||||
mStopWriteThread(false) {} |
||||
|
||||
StreamOut::~StreamOut() { |
||||
ATRACE_CALL(); |
||||
(void)close(); |
||||
if (mWriteThread.get()) { |
||||
ATRACE_NAME("mWriteThread->join"); |
||||
status_t status = mWriteThread->join(); |
||||
ALOGE_IF(status, "write thread exit error: %s", strerror(-status)); |
||||
} |
||||
if (mEfGroup) { |
||||
status_t status = EventFlag::deleteEventFlag(&mEfGroup); |
||||
ALOGE_IF(status, "write MQ event flag deletion error: %s", strerror(-status)); |
||||
} |
||||
mCallback = nullptr; |
||||
#if MAJOR_VERSION <= 5 |
||||
mDevice->closeOutputStream(mStream); |
||||
// Closing the output stream in the HAL waits for the callback to finish,
|
||||
// and joins the callback thread. Thus is it guaranteed that the callback
|
||||
// thread will not be accessing our object anymore.
|
||||
#endif |
||||
mStream = nullptr; |
||||
} |
||||
|
||||
// Methods from ::android::hardware::audio::CPP_VERSION::IStream follow.
|
||||
Return<uint64_t> StreamOut::getFrameSize() { |
||||
return audio_stream_out_frame_size(mStream); |
||||
} |
||||
|
||||
Return<uint64_t> StreamOut::getFrameCount() { |
||||
return mStreamCommon->getFrameCount(); |
||||
} |
||||
|
||||
Return<uint64_t> StreamOut::getBufferSize() { |
||||
return mStreamCommon->getBufferSize(); |
||||
} |
||||
|
||||
#if MAJOR_VERSION <= 6 |
||||
Return<uint32_t> StreamOut::getSampleRate() { |
||||
return mStreamCommon->getSampleRate(); |
||||
} |
||||
|
||||
#if MAJOR_VERSION == 2 |
||||
Return<void> StreamOut::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) { |
||||
return mStreamCommon->getSupportedChannelMasks(_hidl_cb); |
||||
} |
||||
Return<void> StreamOut::getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) { |
||||
return mStreamCommon->getSupportedSampleRates(_hidl_cb); |
||||
} |
||||
#endif |
||||
|
||||
Return<void> StreamOut::getSupportedChannelMasks(AudioFormat format, |
||||
getSupportedChannelMasks_cb _hidl_cb) { |
||||
return mStreamCommon->getSupportedChannelMasks(format, _hidl_cb); |
||||
} |
||||
Return<void> StreamOut::getSupportedSampleRates(AudioFormat format, |
||||
getSupportedSampleRates_cb _hidl_cb) { |
||||
return mStreamCommon->getSupportedSampleRates(format, _hidl_cb); |
||||
} |
||||
|
||||
Return<Result> StreamOut::setSampleRate(uint32_t sampleRateHz) { |
||||
return mStreamCommon->setSampleRate(sampleRateHz); |
||||
} |
||||
|
||||
Return<AudioChannelBitfield> StreamOut::getChannelMask() { |
||||
return mStreamCommon->getChannelMask(); |
||||
} |
||||
|
||||
Return<Result> StreamOut::setChannelMask(AudioChannelBitfield mask) { |
||||
return mStreamCommon->setChannelMask(mask); |
||||
} |
||||
|
||||
Return<AudioFormat> StreamOut::getFormat() { |
||||
return mStreamCommon->getFormat(); |
||||
} |
||||
|
||||
Return<void> StreamOut::getSupportedFormats(getSupportedFormats_cb _hidl_cb) { |
||||
return mStreamCommon->getSupportedFormats(_hidl_cb); |
||||
} |
||||
|
||||
Return<Result> StreamOut::setFormat(AudioFormat format) { |
||||
return mStreamCommon->setFormat(format); |
||||
} |
||||
|
||||
#else |
||||
|
||||
Return<void> StreamOut::getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) { |
||||
return mStreamCommon->getSupportedProfiles(_hidl_cb); |
||||
} |
||||
|
||||
Return<Result> StreamOut::setAudioProperties(const AudioConfigBaseOptional& config) { |
||||
return mStreamCommon->setAudioProperties(config); |
||||
} |
||||
|
||||
#endif // MAJOR_VERSION <= 6
|
||||
|
||||
Return<void> StreamOut::getAudioProperties(getAudioProperties_cb _hidl_cb) { |
||||
return mStreamCommon->getAudioProperties(_hidl_cb); |
||||
} |
||||
|
||||
Return<Result> StreamOut::addEffect(uint64_t effectId) { |
||||
return mStreamCommon->addEffect(effectId); |
||||
} |
||||
|
||||
Return<Result> StreamOut::removeEffect(uint64_t effectId) { |
||||
return mStreamCommon->removeEffect(effectId); |
||||
} |
||||
|
||||
Return<Result> StreamOut::standby() { |
||||
return mStreamCommon->standby(); |
||||
} |
||||
|
||||
Return<Result> StreamOut::setHwAvSync(uint32_t hwAvSync) { |
||||
return mStreamCommon->setHwAvSync(hwAvSync); |
||||
} |
||||
|
||||
#if MAJOR_VERSION == 2 |
||||
Return<Result> StreamOut::setConnectedState(const DeviceAddress& address, bool connected) { |
||||
return mStreamCommon->setConnectedState(address, connected); |
||||
} |
||||
|
||||
Return<AudioDevice> StreamOut::getDevice() { |
||||
return mStreamCommon->getDevice(); |
||||
} |
||||
|
||||
Return<Result> StreamOut::setDevice(const DeviceAddress& address) { |
||||
return mStreamCommon->setDevice(address); |
||||
} |
||||
|
||||
Return<void> StreamOut::getParameters(const hidl_vec<hidl_string>& keys, |
||||
getParameters_cb _hidl_cb) { |
||||
return mStreamCommon->getParameters(keys, _hidl_cb); |
||||
} |
||||
|
||||
Return<Result> StreamOut::setParameters(const hidl_vec<ParameterValue>& parameters) { |
||||
return mStreamCommon->setParameters(parameters); |
||||
} |
||||
|
||||
Return<void> StreamOut::debugDump(const hidl_handle& fd) { |
||||
return mStreamCommon->debugDump(fd); |
||||
} |
||||
#elif MAJOR_VERSION >= 4 |
||||
Return<void> StreamOut::getDevices(getDevices_cb _hidl_cb) { |
||||
return mStreamCommon->getDevices(_hidl_cb); |
||||
} |
||||
|
||||
Return<Result> StreamOut::setDevices(const hidl_vec<DeviceAddress>& devices) { |
||||
return mStreamCommon->setDevices(devices); |
||||
} |
||||
Return<void> StreamOut::getParameters(const hidl_vec<ParameterValue>& context, |
||||
const hidl_vec<hidl_string>& keys, |
||||
getParameters_cb _hidl_cb) { |
||||
return mStreamCommon->getParameters(context, keys, _hidl_cb); |
||||
} |
||||
|
||||
Return<Result> StreamOut::setParameters(const hidl_vec<ParameterValue>& context, |
||||
const hidl_vec<ParameterValue>& parameters) { |
||||
return mStreamCommon->setParameters(context, parameters); |
||||
} |
||||
#endif |
||||
|
||||
Return<Result> StreamOut::close() { |
||||
if (mStopWriteThread.load(std::memory_order_relaxed)) { // only this thread writes
|
||||
return Result::INVALID_STATE; |
||||
} |
||||
mStopWriteThread.store(true, std::memory_order_release); |
||||
if (mEfGroup) { |
||||
mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY)); |
||||
} |
||||
#if MAJOR_VERSION >= 6 |
||||
mDevice->closeOutputStream(mStream); |
||||
#endif |
||||
return Result::OK; |
||||
} |
||||
|
||||
// Methods from ::android::hardware::audio::CPP_VERSION::IStreamOut follow.
|
||||
Return<uint32_t> StreamOut::getLatency() { |
||||
return mStream->get_latency(mStream); |
||||
} |
||||
|
||||
Return<Result> StreamOut::setVolume(float left, float right) { |
||||
if (mStream->set_volume == NULL) { |
||||
return Result::NOT_SUPPORTED; |
||||
} |
||||
if (!util::isGainNormalized(left)) { |
||||
ALOGW("Can not set a stream output volume {%f, %f} outside [0,1]", left, right); |
||||
return Result::INVALID_ARGUMENTS; |
||||
} |
||||
return Stream::analyzeStatus("set_volume", mStream->set_volume(mStream, left, right), |
||||
{ENOSYS} /*ignore*/); |
||||
} |
||||
|
||||
Return<void> StreamOut::prepareForWriting(uint32_t frameSize, uint32_t framesCount, |
||||
prepareForWriting_cb _hidl_cb) { |
||||
status_t status; |
||||
#if MAJOR_VERSION <= 6 |
||||
ThreadInfo threadInfo = {0, 0}; |
||||
#else |
||||
int32_t threadInfo = 0; |
||||
#endif |
||||
|
||||
// Wrap the _hidl_cb to return an error
|
||||
auto sendError = [&threadInfo, &_hidl_cb](Result result) { |
||||
_hidl_cb(result, CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), |
||||
threadInfo); |
||||
}; |
||||
|
||||
// Create message queues.
|
||||
if (mDataMQ) { |
||||
ALOGE("the client attempts to call prepareForWriting twice"); |
||||
sendError(Result::INVALID_STATE); |
||||
return Void(); |
||||
} |
||||
std::unique_ptr<CommandMQ> tempCommandMQ(new CommandMQ(1)); |
||||
|
||||
// Check frameSize and framesCount
|
||||
if (frameSize == 0 || framesCount == 0) { |
||||
ALOGE("Null frameSize (%u) or framesCount (%u)", frameSize, framesCount); |
||||
sendError(Result::INVALID_ARGUMENTS); |
||||
return Void(); |
||||
} |
||||
if (frameSize > Stream::MAX_BUFFER_SIZE / framesCount) { |
||||
ALOGE("Buffer too big: %u*%u bytes > MAX_BUFFER_SIZE (%u)", frameSize, framesCount, |
||||
Stream::MAX_BUFFER_SIZE); |
||||
sendError(Result::INVALID_ARGUMENTS); |
||||
return Void(); |
||||
} |
||||
std::unique_ptr<DataMQ> tempDataMQ(new DataMQ(frameSize * framesCount, true /* EventFlag */)); |
||||
|
||||
std::unique_ptr<StatusMQ> tempStatusMQ(new StatusMQ(1)); |
||||
if (!tempCommandMQ->isValid() || !tempDataMQ->isValid() || !tempStatusMQ->isValid()) { |
||||
ALOGE_IF(!tempCommandMQ->isValid(), "command MQ is invalid"); |
||||
ALOGE_IF(!tempDataMQ->isValid(), "data MQ is invalid"); |
||||
ALOGE_IF(!tempStatusMQ->isValid(), "status MQ is invalid"); |
||||
sendError(Result::INVALID_ARGUMENTS); |
||||
return Void(); |
||||
} |
||||
EventFlag* tempRawEfGroup{}; |
||||
status = EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &tempRawEfGroup); |
||||
std::unique_ptr<EventFlag, void (*)(EventFlag*)> tempElfGroup( |
||||
tempRawEfGroup, [](auto* ef) { EventFlag::deleteEventFlag(&ef); }); |
||||
if (status != OK || !tempElfGroup) { |
||||
ALOGE("failed creating event flag for data MQ: %s", strerror(-status)); |
||||
sendError(Result::INVALID_ARGUMENTS); |
||||
return Void(); |
||||
} |
||||
|
||||
// Create and launch the thread.
|
||||
auto tempWriteThread = |
||||
sp<WriteThread>::make(&mStopWriteThread, mStream, tempCommandMQ.get(), tempDataMQ.get(), |
||||
tempStatusMQ.get(), tempElfGroup.get()); |
||||
if (!tempWriteThread->init()) { |
||||
ALOGW("failed to start writer thread: %s", strerror(-status)); |
||||
sendError(Result::INVALID_ARGUMENTS); |
||||
return Void(); |
||||
} |
||||
status = tempWriteThread->run("writer", PRIORITY_URGENT_AUDIO); |
||||
if (status != OK) { |
||||
ALOGW("failed to start writer thread: %s", strerror(-status)); |
||||
sendError(Result::INVALID_ARGUMENTS); |
||||
return Void(); |
||||
} |
||||
|
||||
mCommandMQ = std::move(tempCommandMQ); |
||||
mDataMQ = std::move(tempDataMQ); |
||||
mStatusMQ = std::move(tempStatusMQ); |
||||
mWriteThread = tempWriteThread; |
||||
mEfGroup = tempElfGroup.release(); |
||||
#if MAJOR_VERSION <= 6 |
||||
threadInfo.pid = getpid(); |
||||
threadInfo.tid = mWriteThread->getTid(); |
||||
#else |
||||
threadInfo = mWriteThread->getTid(); |
||||
#endif |
||||
_hidl_cb(Result::OK, *mCommandMQ->getDesc(), *mDataMQ->getDesc(), *mStatusMQ->getDesc(), |
||||
threadInfo); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<void> StreamOut::getRenderPosition(getRenderPosition_cb _hidl_cb) { |
||||
uint32_t halDspFrames; |
||||
Result retval = Stream::analyzeStatus("get_render_position", |
||||
mStream->get_render_position(mStream, &halDspFrames), |
||||
{ENOSYS} /*ignore*/); |
||||
_hidl_cb(retval, halDspFrames); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<void> StreamOut::getNextWriteTimestamp(getNextWriteTimestamp_cb _hidl_cb) { |
||||
Result retval(Result::NOT_SUPPORTED); |
||||
int64_t timestampUs = 0; |
||||
if (mStream->get_next_write_timestamp != NULL) { |
||||
retval = Stream::analyzeStatus("get_next_write_timestamp", |
||||
mStream->get_next_write_timestamp(mStream, ×tampUs), |
||||
{ENOSYS} /*ignore*/); |
||||
} |
||||
_hidl_cb(retval, timestampUs); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<Result> StreamOut::setCallback(const sp<IStreamOutCallback>& callback) { |
||||
if (mStream->set_callback == NULL) return Result::NOT_SUPPORTED; |
||||
// Safe to pass 'this' because it is guaranteed that the callback thread
|
||||
// is joined prior to exit from StreamOut's destructor.
|
||||
int result = mStream->set_callback(mStream, StreamOut::asyncCallback, this); |
||||
if (result == 0) { |
||||
mCallback = callback; |
||||
} |
||||
return Stream::analyzeStatus("set_callback", result, {ENOSYS} /*ignore*/); |
||||
} |
||||
|
||||
Return<Result> StreamOut::clearCallback() { |
||||
if (mStream->set_callback == NULL) return Result::NOT_SUPPORTED; |
||||
mCallback = nullptr; |
||||
return Result::OK; |
||||
} |
||||
|
||||
// static
|
||||
int StreamOut::asyncCallback(stream_callback_event_t event, void*, void* cookie) { |
||||
// It is guaranteed that the callback thread is joined prior
|
||||
// to exiting from StreamOut's destructor. Must *not* use sp<StreamOut>
|
||||
// here because it can make this code the last owner of StreamOut,
|
||||
// and an attempt to run the destructor on the callback thread
|
||||
// will cause a deadlock in the legacy HAL code.
|
||||
StreamOut* self = reinterpret_cast<StreamOut*>(cookie); |
||||
// It's correct to hold an sp<> to callback because the reference
|
||||
// in the StreamOut instance can be cleared in the meantime. There is
|
||||
// no difference on which thread to run IStreamOutCallback's destructor.
|
||||
sp<IStreamOutCallback> callback = self->mCallback.load(); |
||||
if (callback.get() == nullptr) return 0; |
||||
ALOGV("asyncCallback() event %d", event); |
||||
Return<void> result; |
||||
switch (event) { |
||||
case STREAM_CBK_EVENT_WRITE_READY: |
||||
result = callback->onWriteReady(); |
||||
break; |
||||
case STREAM_CBK_EVENT_DRAIN_READY: |
||||
result = callback->onDrainReady(); |
||||
break; |
||||
case STREAM_CBK_EVENT_ERROR: |
||||
result = callback->onError(); |
||||
break; |
||||
default: |
||||
ALOGW("asyncCallback() unknown event %d", event); |
||||
break; |
||||
} |
||||
ALOGW_IF(!result.isOk(), "Client callback failed: %s", result.description().c_str()); |
||||
return 0; |
||||
} |
||||
|
||||
Return<void> StreamOut::supportsPauseAndResume(supportsPauseAndResume_cb _hidl_cb) { |
||||
_hidl_cb(mStream->pause != NULL, mStream->resume != NULL); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<Result> StreamOut::pause() { |
||||
return mStream->pause != NULL |
||||
? Stream::analyzeStatus("pause", mStream->pause(mStream), {ENOSYS} /*ignore*/) |
||||
: Result::NOT_SUPPORTED; |
||||
} |
||||
|
||||
Return<Result> StreamOut::resume() { |
||||
return mStream->resume != NULL |
||||
? Stream::analyzeStatus("resume", mStream->resume(mStream), {ENOSYS} /*ignore*/) |
||||
: Result::NOT_SUPPORTED; |
||||
} |
||||
|
||||
Return<bool> StreamOut::supportsDrain() { |
||||
return mStream->drain != NULL; |
||||
} |
||||
|
||||
Return<Result> StreamOut::drain(AudioDrain type) { |
||||
audio_drain_type_t halDrainType = |
||||
type == AudioDrain::EARLY_NOTIFY ? AUDIO_DRAIN_EARLY_NOTIFY : AUDIO_DRAIN_ALL; |
||||
return mStream->drain != NULL |
||||
? Stream::analyzeStatus("drain", mStream->drain(mStream, halDrainType), |
||||
{ENOSYS} /*ignore*/) |
||||
: Result::NOT_SUPPORTED; |
||||
} |
||||
|
||||
Return<Result> StreamOut::flush() { |
||||
return mStream->flush != NULL |
||||
? Stream::analyzeStatus("flush", mStream->flush(mStream), {ENOSYS} /*ignore*/) |
||||
: Result::NOT_SUPPORTED; |
||||
} |
||||
|
||||
// static
|
||||
Result StreamOut::getPresentationPositionImpl(audio_stream_out_t* stream, uint64_t* frames, |
||||
TimeSpec* timeStamp) { |
||||
// Don't logspam on EINVAL--it's normal for get_presentation_position
|
||||
// to return it sometimes. EAGAIN may be returned by A2DP audio HAL
|
||||
// implementation. ENODATA can also be reported while the writer is
|
||||
// continuously querying it, but the stream has been stopped.
|
||||
static const std::vector<int> ignoredErrors{EINVAL, EAGAIN, ENODATA, ENOSYS}; |
||||
Result retval(Result::NOT_SUPPORTED); |
||||
if (stream->get_presentation_position == NULL) return retval; |
||||
struct timespec halTimeStamp; |
||||
retval = Stream::analyzeStatus("get_presentation_position", |
||||
stream->get_presentation_position(stream, frames, &halTimeStamp), |
||||
ignoredErrors); |
||||
if (retval == Result::OK) { |
||||
timeStamp->tvSec = halTimeStamp.tv_sec; |
||||
timeStamp->tvNSec = halTimeStamp.tv_nsec; |
||||
} |
||||
return retval; |
||||
} |
||||
|
||||
Return<void> StreamOut::getPresentationPosition(getPresentationPosition_cb _hidl_cb) { |
||||
uint64_t frames = 0; |
||||
TimeSpec timeStamp = {0, 0}; |
||||
Result retval = getPresentationPositionImpl(mStream, &frames, &timeStamp); |
||||
_hidl_cb(retval, frames, timeStamp); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<Result> StreamOut::start() { |
||||
return mStreamMmap->start(); |
||||
} |
||||
|
||||
Return<Result> StreamOut::stop() { |
||||
return mStreamMmap->stop(); |
||||
} |
||||
|
||||
Return<void> StreamOut::createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) { |
||||
return mStreamMmap->createMmapBuffer(minSizeFrames, audio_stream_out_frame_size(mStream), |
||||
_hidl_cb); |
||||
} |
||||
|
||||
Return<void> StreamOut::getMmapPosition(getMmapPosition_cb _hidl_cb) { |
||||
return mStreamMmap->getMmapPosition(_hidl_cb); |
||||
} |
||||
|
||||
Return<void> StreamOut::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) { |
||||
return mStreamCommon->debug(fd, options); |
||||
} |
||||
|
||||
#if MAJOR_VERSION >= 4 |
||||
Result StreamOut::doUpdateSourceMetadata(const SourceMetadata& sourceMetadata) { |
||||
std::vector<playback_track_metadata_t> halTracks; |
||||
#if MAJOR_VERSION <= 6 |
||||
(void)CoreUtils::sourceMetadataToHal(sourceMetadata, &halTracks); |
||||
#else |
||||
// Validate whether a conversion to V7 is possible. This is needed
|
||||
// to have a consistent behavior of the HAL regardless of the API
|
||||
// version of the legacy HAL (and also to be consistent with openOutputStream).
|
||||
std::vector<playback_track_metadata_v7> halTracksV7; |
||||
if (status_t status = CoreUtils::sourceMetadataToHalV7( |
||||
sourceMetadata, false /*ignoreNonVendorTags*/, &halTracksV7); |
||||
status == NO_ERROR) { |
||||
halTracks.reserve(halTracksV7.size()); |
||||
for (auto metadata_v7 : halTracksV7) { |
||||
halTracks.push_back(std::move(metadata_v7.base)); |
||||
} |
||||
} else { |
||||
return Stream::analyzeStatus("sourceMetadataToHal", status); |
||||
} |
||||
#endif // MAJOR_VERSION <= 6
|
||||
const source_metadata_t halMetadata = { |
||||
.track_count = halTracks.size(), |
||||
.tracks = halTracks.data(), |
||||
}; |
||||
mStream->update_source_metadata(mStream, &halMetadata); |
||||
return Result::OK; |
||||
} |
||||
|
||||
#if MAJOR_VERSION >= 7 |
||||
Result StreamOut::doUpdateSourceMetadataV7(const SourceMetadata& sourceMetadata) { |
||||
std::vector<playback_track_metadata_v7> halTracks; |
||||
if (status_t status = CoreUtils::sourceMetadataToHalV7( |
||||
sourceMetadata, false /*ignoreNonVendorTags*/, &halTracks); |
||||
status != NO_ERROR) { |
||||
return Stream::analyzeStatus("sourceMetadataToHal", status); |
||||
} |
||||
const source_metadata_v7_t halMetadata = { |
||||
.track_count = halTracks.size(), |
||||
.tracks = halTracks.data(), |
||||
}; |
||||
mStream->update_source_metadata_v7(mStream, &halMetadata); |
||||
return Result::OK; |
||||
} |
||||
#endif // MAJOR_VERSION >= 7
|
||||
|
||||
#if MAJOR_VERSION <= 6 |
||||
Return<void> StreamOut::updateSourceMetadata(const SourceMetadata& sourceMetadata) { |
||||
if (mStream->update_source_metadata == nullptr) { |
||||
return Void(); // not supported by the HAL
|
||||
} |
||||
(void)doUpdateSourceMetadata(sourceMetadata); |
||||
return Void(); |
||||
} |
||||
#elif MAJOR_VERSION >= 7 |
||||
Return<Result> StreamOut::updateSourceMetadata(const SourceMetadata& sourceMetadata) { |
||||
if (mDevice->version() < AUDIO_DEVICE_API_VERSION_3_2) { |
||||
if (mStream->update_source_metadata == nullptr) { |
||||
return Result::NOT_SUPPORTED; |
||||
} |
||||
return doUpdateSourceMetadata(sourceMetadata); |
||||
} else { |
||||
if (mStream->update_source_metadata_v7 == nullptr) { |
||||
return Result::NOT_SUPPORTED; |
||||
} |
||||
return doUpdateSourceMetadataV7(sourceMetadata); |
||||
} |
||||
} |
||||
#endif |
||||
|
||||
Return<Result> StreamOut::selectPresentation(int32_t /*presentationId*/, int32_t /*programId*/) { |
||||
return Result::NOT_SUPPORTED; // TODO: propagate to legacy
|
||||
} |
||||
#endif |
||||
|
||||
#if MAJOR_VERSION >= 6 |
||||
Return<void> StreamOut::getDualMonoMode(getDualMonoMode_cb _hidl_cb) { |
||||
audio_dual_mono_mode_t mode = AUDIO_DUAL_MONO_MODE_OFF; |
||||
Result retval = mStream->get_dual_mono_mode != nullptr |
||||
? Stream::analyzeStatus("get_dual_mono_mode", |
||||
mStream->get_dual_mono_mode(mStream, &mode)) |
||||
: Result::NOT_SUPPORTED; |
||||
_hidl_cb(retval, DualMonoMode(mode)); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<Result> StreamOut::setDualMonoMode(DualMonoMode mode) { |
||||
return mStream->set_dual_mono_mode != nullptr |
||||
? Stream::analyzeStatus( |
||||
"set_dual_mono_mode", |
||||
mStream->set_dual_mono_mode(mStream, |
||||
static_cast<audio_dual_mono_mode_t>(mode))) |
||||
: Result::NOT_SUPPORTED; |
||||
} |
||||
|
||||
Return<void> StreamOut::getAudioDescriptionMixLevel(getAudioDescriptionMixLevel_cb _hidl_cb) { |
||||
float leveldB = -std::numeric_limits<float>::infinity(); |
||||
Result retval = mStream->get_audio_description_mix_level != nullptr |
||||
? Stream::analyzeStatus( |
||||
"get_audio_description_mix_level", |
||||
mStream->get_audio_description_mix_level(mStream, &leveldB)) |
||||
: Result::NOT_SUPPORTED; |
||||
_hidl_cb(retval, leveldB); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<Result> StreamOut::setAudioDescriptionMixLevel(float leveldB) { |
||||
return mStream->set_audio_description_mix_level != nullptr |
||||
? Stream::analyzeStatus( |
||||
"set_audio_description_mix_level", |
||||
mStream->set_audio_description_mix_level(mStream, leveldB)) |
||||
: Result::NOT_SUPPORTED; |
||||
} |
||||
|
||||
Return<void> StreamOut::getPlaybackRateParameters(getPlaybackRateParameters_cb _hidl_cb) { |
||||
audio_playback_rate_t rate = AUDIO_PLAYBACK_RATE_INITIALIZER; |
||||
Result retval = |
||||
mStream->get_playback_rate_parameters != nullptr |
||||
? Stream::analyzeStatus("get_playback_rate_parameters", |
||||
mStream->get_playback_rate_parameters(mStream, &rate)) |
||||
: Result::NOT_SUPPORTED; |
||||
_hidl_cb(retval, |
||||
PlaybackRate{rate.mSpeed, rate.mPitch, static_cast<TimestretchMode>(rate.mStretchMode), |
||||
static_cast<TimestretchFallbackMode>(rate.mFallbackMode)}); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<Result> StreamOut::setPlaybackRateParameters(const PlaybackRate& playbackRate) { |
||||
audio_playback_rate_t rate = { |
||||
playbackRate.speed, playbackRate.pitch, |
||||
static_cast<audio_timestretch_stretch_mode_t>(playbackRate.timestretchMode), |
||||
static_cast<audio_timestretch_fallback_mode_t>(playbackRate.fallbackMode)}; |
||||
return mStream->set_playback_rate_parameters != nullptr |
||||
? Stream::analyzeStatus("set_playback_rate_parameters", |
||||
mStream->set_playback_rate_parameters(mStream, &rate)) |
||||
: Result::NOT_SUPPORTED; |
||||
} |
||||
|
||||
Return<Result> StreamOut::setEventCallback(const sp<IStreamOutEventCallback>& callback) { |
||||
if (mStream->set_event_callback == nullptr) return Result::NOT_SUPPORTED; |
||||
int result = mStream->set_event_callback(mStream, StreamOut::asyncEventCallback, this); |
||||
if (result == 0) { |
||||
mEventCallback = callback; |
||||
} |
||||
return Stream::analyzeStatus("set_stream_out_callback", result, {ENOSYS} /*ignore*/); |
||||
} |
||||
|
||||
// static
|
||||
int StreamOut::asyncEventCallback(stream_event_callback_type_t event, void* param, void* cookie) { |
||||
StreamOut* self = reinterpret_cast<StreamOut*>(cookie); |
||||
sp<IStreamOutEventCallback> eventCallback = self->mEventCallback.load(); |
||||
if (eventCallback.get() == nullptr) return 0; |
||||
ALOGV("%s event %d", __func__, event); |
||||
Return<void> result; |
||||
switch (event) { |
||||
case STREAM_EVENT_CBK_TYPE_CODEC_FORMAT_CHANGED: { |
||||
hidl_vec<uint8_t> audioMetadata; |
||||
// void* param is the byte string buffer from byte_string_from_audio_metadata().
|
||||
// As the byte string buffer may have embedded zeroes, we cannot use strlen()
|
||||
// but instead use audio_utils::metadata::dataByteStringLen().
|
||||
audioMetadata.setToExternal((uint8_t*)param, audio_utils::metadata::dataByteStringLen( |
||||
(const uint8_t*)param)); |
||||
result = eventCallback->onCodecFormatChanged(audioMetadata); |
||||
} break; |
||||
default: |
||||
ALOGW("%s unknown event %d", __func__, event); |
||||
break; |
||||
} |
||||
ALOGW_IF(!result.isOk(), "Client callback failed: %s", result.description().c_str()); |
||||
return 0; |
||||
} |
||||
|
||||
#if MAJOR_VERSION == 7 && MINOR_VERSION == 1 |
||||
Return<Result> StreamOut::setLatencyMode(LatencyMode mode) { |
||||
return mStream->set_latency_mode != nullptr |
||||
? Stream::analyzeStatus( |
||||
"set_latency_mode", |
||||
mStream->set_latency_mode(mStream, |
||||
static_cast<audio_latency_mode_t>(mode))) |
||||
: Result::NOT_SUPPORTED; |
||||
}; |
||||
|
||||
Return<void> StreamOut::getRecommendedLatencyModes(getRecommendedLatencyModes_cb _hidl_cb) { |
||||
Result retval = Result::NOT_SUPPORTED; |
||||
hidl_vec<LatencyMode> hidlModes; |
||||
size_t num_modes = AUDIO_LATENCY_MODE_CNT; |
||||
audio_latency_mode_t modes[AUDIO_LATENCY_MODE_CNT]; |
||||
|
||||
if (mStream->get_recommended_latency_modes != nullptr && |
||||
mStream->get_recommended_latency_modes(mStream, &modes[0], &num_modes) == 0) { |
||||
if (num_modes == 0 || num_modes > AUDIO_LATENCY_MODE_CNT) { |
||||
ALOGW("%s invalid number of modes returned: %zu", __func__, num_modes); |
||||
retval = Result::INVALID_STATE; |
||||
} else { |
||||
hidlModes.resize(num_modes); |
||||
for (size_t i = 0; i < num_modes; ++i) { |
||||
hidlModes[i] = static_cast<LatencyMode>(modes[i]); |
||||
} |
||||
retval = Result::OK; |
||||
} |
||||
} |
||||
_hidl_cb(retval, hidlModes); |
||||
return Void(); |
||||
}; |
||||
|
||||
// static
|
||||
void StreamOut::latencyModeCallback(audio_latency_mode_t* modes, size_t num_modes, void* cookie) { |
||||
StreamOut* self = reinterpret_cast<StreamOut*>(cookie); |
||||
sp<IStreamOutLatencyModeCallback> callback = self->mLatencyModeCallback.load(); |
||||
if (callback.get() == nullptr) return; |
||||
|
||||
ALOGV("%s", __func__); |
||||
|
||||
if (num_modes == 0 || num_modes > AUDIO_LATENCY_MODE_CNT) { |
||||
ALOGW("%s invalid number of modes returned: %zu", __func__, num_modes); |
||||
return; |
||||
} |
||||
|
||||
hidl_vec<LatencyMode> hidlModes(num_modes); |
||||
for (size_t i = 0; i < num_modes; ++i) { |
||||
hidlModes[i] = static_cast<LatencyMode>(modes[i]); |
||||
} |
||||
Return<void> result = callback->onRecommendedLatencyModeChanged(hidlModes); |
||||
ALOGW_IF(!result.isOk(), "Client callback failed: %s", result.description().c_str()); |
||||
} |
||||
|
||||
Return<Result> StreamOut::setLatencyModeCallback( |
||||
const sp<IStreamOutLatencyModeCallback>& callback) { |
||||
if (mStream->set_latency_mode_callback == nullptr) return Result::NOT_SUPPORTED; |
||||
int result = mStream->set_latency_mode_callback(mStream, StreamOut::latencyModeCallback, this); |
||||
if (result == 0) { |
||||
mLatencyModeCallback = callback; |
||||
} |
||||
return Stream::analyzeStatus("set_latency_mode_callback", result, {ENOSYS} /*ignore*/); |
||||
}; |
||||
|
||||
#endif |
||||
|
||||
#endif |
||||
|
||||
} // namespace implementation
|
||||
} // namespace CPP_VERSION
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
@ -0,0 +1,204 @@ |
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#ifndef ANDROID_HARDWARE_AUDIO_DEVICE_H |
||||
#define ANDROID_HARDWARE_AUDIO_DEVICE_H |
||||
|
||||
#include PATH(android/hardware/audio/FILE_VERSION/IDevice.h) |
||||
|
||||
#include "ParametersUtil.h" |
||||
|
||||
#include <memory> |
||||
|
||||
#include <hardware/audio.h> |
||||
#include <media/AudioParameter.h> |
||||
|
||||
#include <hidl/Status.h> |
||||
|
||||
#include <hidl/MQDescriptor.h> |
||||
|
||||
#include <VersionUtils.h> |
||||
#include <util/CoreUtils.h> |
||||
|
||||
namespace android { |
||||
namespace hardware { |
||||
namespace audio { |
||||
namespace CPP_VERSION { |
||||
namespace implementation { |
||||
|
||||
using ::android::sp; |
||||
using ::android::hardware::hidl_string; |
||||
using ::android::hardware::hidl_vec; |
||||
using ::android::hardware::Return; |
||||
using ::android::hardware::Void; |
||||
using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::CoreUtils; |
||||
using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::ParametersUtil; |
||||
using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION; |
||||
using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION; |
||||
using namespace ::android::hardware::audio::CPP_VERSION; |
||||
using AudioInputFlags = CoreUtils::AudioInputFlags; |
||||
using AudioOutputFlags = CoreUtils::AudioOutputFlags; |
||||
|
||||
struct Device : public IDevice, public ParametersUtil { |
||||
explicit Device(audio_hw_device_t* device); |
||||
|
||||
// Methods from ::android::hardware::audio::CPP_VERSION::IDevice follow.
|
||||
Return<Result> initCheck() override; |
||||
Return<Result> setMasterVolume(float volume) override; |
||||
Return<void> getMasterVolume(getMasterVolume_cb _hidl_cb) override; |
||||
Return<Result> setMicMute(bool mute) override; |
||||
Return<void> getMicMute(getMicMute_cb _hidl_cb) override; |
||||
Return<Result> setMasterMute(bool mute) override; |
||||
Return<void> getMasterMute(getMasterMute_cb _hidl_cb) override; |
||||
Return<void> getInputBufferSize(const AudioConfig& config, |
||||
getInputBufferSize_cb _hidl_cb) override; |
||||
|
||||
std::tuple<Result, sp<IStreamOut>> openOutputStreamCore(int32_t ioHandle, |
||||
const DeviceAddress& device, |
||||
const AudioConfig& config, |
||||
const AudioOutputFlags& flags, |
||||
AudioConfig* suggestedConfig); |
||||
std::tuple<Result, sp<IStreamIn>> openInputStreamCore( |
||||
int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config, |
||||
const AudioInputFlags& flags, AudioSource source, AudioConfig* suggestedConfig); |
||||
#if MAJOR_VERSION >= 4 |
||||
std::tuple<Result, sp<IStreamOut>, AudioConfig> openOutputStreamImpl( |
||||
int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config, |
||||
const SourceMetadata& sourceMetadata, |
||||
#if MAJOR_VERSION <= 6 |
||||
AudioOutputFlags flags); |
||||
#else |
||||
const AudioOutputFlags& flags); |
||||
#endif |
||||
std::tuple<Result, sp<IStreamIn>, AudioConfig> openInputStreamImpl( |
||||
int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config, |
||||
#if MAJOR_VERSION <= 6 |
||||
AudioInputFlags flags, |
||||
#else |
||||
const AudioInputFlags& flags, |
||||
#endif |
||||
const SinkMetadata& sinkMetadata); |
||||
#endif // MAJOR_VERSION >= 4
|
||||
|
||||
Return<void> openOutputStream(int32_t ioHandle, const DeviceAddress& device, |
||||
const AudioConfig& config, |
||||
#if MAJOR_VERSION <= 6 |
||||
AudioOutputFlags flags, |
||||
#else |
||||
const AudioOutputFlags& flags, |
||||
#endif |
||||
#if MAJOR_VERSION >= 4 |
||||
const SourceMetadata& sourceMetadata, |
||||
#endif |
||||
openOutputStream_cb _hidl_cb) override; |
||||
Return<void> openInputStream(int32_t ioHandle, const DeviceAddress& device, |
||||
const AudioConfig& config, |
||||
#if MAJOR_VERSION <= 6 |
||||
AudioInputFlags flags, |
||||
#else |
||||
const AudioInputFlags& flags, |
||||
#endif |
||||
#if MAJOR_VERSION == 2 |
||||
AudioSource source, |
||||
#elif MAJOR_VERSION >= 4 |
||||
const SinkMetadata& sinkMetadata, |
||||
#endif |
||||
openInputStream_cb _hidl_cb) override; |
||||
|
||||
#if MAJOR_VERSION == 7 && MINOR_VERSION == 1 |
||||
Return<void> openOutputStream_7_1(int32_t ioHandle, const DeviceAddress& device, |
||||
const AudioConfig& config, const AudioOutputFlags& flags, |
||||
const SourceMetadata& sourceMetadata, |
||||
openOutputStream_7_1_cb _hidl_cb) override; |
||||
#endif |
||||
|
||||
Return<bool> supportsAudioPatches() override; |
||||
Return<void> createAudioPatch(const hidl_vec<AudioPortConfig>& sources, |
||||
const hidl_vec<AudioPortConfig>& sinks, |
||||
createAudioPatch_cb _hidl_cb) override; |
||||
Return<Result> releaseAudioPatch(int32_t patch) override; |
||||
Return<void> getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) override; |
||||
Return<Result> setAudioPortConfig(const AudioPortConfig& config) override; |
||||
|
||||
Return<Result> setScreenState(bool turnedOn) override; |
||||
|
||||
#if MAJOR_VERSION == 2 |
||||
Return<AudioHwSync> getHwAvSync() override; |
||||
Return<void> getParameters(const hidl_vec<hidl_string>& keys, |
||||
getParameters_cb _hidl_cb) override; |
||||
Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters) override; |
||||
Return<void> debugDump(const hidl_handle& fd) override; |
||||
#elif MAJOR_VERSION >= 4 |
||||
Return<void> getHwAvSync(getHwAvSync_cb _hidl_cb) override; |
||||
Return<void> getParameters(const hidl_vec<ParameterValue>& context, |
||||
const hidl_vec<hidl_string>& keys, |
||||
getParameters_cb _hidl_cb) override; |
||||
Return<Result> setParameters(const hidl_vec<ParameterValue>& context, |
||||
const hidl_vec<ParameterValue>& parameters) override; |
||||
Return<void> getMicrophones(getMicrophones_cb _hidl_cb) override; |
||||
Return<Result> setConnectedState(const DeviceAddress& address, bool connected) override; |
||||
#endif |
||||
#if MAJOR_VERSION >= 6 |
||||
Return<Result> close() override; |
||||
Return<Result> addDeviceEffect(AudioPortHandle device, uint64_t effectId) override; |
||||
Return<Result> removeDeviceEffect(AudioPortHandle device, uint64_t effectId) override; |
||||
Return<void> updateAudioPatch(int32_t previousPatch, const hidl_vec<AudioPortConfig>& sources, |
||||
const hidl_vec<AudioPortConfig>& sinks, |
||||
createAudioPatch_cb _hidl_cb) override; |
||||
#endif |
||||
#if MAJOR_VERSION == 7 && MINOR_VERSION == 1 |
||||
Return<Result> setConnectedState_7_1(const AudioPort& devicePort, bool connected) override; |
||||
#endif |
||||
Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override; |
||||
|
||||
// Utility methods for extending interfaces.
|
||||
Result analyzeStatus(const char* funcName, int status, |
||||
const std::vector<int>& ignoreErrors = {}); |
||||
void closeInputStream(audio_stream_in_t* stream); |
||||
void closeOutputStream(audio_stream_out_t* stream); |
||||
audio_hw_device_t* device() const { return mDevice; } |
||||
|
||||
uint32_t version() const { return mDevice->common.version; } |
||||
|
||||
int halSetParameters(const char* keysAndValues) override; |
||||
|
||||
private: |
||||
bool mIsClosed; |
||||
audio_hw_device_t* mDevice; |
||||
int mOpenedStreamsCount = 0; |
||||
|
||||
virtual ~Device(); |
||||
|
||||
Result doClose(); |
||||
std::tuple<Result, AudioPatchHandle> createOrUpdateAudioPatch( |
||||
AudioPatchHandle patch, const hidl_vec<AudioPortConfig>& sources, |
||||
const hidl_vec<AudioPortConfig>& sinks); |
||||
template <typename HalPort> |
||||
Return<void> getAudioPortImpl(const AudioPort& port, getAudioPort_cb _hidl_cb, |
||||
int (*halGetter)(audio_hw_device_t*, HalPort*), |
||||
const char* halGetterName); |
||||
|
||||
// Methods from ParametersUtil.
|
||||
char* halGetParameters(const char* keys) override; |
||||
}; |
||||
|
||||
} // namespace implementation
|
||||
} // namespace CPP_VERSION
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_HARDWARE_AUDIO_DEVICE_H
|
@ -0,0 +1,70 @@ |
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#ifndef ANDROID_HARDWARE_AUDIO_DEVICESFACTORY_H |
||||
#define ANDROID_HARDWARE_AUDIO_DEVICESFACTORY_H |
||||
|
||||
#include PATH(android/hardware/audio/FILE_VERSION/IDevicesFactory.h) |
||||
|
||||
#include <hardware/audio.h> |
||||
|
||||
#include <hidl/Status.h> |
||||
|
||||
#include <hidl/MQDescriptor.h> |
||||
namespace android { |
||||
namespace hardware { |
||||
namespace audio { |
||||
namespace CPP_VERSION { |
||||
namespace implementation { |
||||
|
||||
using ::android::sp; |
||||
using ::android::hardware::hidl_string; |
||||
using ::android::hardware::hidl_vec; |
||||
using ::android::hardware::Return; |
||||
using ::android::hardware::Void; |
||||
using namespace ::android::hardware::audio::CPP_VERSION; |
||||
|
||||
struct DevicesFactory : public IDevicesFactory { |
||||
#if MAJOR_VERSION == 2 |
||||
Return<void> openDevice(IDevicesFactory::Device device, openDevice_cb _hidl_cb) override; |
||||
#elif MAJOR_VERSION >= 4 |
||||
Return<void> openDevice(const hidl_string& device, openDevice_cb _hidl_cb) override; |
||||
Return<void> openPrimaryDevice(openPrimaryDevice_cb _hidl_cb) override; |
||||
#endif |
||||
#if MAJOR_VERSION == 7 && MINOR_VERSION == 1 |
||||
Return<void> openDevice_7_1(const hidl_string& device, openDevice_7_1_cb _hidl_cb) override; |
||||
Return<void> openPrimaryDevice_7_1(openPrimaryDevice_7_1_cb _hidl_cb) override; |
||||
#endif |
||||
|
||||
private: |
||||
template <class DeviceShim, class Callback> |
||||
Return<void> openDevice(const char* moduleName, Callback _hidl_cb); |
||||
#if MAJOR_VERSION == 2 |
||||
Return<void> openDevice(const char* moduleName, openDevice_cb _hidl_cb); |
||||
#endif |
||||
|
||||
static int loadAudioInterface(const char* if_name, audio_hw_device_t** dev); |
||||
}; |
||||
|
||||
extern "C" IDevicesFactory* HIDL_FETCH_IDevicesFactory(const char* name); |
||||
|
||||
} // namespace implementation
|
||||
} // namespace CPP_VERSION
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_HARDWARE_AUDIO_DEVICESFACTORY_H
|
@ -0,0 +1,73 @@ |
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#ifndef ANDROID_HARDWARE_AUDIO_PARAMETERS_UTIL_H_ |
||||
#define ANDROID_HARDWARE_AUDIO_PARAMETERS_UTIL_H_ |
||||
|
||||
// clang-format off
|
||||
#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h) |
||||
#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h) |
||||
// clang-format on
|
||||
|
||||
#include <functional> |
||||
#include <memory> |
||||
|
||||
#include <hidl/HidlSupport.h> |
||||
#include <media/AudioParameter.h> |
||||
|
||||
namespace android { |
||||
namespace hardware { |
||||
namespace audio { |
||||
namespace CORE_TYPES_CPP_VERSION { |
||||
namespace implementation { |
||||
|
||||
using ::android::hardware::hidl_string; |
||||
using ::android::hardware::hidl_vec; |
||||
using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION; |
||||
using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION; |
||||
|
||||
class ParametersUtil { |
||||
public: |
||||
Result setParam(const char* name, const char* value); |
||||
Result getParam(const char* name, bool* value); |
||||
Result getParam(const char* name, int* value); |
||||
Result getParam(const char* name, String8* value, AudioParameter context = {}); |
||||
void getParametersImpl( |
||||
const hidl_vec<ParameterValue>& context, const hidl_vec<hidl_string>& keys, |
||||
std::function<void(Result retval, const hidl_vec<ParameterValue>& parameters)> cb); |
||||
std::unique_ptr<AudioParameter> getParams(const AudioParameter& keys); |
||||
Result setParam(const char* name, bool value); |
||||
Result setParam(const char* name, int value); |
||||
Result setParam(const char* name, float value); |
||||
Result setParametersImpl(const hidl_vec<ParameterValue>& context, |
||||
const hidl_vec<ParameterValue>& parameters); |
||||
Result setParams(const AudioParameter& param); |
||||
Result setParam(const char* name, const DeviceAddress& address); |
||||
|
||||
protected: |
||||
virtual ~ParametersUtil() {} |
||||
|
||||
virtual char* halGetParameters(const char* keys) = 0; |
||||
virtual int halSetParameters(const char* keysAndValues) = 0; |
||||
}; |
||||
|
||||
} // namespace implementation
|
||||
} // namespace CORE_TYPES_CPP_VERSION
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_HARDWARE_AUDIO_PARAMETERS_UTIL_H_
|
@ -0,0 +1,154 @@ |
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#ifndef ANDROID_HARDWARE_AUDIO_PRIMARYDEVICE_H |
||||
#define ANDROID_HARDWARE_AUDIO_PRIMARYDEVICE_H |
||||
|
||||
#include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h) |
||||
|
||||
#include "Device.h" |
||||
|
||||
#include <hidl/Status.h> |
||||
|
||||
#include <hidl/MQDescriptor.h> |
||||
|
||||
namespace android { |
||||
namespace hardware { |
||||
namespace audio { |
||||
namespace CPP_VERSION { |
||||
namespace implementation { |
||||
|
||||
using ::android::sp; |
||||
using ::android::hardware::hidl_string; |
||||
using ::android::hardware::hidl_vec; |
||||
using ::android::hardware::Return; |
||||
using ::android::hardware::Void; |
||||
using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION; |
||||
using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION; |
||||
using namespace ::android::hardware::audio::CPP_VERSION; |
||||
|
||||
struct PrimaryDevice : public IPrimaryDevice { |
||||
explicit PrimaryDevice(audio_hw_device_t* device); |
||||
|
||||
// Methods from ::android::hardware::audio::CPP_VERSION::IDevice follow.
|
||||
Return<Result> initCheck() override; |
||||
Return<Result> setMasterVolume(float volume) override; |
||||
Return<void> getMasterVolume(getMasterVolume_cb _hidl_cb) override; |
||||
Return<Result> setMicMute(bool mute) override; |
||||
Return<void> getMicMute(getMicMute_cb _hidl_cb) override; |
||||
Return<Result> setMasterMute(bool mute) override; |
||||
Return<void> getMasterMute(getMasterMute_cb _hidl_cb) override; |
||||
Return<void> getInputBufferSize(const AudioConfig& config, |
||||
getInputBufferSize_cb _hidl_cb) override; |
||||
|
||||
Return<void> openOutputStream(int32_t ioHandle, const DeviceAddress& device, |
||||
const AudioConfig& config, |
||||
#if MAJOR_VERSION <= 6 |
||||
AudioOutputFlags flags, |
||||
#else |
||||
const AudioOutputFlags& flags, |
||||
#endif |
||||
#if MAJOR_VERSION >= 4 |
||||
const SourceMetadata& sourceMetadata, |
||||
#endif |
||||
openOutputStream_cb _hidl_cb) override; |
||||
Return<void> openInputStream(int32_t ioHandle, const DeviceAddress& device, |
||||
const AudioConfig& config, |
||||
#if MAJOR_VERSION <= 6 |
||||
AudioInputFlags flags, |
||||
#else |
||||
const AudioInputFlags& flags, |
||||
#endif |
||||
#if MAJOR_VERSION == 2 |
||||
AudioSource source, |
||||
#elif MAJOR_VERSION >= 4 |
||||
const SinkMetadata& sinkMetadata, |
||||
#endif |
||||
openInputStream_cb _hidl_cb) override; |
||||
|
||||
Return<bool> supportsAudioPatches() override; |
||||
Return<void> createAudioPatch(const hidl_vec<AudioPortConfig>& sources, |
||||
const hidl_vec<AudioPortConfig>& sinks, |
||||
createAudioPatch_cb _hidl_cb) override; |
||||
Return<Result> releaseAudioPatch(int32_t patch) override; |
||||
Return<void> getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) override; |
||||
Return<Result> setAudioPortConfig(const AudioPortConfig& config) override; |
||||
|
||||
Return<Result> setScreenState(bool turnedOn) override; |
||||
|
||||
#if MAJOR_VERSION == 2 |
||||
Return<AudioHwSync> getHwAvSync() override; |
||||
Return<void> getParameters(const hidl_vec<hidl_string>& keys, |
||||
getParameters_cb _hidl_cb) override; |
||||
Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters) override; |
||||
Return<void> debugDump(const hidl_handle& fd) override; |
||||
#elif MAJOR_VERSION >= 4 |
||||
Return<void> getHwAvSync(getHwAvSync_cb _hidl_cb) override; |
||||
Return<void> getParameters(const hidl_vec<ParameterValue>& context, |
||||
const hidl_vec<hidl_string>& keys, |
||||
getParameters_cb _hidl_cb) override; |
||||
Return<Result> setParameters(const hidl_vec<ParameterValue>& context, |
||||
const hidl_vec<ParameterValue>& parameters) override; |
||||
Return<void> getMicrophones(getMicrophones_cb _hidl_cb) override; |
||||
Return<Result> setConnectedState(const DeviceAddress& address, bool connected) override; |
||||
#endif |
||||
#if MAJOR_VERSION >= 6 |
||||
Return<Result> close() override; |
||||
Return<Result> addDeviceEffect(AudioPortHandle device, uint64_t effectId) override; |
||||
Return<Result> removeDeviceEffect(AudioPortHandle device, uint64_t effectId) override; |
||||
Return<void> updateAudioPatch(int32_t previousPatch, const hidl_vec<AudioPortConfig>& sources, |
||||
const hidl_vec<AudioPortConfig>& sinks, |
||||
updateAudioPatch_cb _hidl_cb) override; |
||||
#endif |
||||
|
||||
Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override; |
||||
|
||||
// Methods from ::android::hardware::audio::CPP_VERSION::IPrimaryDevice follow.
|
||||
Return<Result> setVoiceVolume(float volume) override; |
||||
Return<Result> setMode(AudioMode mode) override; |
||||
Return<void> getBtScoNrecEnabled(getBtScoNrecEnabled_cb _hidl_cb) override; |
||||
Return<Result> setBtScoNrecEnabled(bool enabled) override; |
||||
Return<void> getBtScoWidebandEnabled(getBtScoWidebandEnabled_cb _hidl_cb) override; |
||||
Return<Result> setBtScoWidebandEnabled(bool enabled) override; |
||||
Return<void> getTtyMode(getTtyMode_cb _hidl_cb) override; |
||||
Return<Result> setTtyMode(IPrimaryDevice::TtyMode mode) override; |
||||
Return<void> getHacEnabled(getHacEnabled_cb _hidl_cb) override; |
||||
Return<Result> setHacEnabled(bool enabled) override; |
||||
|
||||
#if MAJOR_VERSION >= 4 |
||||
Return<Result> setBtScoHeadsetDebugName(const hidl_string& name) override; |
||||
Return<void> getBtHfpEnabled(getBtHfpEnabled_cb _hidl_cb) override; |
||||
Return<Result> setBtHfpEnabled(bool enabled) override; |
||||
Return<Result> setBtHfpSampleRate(uint32_t sampleRateHz) override; |
||||
Return<Result> setBtHfpVolume(float volume) override; |
||||
Return<Result> updateRotation(IPrimaryDevice::Rotation rotation) override; |
||||
#endif |
||||
#if MAJOR_VERSION == 7 && MINOR_VERSION == 1 |
||||
Return<sp<::android::hardware::audio::V7_1::IDevice>> getDevice() override { return mDevice; } |
||||
#endif |
||||
private: |
||||
sp<Device> mDevice; |
||||
|
||||
virtual ~PrimaryDevice(); |
||||
}; |
||||
|
||||
} // namespace implementation
|
||||
} // namespace CPP_VERSION
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_HARDWARE_AUDIO_PRIMARYDEVICE_H
|
@ -0,0 +1,236 @@ |
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#ifndef ANDROID_HARDWARE_AUDIO_STREAM_H |
||||
#define ANDROID_HARDWARE_AUDIO_STREAM_H |
||||
|
||||
// clang-format off
|
||||
#include PATH(android/hardware/audio/COMMON_TYPES_FILE_VERSION/IStream.h) |
||||
// clang-format on
|
||||
|
||||
#include "ParametersUtil.h" |
||||
|
||||
#include <vector> |
||||
|
||||
#include <hardware/audio.h> |
||||
#include <hidl/Status.h> |
||||
|
||||
#include <hidl/MQDescriptor.h> |
||||
|
||||
#include <VersionUtils.h> |
||||
|
||||
namespace android { |
||||
namespace hardware { |
||||
namespace audio { |
||||
namespace CPP_VERSION { |
||||
namespace implementation { |
||||
|
||||
using ::android::sp; |
||||
using ::android::hardware::hidl_string; |
||||
using ::android::hardware::hidl_vec; |
||||
using ::android::hardware::Return; |
||||
using ::android::hardware::Void; |
||||
using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::ParametersUtil; |
||||
#if MAJOR_VERSION <= 6 |
||||
using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation:: |
||||
AudioChannelBitfield; |
||||
#endif |
||||
using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION; |
||||
using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION; |
||||
using namespace ::android::hardware::audio::CPP_VERSION; |
||||
|
||||
struct Stream : public IStream, public ParametersUtil { |
||||
Stream(bool isInput, audio_stream_t* stream); |
||||
|
||||
/** 1GiB is the maximum buffer size the HAL client is allowed to request.
|
||||
* This value has been chosen to be under SIZE_MAX and still big enough |
||||
* for all audio use case. |
||||
* Keep private for 2.0, put in .hal in 2.1 |
||||
*/ |
||||
static constexpr uint32_t MAX_BUFFER_SIZE = 2 << 30 /* == 1GiB */; |
||||
|
||||
// Methods from ::android::hardware::audio::CPP_VERSION::IStream follow.
|
||||
Return<uint64_t> getFrameSize() override; |
||||
Return<uint64_t> getFrameCount() override; |
||||
Return<uint64_t> getBufferSize() override; |
||||
#if MAJOR_VERSION <= 6 |
||||
Return<uint32_t> getSampleRate() override; |
||||
#if MAJOR_VERSION == 2 |
||||
Return<void> getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) override; |
||||
Return<void> getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) override; |
||||
#endif |
||||
Return<void> getSupportedSampleRates(AudioFormat format, getSupportedSampleRates_cb _hidl_cb); |
||||
Return<void> getSupportedChannelMasks(AudioFormat format, getSupportedChannelMasks_cb _hidl_cb); |
||||
Return<Result> setSampleRate(uint32_t sampleRateHz) override; |
||||
Return<AudioChannelBitfield> getChannelMask() override; |
||||
Return<Result> setChannelMask(AudioChannelBitfield mask) override; |
||||
Return<AudioFormat> getFormat() override; |
||||
Return<void> getSupportedFormats(getSupportedFormats_cb _hidl_cb) override; |
||||
Return<Result> setFormat(AudioFormat format) override; |
||||
#else |
||||
Return<void> getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) override; |
||||
Return<Result> setAudioProperties(const AudioConfigBaseOptional& config) override; |
||||
#endif // MAJOR_VERSION <= 6
|
||||
Return<void> getAudioProperties(getAudioProperties_cb _hidl_cb) override; |
||||
Return<Result> addEffect(uint64_t effectId) override; |
||||
Return<Result> removeEffect(uint64_t effectId) override; |
||||
Return<Result> standby() override; |
||||
#if MAJOR_VERSION == 2 |
||||
Return<AudioDevice> getDevice() override; |
||||
Return<Result> setDevice(const DeviceAddress& address) override; |
||||
Return<void> getParameters(const hidl_vec<hidl_string>& keys, |
||||
getParameters_cb _hidl_cb) override; |
||||
Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters) override; |
||||
Return<Result> setConnectedState(const DeviceAddress& address, bool connected) override; |
||||
#elif MAJOR_VERSION >= 4 |
||||
Return<void> getDevices(getDevices_cb _hidl_cb) override; |
||||
Return<Result> setDevices(const hidl_vec<DeviceAddress>& devices) override; |
||||
Return<void> getParameters(const hidl_vec<ParameterValue>& context, |
||||
const hidl_vec<hidl_string>& keys, |
||||
getParameters_cb _hidl_cb) override; |
||||
Return<Result> setParameters(const hidl_vec<ParameterValue>& context, |
||||
const hidl_vec<ParameterValue>& parameters) override; |
||||
#endif |
||||
Return<Result> setHwAvSync(uint32_t hwAvSync) override; |
||||
Return<Result> start() override; |
||||
Return<Result> stop() override; |
||||
Return<void> createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) override; |
||||
Return<void> getMmapPosition(getMmapPosition_cb _hidl_cb) override; |
||||
Return<Result> close() override; |
||||
|
||||
Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override; |
||||
#if MAJOR_VERSION == 2 |
||||
Return<void> debugDump(const hidl_handle& fd) override; |
||||
#endif |
||||
|
||||
// Utility methods for extending interfaces.
|
||||
static Result analyzeStatus(const char* funcName, int status); |
||||
static Result analyzeStatus(const char* funcName, int status, |
||||
const std::vector<int>& ignoreErrors); |
||||
|
||||
private: |
||||
const bool mIsInput; |
||||
audio_stream_t* mStream; |
||||
|
||||
virtual ~Stream(); |
||||
|
||||
// Methods from ParametersUtil.
|
||||
char* halGetParameters(const char* keys) override; |
||||
int halSetParameters(const char* keysAndValues) override; |
||||
}; |
||||
|
||||
template <typename T> |
||||
struct StreamMmap : public RefBase { |
||||
explicit StreamMmap(T* stream) : mStream(stream) {} |
||||
|
||||
Return<Result> start(); |
||||
Return<Result> stop(); |
||||
Return<void> createMmapBuffer(int32_t minSizeFrames, size_t frameSize, |
||||
IStream::createMmapBuffer_cb _hidl_cb); |
||||
Return<void> getMmapPosition(IStream::getMmapPosition_cb _hidl_cb); |
||||
|
||||
private: |
||||
StreamMmap() {} |
||||
|
||||
T* mStream; |
||||
}; |
||||
|
||||
template <typename T> |
||||
Return<Result> StreamMmap<T>::start() { |
||||
if (mStream->start == NULL) return Result::NOT_SUPPORTED; |
||||
int result = mStream->start(mStream); |
||||
return Stream::analyzeStatus("start", result); |
||||
} |
||||
|
||||
template <typename T> |
||||
Return<Result> StreamMmap<T>::stop() { |
||||
if (mStream->stop == NULL) return Result::NOT_SUPPORTED; |
||||
int result = mStream->stop(mStream); |
||||
return Stream::analyzeStatus("stop", result); |
||||
} |
||||
|
||||
template <typename T> |
||||
Return<void> StreamMmap<T>::createMmapBuffer(int32_t minSizeFrames, size_t frameSize, |
||||
IStream::createMmapBuffer_cb _hidl_cb) { |
||||
Result retval(Result::NOT_SUPPORTED); |
||||
MmapBufferInfo info; |
||||
native_handle_t* hidlHandle = nullptr; |
||||
|
||||
if (mStream->create_mmap_buffer != NULL) { |
||||
if (minSizeFrames <= 0) { |
||||
retval = Result::INVALID_ARGUMENTS; |
||||
goto exit; |
||||
} |
||||
struct audio_mmap_buffer_info halInfo; |
||||
retval = Stream::analyzeStatus( |
||||
"create_mmap_buffer", mStream->create_mmap_buffer(mStream, minSizeFrames, &halInfo)); |
||||
if (retval == Result::OK) { |
||||
hidlHandle = native_handle_create(1, 0); |
||||
hidlHandle->data[0] = halInfo.shared_memory_fd; |
||||
|
||||
// Negative buffer size frame is a legacy hack to indicate that the buffer
|
||||
// is shareable to applications before the relevant flag was introduced
|
||||
bool applicationShareable = |
||||
halInfo.flags & AUDIO_MMAP_APPLICATION_SHAREABLE || halInfo.buffer_size_frames < 0; |
||||
halInfo.buffer_size_frames = abs(halInfo.buffer_size_frames); |
||||
info.sharedMemory = // hidl_memory size must always be positive
|
||||
hidl_memory("audio_buffer", hidlHandle, frameSize * halInfo.buffer_size_frames); |
||||
#if MAJOR_VERSION == 2 |
||||
if (applicationShareable) { |
||||
halInfo.buffer_size_frames *= -1; |
||||
} |
||||
#else |
||||
info.flags = |
||||
halInfo.flags | (applicationShareable ? MmapBufferFlag::APPLICATION_SHAREABLE |
||||
: MmapBufferFlag::NONE); |
||||
#endif |
||||
info.bufferSizeFrames = halInfo.buffer_size_frames; |
||||
info.burstSizeFrames = halInfo.burst_size_frames; |
||||
} |
||||
} |
||||
exit: |
||||
_hidl_cb(retval, info); |
||||
if (hidlHandle != nullptr) { |
||||
native_handle_delete(hidlHandle); |
||||
} |
||||
return Void(); |
||||
} |
||||
|
||||
template <typename T> |
||||
Return<void> StreamMmap<T>::getMmapPosition(IStream::getMmapPosition_cb _hidl_cb) { |
||||
Result retval(Result::NOT_SUPPORTED); |
||||
MmapPosition position; |
||||
|
||||
if (mStream->get_mmap_position != NULL) { |
||||
struct audio_mmap_position halPosition; |
||||
retval = Stream::analyzeStatus("get_mmap_position", |
||||
mStream->get_mmap_position(mStream, &halPosition)); |
||||
if (retval == Result::OK) { |
||||
position.timeNanoseconds = halPosition.time_nanoseconds; |
||||
position.positionFrames = halPosition.position_frames; |
||||
} |
||||
} |
||||
_hidl_cb(retval, position); |
||||
return Void(); |
||||
} |
||||
|
||||
} // namespace implementation
|
||||
} // namespace CPP_VERSION
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_HARDWARE_AUDIO_STREAM_H
|
@ -0,0 +1,162 @@ |
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#ifndef ANDROID_HARDWARE_AUDIO_STREAMIN_H |
||||
#define ANDROID_HARDWARE_AUDIO_STREAMIN_H |
||||
|
||||
// clang-format off
|
||||
#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/IStreamIn.h) |
||||
// clang-format on
|
||||
|
||||
#include "Device.h" |
||||
#include "Stream.h" |
||||
|
||||
#include <atomic> |
||||
#include <memory> |
||||
|
||||
#include <fmq/EventFlag.h> |
||||
#include <fmq/MessageQueue.h> |
||||
#include <hidl/MQDescriptor.h> |
||||
#include <hidl/Status.h> |
||||
#include <utils/Thread.h> |
||||
|
||||
namespace android { |
||||
namespace hardware { |
||||
namespace audio { |
||||
namespace CPP_VERSION { |
||||
namespace implementation { |
||||
|
||||
using ::android::sp; |
||||
using ::android::hardware::hidl_string; |
||||
using ::android::hardware::hidl_vec; |
||||
using ::android::hardware::Return; |
||||
using ::android::hardware::Void; |
||||
using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION; |
||||
using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION; |
||||
using namespace ::android::hardware::audio::CPP_VERSION; |
||||
|
||||
struct StreamIn : public IStreamIn { |
||||
typedef MessageQueue<ReadParameters, kSynchronizedReadWrite> CommandMQ; |
||||
typedef MessageQueue<uint8_t, kSynchronizedReadWrite> DataMQ; |
||||
typedef MessageQueue<ReadStatus, kSynchronizedReadWrite> StatusMQ; |
||||
|
||||
StreamIn(const sp<Device>& device, audio_stream_in_t* stream); |
||||
|
||||
// Methods from ::android::hardware::audio::CPP_VERSION::IStream follow.
|
||||
Return<uint64_t> getFrameSize() override; |
||||
Return<uint64_t> getFrameCount() override; |
||||
Return<uint64_t> getBufferSize() override; |
||||
#if MAJOR_VERSION <= 6 |
||||
Return<uint32_t> getSampleRate() override; |
||||
#if MAJOR_VERSION == 2 |
||||
Return<void> getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) override; |
||||
Return<void> getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) override; |
||||
#endif |
||||
Return<void> getSupportedSampleRates(AudioFormat format, getSupportedSampleRates_cb _hidl_cb); |
||||
Return<void> getSupportedChannelMasks(AudioFormat format, getSupportedChannelMasks_cb _hidl_cb); |
||||
Return<Result> setSampleRate(uint32_t sampleRateHz) override; |
||||
Return<AudioChannelBitfield> getChannelMask() override; |
||||
Return<Result> setChannelMask(AudioChannelBitfield mask) override; |
||||
Return<AudioFormat> getFormat() override; |
||||
Return<void> getSupportedFormats(getSupportedFormats_cb _hidl_cb) override; |
||||
Return<Result> setFormat(AudioFormat format) override; |
||||
#else |
||||
Return<void> getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) override; |
||||
Return<Result> setAudioProperties(const AudioConfigBaseOptional& config) override; |
||||
#endif // MAJOR_VERSION <= 6
|
||||
Return<void> getAudioProperties(getAudioProperties_cb _hidl_cb) override; |
||||
Return<Result> addEffect(uint64_t effectId) override; |
||||
Return<Result> removeEffect(uint64_t effectId) override; |
||||
Return<Result> standby() override; |
||||
#if MAJOR_VERSION == 2 |
||||
Return<AudioDevice> getDevice() override; |
||||
Return<Result> setDevice(const DeviceAddress& address) override; |
||||
Return<void> getParameters(const hidl_vec<hidl_string>& keys, |
||||
getParameters_cb _hidl_cb) override; |
||||
Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters) override; |
||||
Return<Result> setConnectedState(const DeviceAddress& address, bool connected) override; |
||||
#elif MAJOR_VERSION >= 4 |
||||
Return<void> getDevices(getDevices_cb _hidl_cb) override; |
||||
Return<Result> setDevices(const hidl_vec<DeviceAddress>& devices) override; |
||||
Return<void> getParameters(const hidl_vec<ParameterValue>& context, |
||||
const hidl_vec<hidl_string>& keys, |
||||
getParameters_cb _hidl_cb) override; |
||||
Return<Result> setParameters(const hidl_vec<ParameterValue>& context, |
||||
const hidl_vec<ParameterValue>& parameters) override; |
||||
#endif |
||||
Return<Result> setHwAvSync(uint32_t hwAvSync) override; |
||||
Return<Result> close() override; |
||||
|
||||
Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override; |
||||
#if MAJOR_VERSION == 2 |
||||
Return<void> debugDump(const hidl_handle& fd) override; |
||||
#endif |
||||
|
||||
// Methods from ::android::hardware::audio::CPP_VERSION::IStreamIn follow.
|
||||
Return<void> getAudioSource(getAudioSource_cb _hidl_cb) override; |
||||
Return<Result> setGain(float gain) override; |
||||
Return<void> prepareForReading(uint32_t frameSize, uint32_t framesCount, |
||||
prepareForReading_cb _hidl_cb) override; |
||||
Return<uint32_t> getInputFramesLost() override; |
||||
Return<void> getCapturePosition(getCapturePosition_cb _hidl_cb) override; |
||||
Return<Result> start() override; |
||||
Return<Result> stop() override; |
||||
Return<void> createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) override; |
||||
Return<void> getMmapPosition(getMmapPosition_cb _hidl_cb) override; |
||||
#if MAJOR_VERSION >= 4 |
||||
#if MAJOR_VERSION <= 6 |
||||
Return<void> updateSinkMetadata(const SinkMetadata& sinkMetadata) override; |
||||
#else |
||||
Return<Result> updateSinkMetadata(const SinkMetadata& sinkMetadata) override; |
||||
#endif |
||||
Return<void> getActiveMicrophones(getActiveMicrophones_cb _hidl_cb) override; |
||||
#endif // MAJOR_VERSION >= 4
|
||||
#if MAJOR_VERSION >= 5 |
||||
Return<Result> setMicrophoneDirection(MicrophoneDirection direction) override; |
||||
Return<Result> setMicrophoneFieldDimension(float zoom) override; |
||||
#endif |
||||
static Result getCapturePositionImpl(audio_stream_in_t* stream, uint64_t* frames, |
||||
uint64_t* time); |
||||
|
||||
private: |
||||
#if MAJOR_VERSION >= 4 |
||||
Result doUpdateSinkMetadata(const SinkMetadata& sinkMetadata); |
||||
#if MAJOR_VERSION >= 7 |
||||
Result doUpdateSinkMetadataV7(const SinkMetadata& sinkMetadata); |
||||
#endif |
||||
#endif // MAJOR_VERSION >= 4
|
||||
|
||||
const sp<Device> mDevice; |
||||
audio_stream_in_t* mStream; |
||||
const sp<Stream> mStreamCommon; |
||||
const sp<StreamMmap<audio_stream_in_t>> mStreamMmap; |
||||
std::unique_ptr<CommandMQ> mCommandMQ; |
||||
std::unique_ptr<DataMQ> mDataMQ; |
||||
std::unique_ptr<StatusMQ> mStatusMQ; |
||||
EventFlag* mEfGroup; |
||||
std::atomic<bool> mStopReadThread; |
||||
sp<Thread> mReadThread; |
||||
|
||||
virtual ~StreamIn(); |
||||
}; |
||||
|
||||
} // namespace implementation
|
||||
} // namespace CPP_VERSION
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_HARDWARE_AUDIO_STREAMIN_H
|
@ -0,0 +1,201 @@ |
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#ifndef ANDROID_HARDWARE_AUDIO_STREAMOUT_H |
||||
#define ANDROID_HARDWARE_AUDIO_STREAMOUT_H |
||||
|
||||
#include PATH(android/hardware/audio/FILE_VERSION/IStreamOut.h) |
||||
|
||||
#include "Device.h" |
||||
#include "Stream.h" |
||||
|
||||
#include <atomic> |
||||
#include <memory> |
||||
|
||||
#include <fmq/EventFlag.h> |
||||
#include <fmq/MessageQueue.h> |
||||
#include <hidl/MQDescriptor.h> |
||||
#include <hidl/Status.h> |
||||
#include <mediautils/Synchronization.h> |
||||
#include <utils/Thread.h> |
||||
|
||||
namespace android { |
||||
namespace hardware { |
||||
namespace audio { |
||||
namespace CPP_VERSION { |
||||
namespace implementation { |
||||
|
||||
using ::android::sp; |
||||
using ::android::hardware::hidl_string; |
||||
using ::android::hardware::hidl_vec; |
||||
using ::android::hardware::Return; |
||||
using ::android::hardware::Void; |
||||
using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION; |
||||
using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION; |
||||
using namespace ::android::hardware::audio::CPP_VERSION; |
||||
|
||||
struct StreamOut : public IStreamOut { |
||||
typedef MessageQueue<WriteCommand, kSynchronizedReadWrite> CommandMQ; |
||||
typedef MessageQueue<uint8_t, kSynchronizedReadWrite> DataMQ; |
||||
typedef MessageQueue<WriteStatus, kSynchronizedReadWrite> StatusMQ; |
||||
|
||||
StreamOut(const sp<Device>& device, audio_stream_out_t* stream); |
||||
|
||||
// Methods from ::android::hardware::audio::CPP_VERSION::IStream follow.
|
||||
Return<uint64_t> getFrameSize() override; |
||||
Return<uint64_t> getFrameCount() override; |
||||
Return<uint64_t> getBufferSize() override; |
||||
#if MAJOR_VERSION <= 6 |
||||
Return<uint32_t> getSampleRate() override; |
||||
#if MAJOR_VERSION == 2 |
||||
Return<void> getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) override; |
||||
Return<void> getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) override; |
||||
#endif |
||||
Return<void> getSupportedSampleRates(AudioFormat format, getSupportedSampleRates_cb _hidl_cb); |
||||
Return<void> getSupportedChannelMasks(AudioFormat format, getSupportedChannelMasks_cb _hidl_cb); |
||||
Return<Result> setSampleRate(uint32_t sampleRateHz) override; |
||||
Return<AudioChannelBitfield> getChannelMask() override; |
||||
Return<Result> setChannelMask(AudioChannelBitfield mask) override; |
||||
Return<AudioFormat> getFormat() override; |
||||
Return<void> getSupportedFormats(getSupportedFormats_cb _hidl_cb) override; |
||||
Return<Result> setFormat(AudioFormat format) override; |
||||
#else |
||||
Return<void> getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) override; |
||||
Return<Result> setAudioProperties(const AudioConfigBaseOptional& config) override; |
||||
#endif // MAJOR_VERSION <= 6
|
||||
Return<void> getAudioProperties(getAudioProperties_cb _hidl_cb) override; |
||||
Return<Result> addEffect(uint64_t effectId) override; |
||||
Return<Result> removeEffect(uint64_t effectId) override; |
||||
Return<Result> standby() override; |
||||
#if MAJOR_VERSION == 2 |
||||
Return<AudioDevice> getDevice() override; |
||||
Return<Result> setDevice(const DeviceAddress& address) override; |
||||
Return<void> getParameters(const hidl_vec<hidl_string>& keys, |
||||
getParameters_cb _hidl_cb) override; |
||||
Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters) override; |
||||
Return<Result> setConnectedState(const DeviceAddress& address, bool connected) override; |
||||
#elif MAJOR_VERSION >= 4 |
||||
Return<void> getDevices(getDevices_cb _hidl_cb) override; |
||||
Return<Result> setDevices(const hidl_vec<DeviceAddress>& devices) override; |
||||
Return<void> getParameters(const hidl_vec<ParameterValue>& context, |
||||
const hidl_vec<hidl_string>& keys, |
||||
getParameters_cb _hidl_cb) override; |
||||
Return<Result> setParameters(const hidl_vec<ParameterValue>& context, |
||||
const hidl_vec<ParameterValue>& parameters) override; |
||||
#endif |
||||
Return<Result> setHwAvSync(uint32_t hwAvSync) override; |
||||
Return<Result> close() override; |
||||
|
||||
Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override; |
||||
#if MAJOR_VERSION == 2 |
||||
Return<void> debugDump(const hidl_handle& fd) override; |
||||
#endif |
||||
|
||||
// Methods from ::android::hardware::audio::CPP_VERSION::IStreamOut follow.
|
||||
Return<uint32_t> getLatency() override; |
||||
Return<Result> setVolume(float left, float right) override; |
||||
Return<void> prepareForWriting(uint32_t frameSize, uint32_t framesCount, |
||||
prepareForWriting_cb _hidl_cb) override; |
||||
Return<void> getRenderPosition(getRenderPosition_cb _hidl_cb) override; |
||||
Return<void> getNextWriteTimestamp(getNextWriteTimestamp_cb _hidl_cb) override; |
||||
Return<Result> setCallback(const sp<IStreamOutCallback>& callback) override; |
||||
Return<Result> clearCallback() override; |
||||
Return<void> supportsPauseAndResume(supportsPauseAndResume_cb _hidl_cb) override; |
||||
Return<Result> pause() override; |
||||
Return<Result> resume() override; |
||||
Return<bool> supportsDrain() override; |
||||
Return<Result> drain(AudioDrain type) override; |
||||
Return<Result> flush() override; |
||||
Return<void> getPresentationPosition(getPresentationPosition_cb _hidl_cb) override; |
||||
Return<Result> start() override; |
||||
Return<Result> stop() override; |
||||
Return<void> createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) override; |
||||
Return<void> getMmapPosition(getMmapPosition_cb _hidl_cb) override; |
||||
#if MAJOR_VERSION >= 4 |
||||
Return<Result> selectPresentation(int32_t presentationId, int32_t programId) override; |
||||
#if MAJOR_VERSION <= 6 |
||||
Return<void> updateSourceMetadata(const SourceMetadata& sourceMetadata) override; |
||||
#else |
||||
Return<Result> updateSourceMetadata(const SourceMetadata& sourceMetadata) override; |
||||
#endif |
||||
#endif // MAJOR_VERSION >= 4
|
||||
#if MAJOR_VERSION >= 6 |
||||
Return<void> getDualMonoMode(getDualMonoMode_cb _hidl_cb) override; |
||||
Return<Result> setDualMonoMode(DualMonoMode mode) override; |
||||
Return<void> getAudioDescriptionMixLevel(getAudioDescriptionMixLevel_cb _hidl_cb) override; |
||||
Return<Result> setAudioDescriptionMixLevel(float leveldB) override; |
||||
Return<void> getPlaybackRateParameters(getPlaybackRateParameters_cb _hidl_cb) override; |
||||
Return<Result> setPlaybackRateParameters(const PlaybackRate& playbackRate) override; |
||||
#endif |
||||
|
||||
static Result getPresentationPositionImpl(audio_stream_out_t* stream, uint64_t* frames, |
||||
TimeSpec* timeStamp); |
||||
|
||||
#if MAJOR_VERSION >= 6 |
||||
Return<Result> setEventCallback(const sp<IStreamOutEventCallback>& callback) override; |
||||
#endif |
||||
|
||||
private: |
||||
#if MAJOR_VERSION >= 4 |
||||
Result doUpdateSourceMetadata(const SourceMetadata& sourceMetadata); |
||||
#if MAJOR_VERSION >= 7 |
||||
Result doUpdateSourceMetadataV7(const SourceMetadata& sourceMetadata); |
||||
#if MAJOR_VERSION == 7 && MINOR_VERSION == 1 |
||||
Return<Result> setLatencyMode(LatencyMode mode) override; |
||||
Return<void> getRecommendedLatencyModes(getRecommendedLatencyModes_cb _hidl_cb) override; |
||||
Return<Result> setLatencyModeCallback( |
||||
const sp<IStreamOutLatencyModeCallback>& callback) override; |
||||
#endif |
||||
#endif |
||||
#endif // MAJOR_VERSION >= 4
|
||||
|
||||
const sp<Device> mDevice; |
||||
audio_stream_out_t* mStream; |
||||
const sp<Stream> mStreamCommon; |
||||
const sp<StreamMmap<audio_stream_out_t>> mStreamMmap; |
||||
mediautils::atomic_sp<IStreamOutCallback> mCallback; // for non-blocking write and drain
|
||||
#if MAJOR_VERSION >= 6 |
||||
mediautils::atomic_sp<IStreamOutEventCallback> mEventCallback; |
||||
#if MAJOR_VERSION == 7 && MINOR_VERSION == 1 |
||||
mediautils::atomic_sp<IStreamOutLatencyModeCallback> mLatencyModeCallback; |
||||
#endif |
||||
#endif |
||||
std::unique_ptr<CommandMQ> mCommandMQ; |
||||
std::unique_ptr<DataMQ> mDataMQ; |
||||
std::unique_ptr<StatusMQ> mStatusMQ; |
||||
EventFlag* mEfGroup; |
||||
std::atomic<bool> mStopWriteThread; |
||||
sp<Thread> mWriteThread; |
||||
|
||||
virtual ~StreamOut(); |
||||
|
||||
static int asyncCallback(stream_callback_event_t event, void* param, void* cookie); |
||||
|
||||
#if MAJOR_VERSION >= 6 |
||||
static int asyncEventCallback(stream_event_callback_type_t event, void* param, void* cookie); |
||||
#if MAJOR_VERSION == 7 && MINOR_VERSION == 1 |
||||
static void latencyModeCallback(audio_latency_mode_t* modes, size_t num_modes, void* cookie); |
||||
#endif |
||||
#endif |
||||
}; |
||||
|
||||
} // namespace implementation
|
||||
} // namespace CPP_VERSION
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_HARDWARE_AUDIO_STREAMOUT_H
|
@ -0,0 +1,82 @@ |
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#ifndef ANDROID_HARDWARE_AUDIO_UTIL_H |
||||
#define ANDROID_HARDWARE_AUDIO_UTIL_H |
||||
|
||||
// clang-format off
|
||||
#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h) |
||||
// clang-format on
|
||||
|
||||
#include <algorithm> |
||||
#include <vector> |
||||
|
||||
#include <system/audio.h> |
||||
|
||||
namespace android { |
||||
namespace hardware { |
||||
namespace audio { |
||||
namespace CORE_TYPES_CPP_VERSION { |
||||
namespace implementation { |
||||
|
||||
using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION; |
||||
using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION; |
||||
|
||||
namespace util { |
||||
|
||||
/** @return true if gain is between 0 and 1 included. */ |
||||
constexpr bool isGainNormalized(float gain) { |
||||
return gain >= 0.0 && gain <= 1.0; |
||||
} |
||||
|
||||
template <typename T> |
||||
inline bool element_in(T e, const std::vector<T>& v) { |
||||
return std::find(v.begin(), v.end(), e) != v.end(); |
||||
} |
||||
|
||||
static inline Result analyzeStatus(status_t status) { |
||||
switch (status) { |
||||
case 0: |
||||
return Result::OK; |
||||
case -EINVAL: |
||||
return Result::INVALID_ARGUMENTS; |
||||
case -ENODATA: |
||||
return Result::INVALID_STATE; |
||||
case -ENODEV: |
||||
return Result::NOT_INITIALIZED; |
||||
case -ENOSYS: |
||||
return Result::NOT_SUPPORTED; |
||||
default: |
||||
return Result::INVALID_STATE; |
||||
} |
||||
} |
||||
|
||||
static inline Result analyzeStatus(const char* className, const char* funcName, status_t status, |
||||
const std::vector<int>& ignoreErrors = {}) { |
||||
if (status != 0 && !element_in(-status, ignoreErrors)) { |
||||
ALOGW("Error from HAL %s in function %s: %s", className, funcName, strerror(-status)); |
||||
} |
||||
return analyzeStatus(status); |
||||
} |
||||
|
||||
} // namespace util
|
||||
} // namespace implementation
|
||||
} // namespace CORE_TYPES_CPP_VERSION
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_HARDWARE_AUDIO_UTIL_H
|
@ -0,0 +1 @@ |
||||
require version-bootloader-min=C |
@ -1,32 +0,0 @@ |
||||
<?xml version="1.0" encoding="ISO-8859-1"?> |
||||
<!-- |
||||
Copyright (c) 2019, The Linux Foundation. All rights reserved. |
||||
|
||||
Redistribution and use in source and binary forms, with or without |
||||
modification, are permitted provided that the following conditions are |
||||
met: |
||||
* Redistributions of source code must retain the above copyright |
||||
notice, this list of conditions and the following disclaimer. |
||||
* Redistributions in binary form must reproduce the above |
||||
copyright notice, this list of conditions and the following |
||||
disclaimer in the documentation and/or other materials provided |
||||
with the distribution. |
||||
* Neither the name of The Linux Foundation nor the names of its |
||||
contributors may be used to endorse or promote products derived |
||||
from this software without specific prior written permission. |
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED |
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT |
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS |
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
--> |
||||
<configs> |
||||
<!-- AHAL Configs --> |
||||
</configs> |
@ -1,367 +0,0 @@ |
||||
# List of effect libraries to load. Each library element must contain a "path" element |
||||
# giving the full path of the library .so file. |
||||
# libraries { |
||||
# <lib name> { |
||||
# path <lib path> |
||||
# } |
||||
# } |
||||
libraries { |
||||
bundle { |
||||
path /vendor/lib/soundfx/libbundlewrapper.so |
||||
} |
||||
reverb { |
||||
path /vendor/lib/soundfx/libreverbwrapper.so |
||||
} |
||||
qcbassboost { |
||||
path /vendor/lib/soundfx/libqcbassboost.so |
||||
} |
||||
qcvirt { |
||||
path /vendor/lib/soundfx/libqcvirt.so |
||||
} |
||||
qcreverb { |
||||
path /vendor/lib/soundfx/libqcreverb.so |
||||
} |
||||
visualizer_sw { |
||||
path /vendor/lib/soundfx/libvisualizer.so |
||||
} |
||||
visualizer_hw { |
||||
path /vendor/lib/soundfx/libqcomvisualizer.so |
||||
} |
||||
downmix { |
||||
path /vendor/lib/soundfx/libdownmix.so |
||||
} |
||||
loudness_enhancer { |
||||
path /vendor/lib/soundfx/libldnhncr.so |
||||
} |
||||
dynamics_processing { |
||||
path /vendor/lib/soundfx/libdynproc.so |
||||
} |
||||
proxy { |
||||
path /vendor/lib/soundfx/libeffectproxy.so |
||||
} |
||||
offload_bundle { |
||||
path /vendor/lib/soundfx/libqcompostprocbundle.so |
||||
} |
||||
audio_pre_processing { |
||||
path /vendor/lib/soundfx/libqcomvoiceprocessing.so |
||||
} |
||||
volume_listener { |
||||
path /vendor/lib/soundfx/libvolumelistener.so |
||||
} |
||||
audiosphere { |
||||
path /vendor/lib/soundfx/libasphere.so |
||||
} |
||||
shoebox { |
||||
path /vendor/lib/soundfx/libshoebox.so |
||||
} |
||||
} |
||||
|
||||
# Default pre-processing library. Add to audio_effect.conf "libraries" section if |
||||
# audio HAL implements support for default software audio pre-processing effects |
||||
# |
||||
# pre_processing { |
||||
# path /vendor/lib/soundfx/libaudiopreprocessing.so |
||||
# } |
||||
|
||||
# list of effects to load. Each effect element must contain a "library" and a "uuid" element. |
||||
# The value of the "library" element must correspond to the name of one library element in the |
||||
# "libraries" element. |
||||
# The name of the effect element is indicative, only the value of the "uuid" element |
||||
# designates the effect. |
||||
# The uuid is the implementation specific UUID as specified by the effect vendor. This is not the |
||||
# generic effect type UUID. |
||||
# effects { |
||||
# <fx name> { |
||||
# library <lib name> |
||||
# uuid <effect uuid> |
||||
# } |
||||
# ... |
||||
# } |
||||
|
||||
effects { |
||||
|
||||
# additions for the proxy implementation |
||||
# Proxy implementation |
||||
#effectname { |
||||
#library proxy |
||||
#uuid xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx |
||||
|
||||
# SW implemetation of the effect. Added as a node under the proxy to |
||||
# indicate this as a sub effect. |
||||
#libsw { |
||||
#library libSW |
||||
#uuid yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy |
||||
#} End of SW effect |
||||
|
||||
# HW implementation of the effect. Added as a node under the proxy to |
||||
# indicate this as a sub effect. |
||||
#libhw { |
||||
#library libHW |
||||
#uuid zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz |
||||
#}End of HW effect |
||||
#} End of effect proxy |
||||
|
||||
bassboost { |
||||
library proxy |
||||
uuid 14804144-a5ee-4d24-aa88-0002a5d5c51b |
||||
|
||||
libsw { |
||||
library qcbassboost |
||||
uuid 23aca180-44bd-11e2-bcfd-0800200c9a66 |
||||
} |
||||
|
||||
libhw { |
||||
library offload_bundle |
||||
uuid 2c4a8c24-1581-487f-94f6-0002a5d5c51b |
||||
} |
||||
} |
||||
virtualizer { |
||||
library proxy |
||||
uuid d3467faa-acc7-4d34-acaf-0002a5d5c51b |
||||
|
||||
libsw { |
||||
library qcvirt |
||||
uuid e6c98a16-22a3-11e2-b87b-f23c91aec05e |
||||
} |
||||
|
||||
libhw { |
||||
library offload_bundle |
||||
uuid 509a4498-561a-4bea-b3b1-0002a5d5c51b |
||||
} |
||||
} |
||||
equalizer { |
||||
library proxy |
||||
uuid c8e70ecd-48ca-456e-8a4f-0002a5d5c51b |
||||
|
||||
libsw { |
||||
library bundle |
||||
uuid ce772f20-847d-11df-bb17-0002a5d5c51b |
||||
} |
||||
|
||||
libhw { |
||||
library offload_bundle |
||||
uuid a0dac280-401c-11e3-9379-0002a5d5c51b |
||||
} |
||||
} |
||||
volume { |
||||
library bundle |
||||
uuid 119341a0-8469-11df-81f9-0002a5d5c51b |
||||
} |
||||
reverb_env_aux { |
||||
library proxy |
||||
uuid 48404ac9-d202-4ccc-bf84-0002a5d5c51b |
||||
|
||||
libsw { |
||||
library qcreverb |
||||
uuid a8c1e5f3-293d-43cd-95ec-d5e26c02e217 |
||||
} |
||||
|
||||
libhw { |
||||
library offload_bundle |
||||
uuid 79a18026-18fd-4185-8233-0002a5d5c51b |
||||
} |
||||
} |
||||
reverb_env_ins { |
||||
library proxy |
||||
uuid b707403a-a1c1-4291-9573-0002a5d5c51b |
||||
|
||||
libsw { |
||||
library qcreverb |
||||
uuid 791fff8b-8129-4655-83a4-59bc61034c3a |
||||
} |
||||
|
||||
libhw { |
||||
library offload_bundle |
||||
uuid eb64ea04-973b-43d2-8f5e-0002a5d5c51b |
||||
} |
||||
} |
||||
reverb_pre_aux { |
||||
library proxy |
||||
uuid 1b78f587-6d1c-422e-8b84-0002a5d5c51b |
||||
|
||||
libsw { |
||||
library qcreverb |
||||
uuid 53ef1db5-c0c0-445b-b060-e34d20ebb70a |
||||
} |
||||
|
||||
libhw { |
||||
library offload_bundle |
||||
uuid 6987be09-b142-4b41-9056-0002a5d5c51b |
||||
} |
||||
} |
||||
reverb_pre_ins { |
||||
library proxy |
||||
uuid f3e178d2-ebcb-408e-8357-0002a5d5c51b |
||||
|
||||
libsw { |
||||
library qcreverb |
||||
uuid b08a0e38-22a5-11e2-b87b-f23c91aec05e |
||||
} |
||||
|
||||
libhw { |
||||
library offload_bundle |
||||
uuid aa2bebf6-47cf-4613-9bca-0002a5d5c51b |
||||
} |
||||
} |
||||
visualizer { |
||||
library proxy |
||||
uuid 1d0a1a53-7d5d-48f2-8e71-27fbd10d842c |
||||
|
||||
libsw { |
||||
library visualizer_sw |
||||
uuid d069d9e0-8329-11df-9168-0002a5d5c51b |
||||
} |
||||
|
||||
libhw { |
||||
library visualizer_hw |
||||
uuid 7a8044a0-1a71-11e3-a184-0002a5d5c51b |
||||
} |
||||
} |
||||
downmix { |
||||
library downmix |
||||
uuid 93f04452-e4fe-41cc-91f9-e475b6d1d69f |
||||
} |
||||
hw_acc { |
||||
library offload_bundle |
||||
uuid 7d1580bd-297f-4683-9239-e475b6d1d69f |
||||
} |
||||
loudness_enhancer { |
||||
library loudness_enhancer |
||||
uuid fa415329-2034-4bea-b5dc-5b381c8d1e2c |
||||
} |
||||
dynamics_processing { |
||||
library dynamics_processing |
||||
uuid e0e6539b-1781-7261-676f-6d7573696340 |
||||
} |
||||
aec { |
||||
library audio_pre_processing |
||||
uuid 0f8d0d2a-59e5-45fe-b6e4-248c8a799109 |
||||
} |
||||
ns { |
||||
library audio_pre_processing |
||||
uuid 1d97bb0b-9e2f-4403-9ae3-58c2554306f8 |
||||
} |
||||
music_helper { |
||||
library volume_listener |
||||
uuid 08b8b058-0590-11e5-ac71-0025b32654a0 |
||||
} |
||||
ring_helper { |
||||
library volume_listener |
||||
uuid 0956df94-0590-11e5-bdbe-0025b32654a0 |
||||
} |
||||
alarm_helper { |
||||
library volume_listener |
||||
uuid 09f303e2-0590-11e5-8fdb-0025b32654a0 |
||||
} |
||||
# voice_helper is called when stream type is voice_call in VoIP usecase |
||||
voice_helper { |
||||
library volume_listener |
||||
uuid 0ace5c08-0590-11e5-ae9e-0025b32654a0 |
||||
} |
||||
notification_helper { |
||||
library volume_listener |
||||
uuid 0b776dde-0590-11e5-81ba-0025b32654a0 |
||||
} |
||||
audiosphere { |
||||
library audiosphere |
||||
uuid 184e62ab-2d19-4364-9d1b-c0a40733866c |
||||
} |
||||
shoebox { |
||||
library shoebox |
||||
uuid 1eab784c-1a36-4b2a-b7fc-e34c44cab89e |
||||
} |
||||
} |
||||
|
||||
# additional effect from vendor |
||||
# UUID generated using version 1 |
||||
|
||||
output_session_processing { |
||||
music { |
||||
music_helper { |
||||
} |
||||
} |
||||
ring { |
||||
ring_helper { |
||||
} |
||||
} |
||||
alarm { |
||||
alarm_helper { |
||||
} |
||||
} |
||||
# stream type voice_call is used for VoIP call |
||||
voice_call { |
||||
voice_helper { |
||||
} |
||||
} |
||||
notification { |
||||
notification_helper { |
||||
} |
||||
} |
||||
} |
||||
|
||||
# Added aec, ns effects for voice_communication, which are supported by the board |
||||
|
||||
pre_processing { |
||||
voice_communication { |
||||
aec { |
||||
} |
||||
ns { |
||||
} |
||||
} |
||||
} |
||||
|
||||
# Default pre-processing effects. Add to audio_effect.conf "effects" section if |
||||
# audio HAL implements support for them. |
||||
# |
||||
# agc { |
||||
# library pre_processing |
||||
# uuid aa8130e0-66fc-11e0-bad0-0002a5d5c51b |
||||
# } |
||||
# aec { |
||||
# library pre_processing |
||||
# uuid bb392ec0-8d4d-11e0-a896-0002a5d5c51b |
||||
# } |
||||
# ns { |
||||
# library pre_processing |
||||
# uuid c06c8400-8e06-11e0-9cb6-0002a5d5c51b |
||||
# } |
||||
|
||||
# Audio preprocessor configurations. |
||||
# The pre processor configuration consists in a list of elements each describing |
||||
# pre processor settings for a given input source. Valid input source names are: |
||||
# "mic", "camcorder", "voice_recognition", "voice_communication" |
||||
# Each input source element contains a list of effects elements. The name of the effect |
||||
# element must be the name of one of the effects in the "effects" list of the file. |
||||
# Each effect element may optionally contain a list of parameters and their |
||||
# default value to apply when the pre processor effect is created. |
||||
# A parameter is defined by a "param" element and a "value" element. Each of these elements |
||||
# consists in one or more elements specifying a type followed by a value. |
||||
# The types defined are: "int", "short", "float", "bool" and "string" |
||||
# When both "param" and "value" are a single int, a simple form is allowed where just |
||||
# the param and value pair is present in the parameter description |
||||
# pre_processing { |
||||
# <input source name> { |
||||
# <fx name> { |
||||
# <param 1 name> { |
||||
# param { |
||||
# int|short|float|bool|string <value> |
||||
# [ int|short|float|bool|string <value> ] |
||||
# ... |
||||
# } |
||||
# value { |
||||
# int|short|float|bool|string <value> |
||||
# [ int|short|float|bool|string <value> ] |
||||
# ... |
||||
# } |
||||
# } |
||||
# <param 2 name > {<param> <value>} |
||||
# ... |
||||
# } |
||||
# ... |
||||
# } |
||||
# ... |
||||
# } |
||||
|
||||
# |
||||
# TODO: add default audio pre processor configurations after debug and tuning phase |
||||
# |
@ -1,135 +0,0 @@ |
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> |
||||
|
||||
<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude"> |
||||
|
||||
<globalConfiguration speaker_drc_enabled="true"/> |
||||
|
||||
<modules> |
||||
<module name="primary" halVersion="3.0"> |
||||
<attachedDevices> |
||||
<item>Earpiece</item> |
||||
<item>Speaker</item> |
||||
<item>Built-In Mic</item> |
||||
<item>Built-In Back Mic</item> |
||||
<item>Voice Call Mic</item> |
||||
</attachedDevices> |
||||
|
||||
<defaultOutputDevice>Speaker</defaultOutputDevice> |
||||
|
||||
<mixPorts> |
||||
<mixPort name="primary-out" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY|AUDIO_OUTPUT_FLAG_DEEP_BUFFER"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> |
||||
</mixPort> |
||||
<mixPort name="fast" role="source" flags="AUDIO_OUTPUT_FLAG_FAST"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> |
||||
</mixPort> |
||||
<mixPort name="primary-in" role="sink"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000" |
||||
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/> |
||||
</mixPort> |
||||
</mixPorts> |
||||
<devicePorts> |
||||
<!-- Output devices declaration, i.e. Sink DEVICE PORT --> |
||||
<devicePort tagName="Earpiece" role="sink" type="AUDIO_DEVICE_OUT_EARPIECE"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/> |
||||
</devicePort> |
||||
<devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> |
||||
</devicePort> |
||||
<devicePort tagName="Wired Headset" role="sink" type="AUDIO_DEVICE_OUT_WIRED_HEADSET"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> |
||||
</devicePort> |
||||
<devicePort tagName="Wired Headphone" role="sink" type="AUDIO_DEVICE_OUT_WIRED_HEADPHONE"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> |
||||
</devicePort> |
||||
<devicePort tagName="Bt Sco All" role="sink" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> |
||||
</devicePort> |
||||
<devicePort tagName="Aux Device Out" role="sink" type="AUDIO_DEVICE_OUT_AUX_DIGITAL"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="44100,48000,64000,88200,96000,128000,176400,192000" |
||||
channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/> |
||||
</devicePort> |
||||
<!-- Input devices declaration, i.e. source DEVICE PORT --> |
||||
<devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000" |
||||
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/> |
||||
</devicePort> |
||||
<devicePort tagName="Built-In Back Mic" type="AUDIO_DEVICE_IN_BACK_MIC" role="source"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000" |
||||
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/> |
||||
</devicePort> |
||||
<devicePort tagName="Wired Headset Mic" type="AUDIO_DEVICE_IN_WIRED_HEADSET" role="source"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000" |
||||
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/> |
||||
</devicePort> |
||||
<devicePort tagName="Bt Sco Headset Mic" type="AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET" role="source"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000" |
||||
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/> |
||||
</devicePort> |
||||
<devicePort tagName="Aux Device In" type="AUDIO_DEVICE_IN_AUX_DIGITAL" role="source"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000" |
||||
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/> |
||||
</devicePort> |
||||
<devicePort tagName="Voice Call Mic" type="AUDIO_DEVICE_IN_VOICE_CALL" role="source"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000" |
||||
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/> |
||||
</devicePort> |
||||
<devicePort tagName="FM Mic" type="AUDIO_DEVICE_IN_FM_TUNER" role="source"> |
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" |
||||
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000" |
||||
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/> |
||||
</devicePort> |
||||
</devicePorts> |
||||
<!-- route declaration, i.e. list all available sources for a given sink --> |
||||
<routes> |
||||
<route type="mix" sink="Earpiece" |
||||
sources="primary-out,fast"/> |
||||
<route type="mix" sink="Speaker" |
||||
sources="primary-out,fast"/> |
||||
<route type="mix" sink="Wired Headset" |
||||
sources="primary-out,fast"/> |
||||
<route type="mix" sink="Wired Headphone" |
||||
sources="primary-out,fast"/> |
||||
<route type="mix" sink="Bt Sco All" |
||||
sources="primary-out,fast"/> |
||||
<route type="mix" sink="primary-in" |
||||
sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,Bt Sco Headset Mic,Aux Device In,Voice Call Mic,FM Mic"/> |
||||
</routes> |
||||
|
||||
</module> |
||||
|
||||
<!-- A2dp Input Audio HAL --> |
||||
<xi:include href="a2dp_in_audio_policy_configuration.xml"/> |
||||
|
||||
<!-- Remote Submix Audio HAL --> |
||||
<xi:include href="r_submix_audio_policy_configuration.xml"/> |
||||
|
||||
<!-- Bluetooth Audio HAL --> |
||||
<xi:include href="bluetooth_audio_policy_configuration.xml"/> |
||||
|
||||
</modules> |
||||
<!-- End of Modules section --> |
||||
|
||||
<!-- Volume section --> |
||||
|
||||
<xi:include href="audio_policy_volumes.xml"/> |
||||
<xi:include href="default_volume_tables.xml"/> |
||||
|
||||
<!-- End of Volume section --> |
||||
|
||||
</audioPolicyConfiguration> |
@ -1,190 +0,0 @@ |
||||
<?xml version="1.0" encoding="ISO-8859-1"?> |
||||
<!-- Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. --> |
||||
<!-- --> |
||||
<!-- Redistribution and use in source and binary forms, with or without --> |
||||
<!-- modification, are permitted provided that the following conditions are --> |
||||
<!-- met: --> |
||||
<!-- * Redistributions of source code must retain the above copyright --> |
||||
<!-- notice, this list of conditions and the following disclaimer. --> |
||||
<!-- * Redistributions in binary form must reproduce the above --> |
||||
<!-- copyright notice, this list of conditions and the following --> |
||||
<!-- disclaimer in the documentation and/or other materials provided --> |
||||
<!-- with the distribution. --> |
||||
<!-- * Neither the name of The Linux Foundation nor the names of its --> |
||||
<!-- contributors may be used to endorse or promote products derived --> |
||||
<!-- from this software without specific prior written permission. --> |
||||
<!-- --> |
||||
<!-- THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED --> |
||||
<!-- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF --> |
||||
<!-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT --> |
||||
<!-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS --> |
||||
<!-- BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --> |
||||
<!-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --> |
||||
<!-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR --> |
||||
<!-- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, --> |
||||
<!-- OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN --> |
||||
<!-- IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> |
||||
<mixer> |
||||
<!-- These are the initial mixer settings --> |
||||
<ctl name="Headset Playback Volume" value="108" /> |
||||
<ctl name="Headset Capture Volume" value="56" /> |
||||
|
||||
<!-- Play Scenario --> |
||||
<path name="usb-headphones-gain"> |
||||
<ctl name="Headset Playback Volume" value="106" /> |
||||
</path> |
||||
|
||||
<path name="speaker-and-usb-headphones-gain"> |
||||
<ctl name="Headset Playback Volume" value="61" /> |
||||
</path> |
||||
|
||||
<path name="dual-speaker-and-usb-headphones-gain"> |
||||
<ctl name="Headset Playback Volume" value="54" /> |
||||
</path> |
||||
|
||||
<path name="fm-usb-headphones-gain"> |
||||
<ctl name="Headset Playback Volume" value="107" /> |
||||
</path> |
||||
|
||||
<path name="remote-usb-headset-gain"> |
||||
<ctl name="Headset Playback Volume" value="108" /> |
||||
</path> |
||||
|
||||
<path name="listenback-usb-headphones-gain"> |
||||
<ctl name="Headset Playback Volume" value="120" /> |
||||
</path> |
||||
|
||||
<path name="listenback-usb-headset-gain"> |
||||
<ctl name="Headset Playback Volume" value="120" /> |
||||
</path> |
||||
<!-- end of Play Scenario --> |
||||
|
||||
<!-- Recording Scenario --> |
||||
<path name="rec-usb-headset-mic-gain"> |
||||
<ctl name="Headset Capture Volume" value="4" /> |
||||
</path> |
||||
|
||||
<path name="rec-usb-headset-stereo-mic-gain"> |
||||
<ctl name="Headset Capture Volume" value="4" /> |
||||
</path> |
||||
<!-- end of Recording Scenario --> |
||||
|
||||
<!-- recognition Scenario --> |
||||
<path name="vr-usb-headset-mic-gain"> |
||||
<ctl name="Headset Capture Volume" value="62" /> |
||||
</path> |
||||
|
||||
<path name="bargein-tts-usb-headset-mic-gain"> |
||||
<ctl name="Headset Capture Volume" value="62" /> |
||||
</path> |
||||
|
||||
<path name="bargein-aec-usb-headset-mic-gain"> |
||||
<ctl name="Headset Capture Volume" value="62" /> |
||||
</path> |
||||
<!-- end of recognition Scenario --> |
||||
|
||||
<!-- call Scenario --> |
||||
<path name="call-usb-headset-gain"> |
||||
<ctl name="Headset Playback Volume" value="108" /> |
||||
</path> |
||||
|
||||
<path name="call-usb-headset-mic-gain"> |
||||
<ctl name="Headset Capture Volume" value="22" /> |
||||
</path> |
||||
|
||||
<path name="call-usb-headphone-mic-gain"> |
||||
</path> |
||||
|
||||
<path name="wifi-call-usb-headset-gain"> |
||||
<ctl name="Headset Playback Volume" value="108" /> |
||||
</path> |
||||
|
||||
<path name="wifi-call-usb-headset-mic-gain"> |
||||
<ctl name="Headset Capture Volume" value="22" /> |
||||
</path> |
||||
|
||||
<path name="wifi-call-headphone-mic-gain"> |
||||
</path> |
||||
<!-- end of call Scenario --> |
||||
|
||||
<!-- TTY Scenario --> |
||||
<path name="call-tty-handset-gain"> |
||||
</path> |
||||
|
||||
<path name="call-tty-usb-headset-mic-gain"> |
||||
<ctl name="Headset Capture Volume" value="30" /> |
||||
</path> |
||||
|
||||
<path name="call-tty-usb-headset-gain"> |
||||
<ctl name="Headset Playback Volume" value="88" /> |
||||
</path> |
||||
|
||||
<path name="call-tty-full-usb-headset-mic-gain"> |
||||
<ctl name="Headset Capture Volume" value="30" /> |
||||
</path> |
||||
<!-- end of TTY Scenario --> |
||||
|
||||
<!-- VoWIFI TTY Scenario --> |
||||
<path name="wifi-call-tty-handset-gain"> |
||||
</path> |
||||
|
||||
<path name="wifi-call-tty-usb-headset-mic-gain"> |
||||
<ctl name="Headset Capture Volume" value="30" /> |
||||
</path> |
||||
|
||||
<path name="wifi-call-tty-usb-headset-gain"> |
||||
<ctl name="Headset Playback Volume" value="88" /> |
||||
</path> |
||||
|
||||
<path name="wifi-call-tty-full-usb-headset-mic-gain"> |
||||
<ctl name="Headset Capture Volume" value="30" /> |
||||
</path> |
||||
<!-- end of TTY Scenario --> |
||||
|
||||
<!-- VoIP Scenario --> |
||||
<path name="voip-comm-usb-headset-gain"> |
||||
<ctl name="Headset Playback Volume" value="108" /> |
||||
</path> |
||||
|
||||
<path name="voip-comm-usb-headset-mic-gain"> |
||||
<ctl name="Headset Capture Volume" value="62" /> |
||||
</path> |
||||
|
||||
<path name="voip-comm-usb-headphone-mic-gain"> |
||||
</path> |
||||
|
||||
<path name="voip-fmc-usb-headset-gain"> |
||||
<ctl name="Headset Playback Volume" value="108" /> |
||||
</path> |
||||
|
||||
<path name="voip-fmc-usb-headset-mic-gain"> |
||||
<ctl name="Headset Capture Volume" value="62" /> |
||||
</path> |
||||
|
||||
<path name="voip-fmc-usb-headphone-mic-gain"> |
||||
</path> |
||||
<!-- end of VoIP Scenario --> |
||||
|
||||
<!-- Factory Scenario --> |
||||
<path name="loopback-usb-headset-gain"> |
||||
<ctl name="Headset Playback Volume" value="108" /> |
||||
</path> |
||||
|
||||
<path name="loopback-main-mic-gain"> |
||||
</path> |
||||
|
||||
<path name="loopback-sub-mic-gain"> |
||||
</path> |
||||
|
||||
<path name="loopback-dual-mic-gain"> |
||||
</path> |
||||
|
||||
<path name="loopback-usb-headset-mic-gain"> |
||||
<ctl name="Headset Capture Volume" value="62" /> |
||||
</path> |
||||
<!-- end of Factory Scenario --> |
||||
|
||||
<path name="dummy"> |
||||
<!-- not exsit --> |
||||
</path> |
||||
</mixer> |
@ -1,25 +0,0 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
<!-- Samsung nfcextras Signature --> |
||||
<signer android:signature="30820411308202f9a003020102020900fd222d6fc87acde0300d06092a864886f70d010105050030819e310b3009060355040613024b523113301106035504080c0a536f7574684b6f7265613112301006035504070c095375776f6e43697479311b3019060355040a0c1253616d73756e67436f72706f726174696f6e310c300a060355040b0c03444d433114301206035504030c0b53616d73756e67436572743125302306092a864886f70d01090116166d2e73656375726974794073616d73756e672e636f6d3020170d3133303132343035323231305a180f32313132313233313035323231305a30819e310b3009060355040613024b523113301106035504080c0a536f7574684b6f7265613112301006035504070c095375776f6e43697479311b3019060355040a0c1253616d73756e67436f72706f726174696f6e310c300a060355040b0c03444d433114301206035504030c0b53616d73756e67436572743125302306092a864886f70d01090116166d2e73656375726974794073616d73756e672e636f6d30820120300d06092a864886f70d01010105000382010d00308201080282010100a2c51f56a1c8bf64ada0af152ced2344ac070b447efc85f1b69ce90fbc2b7a71257240c215eedbf7445c474fe34d62bc3035d79ba110859118f1200ecc9ae48b56400e187591272d59734e456d9dfd5a1f3227a30b9448bda84c2901b501295445e204ddb6f9f9e36b2560998f1764e446176fe5d83987220f8ed15106dc7c8ecb6798de45f5fbae54efe2b35a379631f545f84c98243aa4d92ef339330f954ad32e4e97aff69cbf68928484b03a8fa8eafdc8ff2a9801f249302d467b05f99a1680e4fb5b11624d5e53d67f09e86b82dd7305e3e483b12e3720fcccc2bc8857f13b6e1d60512074004f67d86241940eaba34afda2af3904b04913fa50f499f7020103a350304e301d0603551d0e04160414eef0f8211dccf6e442f3388889c9a3ea3ce0236c301f0603551d23041830168014eef0f8211dccf6e442f3388889c9a3ea3ce0236c300c0603551d13040530030101ff300d06092a864886f70d01010505000382010100395c7e7900c471e03fa9850905c6ab1edc5a8b7d43a16689d9bb1ec1a06513c4ea8f7471c6e474244174261cc151ae8d1a61019e0ed81fffee8afa1d01d85a32de796f4b46d0d5ddfcca7d1f90d523b54751f505a4e3b059569f24ba2564d72fbc4081533840f618c2993d935134d3c987605e032f6a12889af3190af1714a90f2a3476b8e0016ab45564bf10e611899babd86af33149ca6838b0a885c752ffe879f37997f262e819c62cf59caa794cfaaf8e3c462f5092a34264f0634316b13a67a644e104dc4070e8b6628a46f41da7e3c741f6edc21152f9f947dde6fe14b58f34e4d9e7abd103cb1ca9e09eb4fa5b553baa413329bd3919caca2d52e6d4b" /> |
||||
|
||||
<!-- Samsung Platform signature --> |
||||
<signer android:signature="308204d4308203bca003020102020900d20995a79c0daad6300d06092a864886f70d01010505003081a2310b3009060355040613024b52311430120603550408130b536f757468204b6f726561311330110603550407130a5375776f6e2043697479311c301a060355040a131353616d73756e6720436f72706f726174696f6e310c300a060355040b1303444d43311530130603550403130c53616d73756e6720436572743125302306092a864886f70d0109011616616e64726f69642e6f734073616d73756e672e636f6d301e170d3131303632323132323531325a170d3338313130373132323531325a3081a2310b3009060355040613024b52311430120603550408130b536f757468204b6f726561311330110603550407130a5375776f6e2043697479311c301a060355040a131353616d73756e6720436f72706f726174696f6e310c300a060355040b1303444d43311530130603550403130c53616d73756e6720436572743125302306092a864886f70d0109011616616e64726f69642e6f734073616d73756e672e636f6d30820120300d06092a864886f70d01010105000382010d00308201080282010100c986384a3e1f2fb206670e78ef232215c0d26f45a22728db99a44da11c35ac33a71fe071c4a2d6825a9b4c88b333ed96f3c5e6c666d60f3ee94c490885abcf8dc660f707aabc77ead3e2d0d8aee8108c15cd260f2e85042c28d2f292daa3c6da0c7bf2391db7841aade8fdf0c9d0defcf77124e6d2de0a9e0d2da746c3670e4ffcdc85b701bb4744861b96ff7311da3603c5a10336e55ffa34b4353eedc85f51015e1518c67e309e39f87639ff178107f109cd18411a6077f26964b6e63f8a70b9619db04306a323c1a1d23af867e19f14f570ffe573d0e3a0c2b30632aaec3173380994be1e341e3a90bd2e4b615481f46db39ea83816448ec35feb1735c1f3020103a382010b30820107301d0603551d0e04160414932c3af70b627a0c7610b5a0e7427d6cfaea3f1e3081d70603551d230481cf3081cc8014932c3af70b627a0c7610b5a0e7427d6cfaea3f1ea181a8a481a53081a2310b3009060355040613024b52311430120603550408130b536f757468204b6f726561311330110603550407130a5375776f6e2043697479311c301a060355040a131353616d73756e6720436f72706f726174696f6e310c300a060355040b1303444d43311530130603550403130c53616d73756e6720436572743125302306092a864886f70d0109011616616e64726f69642e6f734073616d73756e672e636f6d820900d20995a79c0daad6300c0603551d13040530030101ff300d06092a864886f70d01010505000382010100329601fe40e036a4a86cc5d49dd8c1b5415998e72637538b0d430369ac51530f63aace8c019a1a66616a2f1bb2c5fabd6f313261f380e3471623f053d9e3c53f5fd6d1965d7b000e4dc244c1b27e2fe9a323ff077f52c4675e86247aa801187137e30c9bbf01c567a4299db4bf0b25b7d7107a7b81ee102f72ff47950164e26752e114c42f8b9d2a42e7308897ec640ea1924ed13abbe9d120912b62f4926493a86db94c0b46f44c6161d58c2f648164890c512dfb28d42c855bf470dbee2dab6960cad04e81f71525ded46cdd0f359f99c460db9f007d96ce83b4b218ac2d82c48f12608d469733f05a3375594669ccbf8a495544d6c5701e9369c08c810158"> |
||||
<package android:name="org.simalliance.openmobileapi.service" /> |
||||
<package android:name="com.android.se" /> |
||||
<package android:name="com.skms.android.agent" /> |
||||
<package android:name="com.samsung.android.spay" /> |
||||
<package android:name="com.samsung.android.spayfw" /> |
||||
<package android:name="com.sem.factoryapp" /> |
||||
</signer> |
||||
|
||||
<!-- T-Mobile development Signature --> |
||||
<signer android:signature="3082034830820230a00302010202044f62832f300d06092a864886f70d01010505003066310b3009060355040613025553310b3009060355040813024e593111300f060355040713084e657720596f726b310d300b060355040a130449736973310d300b060355040b13044973697331193017060355040313104a564c2056656e7475726573204c4c43301e170d3132303331363030303235355a170d3339303830323030303235355a3066310b3009060355040613025553310b3009060355040813024e593111300f060355040713084e657720596f726b310d300b060355040a130449736973310d300b060355040b13044973697331193017060355040313104a564c2056656e7475726573204c4c4330820122300d06092a864886f70d01010105000382010f003082010a02820101009aaf7f1047a6821ab0b4ffb7d58f8a0a66f09689dc59926e966b24896759b96304825ea149ebf30e6249877fedac185eec7aa7a44dc718ab578584888c673f46bc351b48dcd54f47bd27a0836032899b0510e0ce69863184bcd033b0654f09e801a24f06fadd7330f3665e12fbbf1c2b616ca14ac169d206607f229a7ad6d3579d330373be0de0d7148eabb80beed83602494247c0b7b735812a5ece89c1ce7f2229f757e29ebfae72350d2db27974cd5341ba5872a92f471a0768972e35246d0269d41d345cd8bda2df14009212d9640f3a33116460dce389c5a113b84e4a6b7f8b597cb601e53dace8777e380ffe4d9f0abfa14993a1f653c9a6bb5a245fd10203010001300d06092a864886f70d010105050003820101009089e52bb237b78c92dd95b4d07004751b3d68e12e83ab0baca39ea593b9b9f8f6395491f6616fe4d2e4c7a7e53c898a17f3ab2c9fac3b1c0886ee8e769ba96488aafd646a7aa425fb283cd6d9d600a083d18868d4d93de7ec73b258f61fc66d2a3f4b4c7b53df62fd3374a5e658bd8266ee24480923ea584f2e7adde360b459e4ad01bcb9f5582f95dab3964e546baf5b33f63acfbb64494902ebae5cc0930abb7dabf0e4727fcc755a6baa6e68be3b864ab1e6438fed6dd280f081ef1e3b3545a257b456b68787d8080653c31ed7f96f6b5a67186dc5a35e620b9bbb9d47a1871d58bf38e192906399c53cb2fab61c1392deae6209d6fb476897a471a23ab4" > |
||||
<model sales="tmo" /> |
||||
</signer> |
||||
|
||||
<!-- T-Mobile production Signature --> |
||||
<signer android:signature="3082036A30820252A00302010202044F8867D3300D06092A864886F70D01010505003077310B3009060355040613025553310B30090603550408130257413111300F0603550407130842656C6C65767565311C301A060355040A131350726F64756374205265616C697A6174696F6E3111300F060355040B1308542D4D6F62696C65311730150603550403130E4E46432050726F64756374696F6E301E170D3132303431333137353231395A170D3339303833303137353231395A3077310B3009060355040613025553310B30090603550408130257413111300F0603550407130842656C6C65767565311C301A060355040A131350726F64756374205265616C697A6174696F6E3111300F060355040B1308542D4D6F62696C65311730150603550403130E4E46432050726F64756374696F6E30820122300D06092A864886F70D01010105000382010F003082010A0282010100D74AC622FDF8F341BE8661DC89F447A78AE25E9F2852AF47242C4FA0FFFAC6658513EFCB427DDA28DB8BEF94F11DFC0B95D1C41ED968E90976B75A66620521D3B2AFA19E8F1E7E93271E444D00020547E2E5307BBFB62D5933116D6D384B5C3B845D1D92B30FF4F689ECB25E7D94D1FCC2F85BAB17CE944CC7CFCA673C5CDBB71F092EACE5432EF45682AA712D1E806F7139CA6BED6BA82F4E67F39B28E49A9704C97C6AC021C3CA6B1143051BCFE67A98F2DEAE788C1DB703D4BB07FB0322998B493BA56CCE49E25691B11E0DD48AC1A8CB5F6CAA6629CB661652FA0EA6288712386DA83F5162150DB8D9353F7E291A54B9C877965C6721DE695C8143BB7CD70203010001300D06092A864886F70D010105050003820101005073792AF8C6DB0762C992A776119DA201A5D62192D4C08EFB827CE999581034B002AE9DD1ED524E860B7F32097918AD82267954336C523D46C5602EF8A2BBFD1BEA553A140706825BFCBD2C60CAA46862E07D7084F83A74CA5271FAB289623D5AF8804E38CCE2CAB9A5EE00A3E5E66E2D7019ED7BAEA337307C0C977CC584E66C4160E6BF700BE37E534691F8D52F8BE65A1781363353ADFB3E0A6746796A31F8A7D6576BCBAC4E670D98FA0D76589B1F1C41029D83AE9E094955D33DE24A264C8B0BDFAFBB418BF6302FC256442A2DD93B14F31CFFDEC8430BDC5EF04B74CA7B058EA0E4ACC12D3558744F9DE21BB8E5443D50C4B83998A012C003B8402E54" > |
||||
<model sales="tmo" /> |
||||
</signer> |
||||
</resources> |
@ -0,0 +1,14 @@ |
||||
<?xml version="1.0" ?> |
||||
<permissions> |
||||
<privapp-permissions package="com.android.hotwordenrollment.okgoogle"> |
||||
<permission name="android.permission.INTERACT_ACROSS_USERS"/> |
||||
<permission name="android.permission.KEYPHRASE_ENROLLMENT_APPLICATION"/> |
||||
<permission name="android.permission.MANAGE_VOICE_KEYPHRASES"/> |
||||
</privapp-permissions> |
||||
|
||||
<privapp-permissions package="com.android.hotwordenrollment.xgoogle"> |
||||
<permission name="android.permission.INTERACT_ACROSS_USERS"/> |
||||
<permission name="android.permission.KEYPHRASE_ENROLLMENT_APPLICATION"/> |
||||
<permission name="android.permission.MANAGE_VOICE_KEYPHRASES"/> |
||||
</privapp-permissions> |
||||
</permissions> |
@ -1,45 +0,0 @@ |
||||
#
|
||||
# Copyright (C) 2021 The LineageOS Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS) |
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
BiometricsFingerprint.cpp \
|
||||
service.cpp
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libbase \
|
||||
libhardware \
|
||||
libhidlbase \
|
||||
libhidltransport \
|
||||
liblog \
|
||||
libutils \
|
||||
android.hardware.biometrics.fingerprint@2.1 \
|
||||
android.hardware.biometrics.fingerprint@2.2 \
|
||||
android.hardware.biometrics.fingerprint@2.3 \
|
||||
vendor.samsung.hardware.biometrics.fingerprint@3.0
|
||||
|
||||
LOCAL_MODULE := vendor.samsung.hardware.biometrics.fingerprint@3.0-service.sm7125
|
||||
LOCAL_INIT_RC := vendor.samsung.hardware.biometrics.fingerprint@3.0-service.sm7125.rc
|
||||
LOCAL_VINTF_FRAGMENTS := vendor.samsung.hardware.biometrics.fingerprint@3.0-service.sm7125.xml
|
||||
LOCAL_MODULE_RELATIVE_PATH := hw
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_OWNER := samsung
|
||||
LOCAL_VENDOR_MODULE := true
|
||||
|
||||
include $(BUILD_EXECUTABLE) |
@ -1,474 +0,0 @@ |
||||
/*
|
||||
* Copyright (C) 2019 The LineageOS Project |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
#define LOG_TAG "vendor.samsung.hardware.biometrics.fingerprint@3.0-service.sm7125" |
||||
|
||||
#include <android-base/logging.h> |
||||
|
||||
#include <hardware/hw_auth_token.h> |
||||
|
||||
#include <hardware/fingerprint.h> |
||||
#include <hardware/hardware.h> |
||||
#include "BiometricsFingerprint.h" |
||||
#include <android-base/properties.h> |
||||
#include <fstream> |
||||
#include <dlfcn.h> |
||||
#include <inttypes.h> |
||||
#include <unistd.h> |
||||
#include <thread> |
||||
|
||||
#define SEH_FINGER_STATE 22 |
||||
#define SEH_PARAM_PRESSED 2 |
||||
#define SEH_PARAM_RELEASED 1 |
||||
#define SEH_AOSP_FQNAME "android.hardware.biometrics.fingerprint@2.3::IBiometricsFingerprint" |
||||
#define TSP_CMD_PATH "/sys/class/sec/tsp/cmd" |
||||
#define BRIGHTNESS_PATH "/sys/class/backlight/panel0-backlight/brightness" |
||||
|
||||
namespace vendor { |
||||
namespace samsung { |
||||
namespace hardware { |
||||
namespace biometrics { |
||||
namespace fingerprint { |
||||
namespace V3_0 { |
||||
namespace implementation { |
||||
|
||||
using RequestStatus = android::hardware::biometrics::fingerprint::V2_1::RequestStatus; |
||||
|
||||
ISehBiometricsFingerprint* SehBiometricsFingerprint::sInstance = nullptr; |
||||
|
||||
template <typename T> |
||||
static void set(const std::string& path, const T& value) { |
||||
std::ofstream file(path); |
||||
file << value; |
||||
} |
||||
|
||||
std::string getBootloader() { |
||||
return android::base::GetProperty("ro.boot.bootloader", ""); |
||||
} |
||||
|
||||
template <typename T> |
||||
static T get(const std::string& path, const T& def) { |
||||
std::ifstream file(path); |
||||
T result; |
||||
|
||||
file >> result; |
||||
return file.fail() ? def : result; |
||||
} |
||||
|
||||
SehBiometricsFingerprint::SehBiometricsFingerprint() : mClientCallback(nullptr) { |
||||
sInstance = this; // keep track of the most recent instance
|
||||
if (!openHal()) { |
||||
LOG(ERROR) << "Can't open HAL module"; |
||||
} |
||||
|
||||
if (getBootloader().find("A525") != std::string::npos) { |
||||
set(TSP_CMD_PATH, "set_fod_rect,421,2018,659,2256"); |
||||
} else if (getBootloader().find("A725") != std::string::npos) { |
||||
set(TSP_CMD_PATH, "set_fod_rect,426,2031,654,2259"); |
||||
} else { |
||||
LOG(ERROR) << "Device is not an A52 or A72, not setting set_fod_rect"; |
||||
} |
||||
|
||||
std::ifstream in("/sys/devices/virtual/fingerprint/fingerprint/position"); |
||||
mIsUdfps = !!in; |
||||
if (in) |
||||
in.close(); |
||||
|
||||
set(TSP_CMD_PATH, "fod_enable,1,1,0"); |
||||
} |
||||
|
||||
SehBiometricsFingerprint::~SehBiometricsFingerprint() { |
||||
if (ss_fingerprint_close() != 0) { |
||||
LOG(ERROR) << "Can't close HAL module"; |
||||
} |
||||
} |
||||
|
||||
Return<bool> SehBiometricsFingerprint::isUdfps(uint32_t) { |
||||
return mIsUdfps; |
||||
} |
||||
|
||||
void SehBiometricsFingerprint::requestResult(int, const hidl_vec<int8_t>&) { |
||||
// Ignore all results
|
||||
} |
||||
|
||||
static hidl_vec<int8_t> stringToVec(const std::string& str) { |
||||
auto vec = hidl_vec<int8_t>(); |
||||
vec.resize(str.size() + 1); |
||||
for (size_t i = 0; i < str.size(); ++i) { |
||||
vec[i] = (int8_t) str[i]; |
||||
} |
||||
vec[str.size()] = '\0'; |
||||
return vec; |
||||
} |
||||
|
||||
Return<void> SehBiometricsFingerprint::onFingerDown(uint32_t, uint32_t, float, float) { |
||||
mPreviousBrightness = get<std::string>(BRIGHTNESS_PATH, ""); |
||||
set(BRIGHTNESS_PATH, "331"); |
||||
|
||||
sehRequest(SEH_FINGER_STATE, SEH_PARAM_PRESSED, |
||||
stringToVec(SEH_AOSP_FQNAME), SehBiometricsFingerprint::requestResult); |
||||
|
||||
std::thread([this]() { |
||||
std::this_thread::sleep_for(std::chrono::milliseconds(400)); |
||||
if (!mPreviousBrightness.empty()) { |
||||
set(BRIGHTNESS_PATH, mPreviousBrightness); |
||||
mPreviousBrightness = ""; |
||||
} |
||||
}).detach(); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<void> SehBiometricsFingerprint::onFingerUp() { |
||||
sehRequest(SEH_FINGER_STATE, SEH_PARAM_RELEASED, |
||||
stringToVec(SEH_AOSP_FQNAME), SehBiometricsFingerprint::requestResult); |
||||
|
||||
return Void(); |
||||
} |
||||
|
||||
Return<RequestStatus> SehBiometricsFingerprint::ErrorFilter(int32_t error) { |
||||
switch (error) { |
||||
case 0: |
||||
return RequestStatus::SYS_OK; |
||||
case -2: |
||||
return RequestStatus::SYS_ENOENT; |
||||
case -4: |
||||
return RequestStatus::SYS_EINTR; |
||||
case -5: |
||||
return RequestStatus::SYS_EIO; |
||||
case -11: |
||||
return RequestStatus::SYS_EAGAIN; |
||||
case -12: |
||||
return RequestStatus::SYS_ENOMEM; |
||||
case -13: |
||||
return RequestStatus::SYS_EACCES; |
||||
case -14: |
||||
return RequestStatus::SYS_EFAULT; |
||||
case -16: |
||||
return RequestStatus::SYS_EBUSY; |
||||
case -22: |
||||
return RequestStatus::SYS_EINVAL; |
||||
case -28: |
||||
return RequestStatus::SYS_ENOSPC; |
||||
case -110: |
||||
return RequestStatus::SYS_ETIMEDOUT; |
||||
default: |
||||
LOG(ERROR) << "An unknown error returned from fingerprint vendor library: " << error; |
||||
return RequestStatus::SYS_UNKNOWN; |
||||
} |
||||
} |
||||
|
||||
// Translate from errors returned by traditional HAL (see fingerprint.h) to
|
||||
// HIDL-compliant FingerprintError.
|
||||
FingerprintError SehBiometricsFingerprint::VendorErrorFilter(int32_t error, int32_t* vendorCode) { |
||||
*vendorCode = 0; |
||||
switch (error) { |
||||
case FINGERPRINT_ERROR_HW_UNAVAILABLE: |
||||
return FingerprintError::ERROR_HW_UNAVAILABLE; |
||||
case FINGERPRINT_ERROR_UNABLE_TO_PROCESS: |
||||
return FingerprintError::ERROR_UNABLE_TO_PROCESS; |
||||
case FINGERPRINT_ERROR_TIMEOUT: |
||||
return FingerprintError::ERROR_TIMEOUT; |
||||
case FINGERPRINT_ERROR_NO_SPACE: |
||||
return FingerprintError::ERROR_NO_SPACE; |
||||
case FINGERPRINT_ERROR_CANCELED: |
||||
return FingerprintError::ERROR_CANCELED; |
||||
case FINGERPRINT_ERROR_UNABLE_TO_REMOVE: |
||||
return FingerprintError::ERROR_UNABLE_TO_REMOVE; |
||||
case FINGERPRINT_ERROR_LOCKOUT: |
||||
return FingerprintError::ERROR_LOCKOUT; |
||||
default: |
||||
if (error >= FINGERPRINT_ERROR_VENDOR_BASE) { |
||||
// vendor specific code.
|
||||
*vendorCode = error - FINGERPRINT_ERROR_VENDOR_BASE; |
||||
return FingerprintError::ERROR_VENDOR; |
||||
} |
||||
} |
||||
LOG(ERROR) << "Unknown error from fingerprint vendor library: " << error; |
||||
return FingerprintError::ERROR_UNABLE_TO_PROCESS; |
||||
} |
||||
|
||||
// Translate acquired messages returned by traditional HAL (see fingerprint.h)
|
||||
// to HIDL-compliant FingerprintAcquiredInfo.
|
||||
FingerprintAcquiredInfo SehBiometricsFingerprint::VendorAcquiredFilter(int32_t info, |
||||
int32_t* vendorCode) { |
||||
*vendorCode = 0; |
||||
switch (info) { |
||||
case FINGERPRINT_ACQUIRED_GOOD: |
||||
return FingerprintAcquiredInfo::ACQUIRED_GOOD; |
||||
case FINGERPRINT_ACQUIRED_PARTIAL: |
||||
return FingerprintAcquiredInfo::ACQUIRED_PARTIAL; |
||||
case FINGERPRINT_ACQUIRED_INSUFFICIENT: |
||||
return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT; |
||||
case FINGERPRINT_ACQUIRED_IMAGER_DIRTY: |
||||
return FingerprintAcquiredInfo::ACQUIRED_IMAGER_DIRTY; |
||||
case FINGERPRINT_ACQUIRED_TOO_SLOW: |
||||
return FingerprintAcquiredInfo::ACQUIRED_TOO_SLOW; |
||||
case FINGERPRINT_ACQUIRED_TOO_FAST: |
||||
return FingerprintAcquiredInfo::ACQUIRED_TOO_FAST; |
||||
default: |
||||
if (info >= FINGERPRINT_ACQUIRED_VENDOR_BASE) { |
||||
// vendor specific code.
|
||||
*vendorCode = info - FINGERPRINT_ACQUIRED_VENDOR_BASE; |
||||
return FingerprintAcquiredInfo::ACQUIRED_VENDOR; |
||||
} |
||||
} |
||||
LOG(ERROR) << "Unknown acquiredmsg from fingerprint vendor library: " << info; |
||||
return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT; |
||||
} |
||||
|
||||
Return<uint64_t> SehBiometricsFingerprint::setNotify( |
||||
const sp<IBiometricsFingerprintClientCallback>& clientCallback) { |
||||
std::lock_guard<std::mutex> lock(mClientCallbackMutex); |
||||
mClientCallback = clientCallback; |
||||
// This is here because HAL 2.3 doesn't have a way to propagate a
|
||||
// unique token for its driver. Subsequent versions should send a unique
|
||||
// token for each call to setNotify(). This is fine as long as there's only
|
||||
// one fingerprint device on the platform.
|
||||
return reinterpret_cast<uint64_t>(this); |
||||
} |
||||
|
||||
Return<uint64_t> SehBiometricsFingerprint::preEnroll() { |
||||
return ss_fingerprint_pre_enroll(); |
||||
} |
||||
|
||||
Return<RequestStatus> SehBiometricsFingerprint::enroll(const hidl_array<uint8_t, 69>& hat, |
||||
uint32_t gid, uint32_t timeoutSec) { |
||||
const hw_auth_token_t* authToken = reinterpret_cast<const hw_auth_token_t*>(hat.data()); |
||||
|
||||
return ErrorFilter(ss_fingerprint_enroll(authToken, gid, timeoutSec)); |
||||
} |
||||
|
||||
Return<RequestStatus> SehBiometricsFingerprint::postEnroll() { |
||||
return ErrorFilter(ss_fingerprint_post_enroll()); |
||||
} |
||||
|
||||
Return<uint64_t> SehBiometricsFingerprint::getAuthenticatorId() { |
||||
return ss_fingerprint_get_auth_id(); |
||||
} |
||||
|
||||
Return<RequestStatus> SehBiometricsFingerprint::cancel() { |
||||
return ErrorFilter(ss_fingerprint_cancel()); |
||||
} |
||||
|
||||
Return<RequestStatus> SehBiometricsFingerprint::enumerate() { |
||||
if (ss_fingerprint_enumerate != nullptr) { |
||||
return ErrorFilter(ss_fingerprint_enumerate()); |
||||
} |
||||
|
||||
return RequestStatus::SYS_UNKNOWN; |
||||
} |
||||
|
||||
Return<RequestStatus> SehBiometricsFingerprint::remove(uint32_t gid, uint32_t fid) { |
||||
return ErrorFilter(ss_fingerprint_remove(gid, fid)); |
||||
} |
||||
|
||||
Return<RequestStatus> SehBiometricsFingerprint::setActiveGroup(uint32_t gid, |
||||
const hidl_string&) { |
||||
std::string storePath = "/data/vendor/biometrics/fp/User_" + std::to_string(gid); |
||||
LOG(ERROR) << "setActiveGroup " << gid << " " << storePath; |
||||
return ErrorFilter(ss_fingerprint_set_active_group(gid, storePath.c_str())); |
||||
} |
||||
|
||||
Return<RequestStatus> SehBiometricsFingerprint::authenticate(uint64_t operationId, uint32_t gid) { |
||||
return ErrorFilter(ss_fingerprint_authenticate(operationId, gid)); |
||||
} |
||||
|
||||
Return<void> SehBiometricsFingerprint::sehRequest(int32_t cmd_id, |
||||
int32_t inParam, const hidl_vec<int8_t>& inputBuf, sehRequest_cb _hidl_cb) { |
||||
size_t inputSize = 0; |
||||
for (; inputBuf[inputSize] != '\0'; ++inputSize); |
||||
|
||||
int8_t input[inputSize + 1]; |
||||
|
||||
// HACK: SehBiometrics 3.0 doesn't have the len parameter like the older 2.1 HAL has. Set it to 10 for now
|
||||
int8_t output[10]; |
||||
|
||||
for (size_t i = 0; i < inputSize; ++i) { |
||||
input[i] = inputBuf[i]; |
||||
} |
||||
input[inputSize] = '\0'; |
||||
for (size_t i = 0; i < static_cast<size_t>(10); ++i) { |
||||
output[i] = '\0'; |
||||
} |
||||
|
||||
LOG(ERROR) << "request(cmd_id=" << cmd_id |
||||
<< ", len=" << 10 |
||||
<< ", inParam=" << inParam |
||||
<< ", inputBuf=" << input |
||||
<< ")"; |
||||
|
||||
int ret = ss_fingerprint_request(cmd_id, input, 0, 10 == 0 ? nullptr : output, 10, inParam); |
||||
|
||||
auto outBuf = hidl_vec<int8_t>(); |
||||
outBuf.setToExternal(output, 10); |
||||
|
||||
_hidl_cb(ret, outBuf); |
||||
return Void(); |
||||
} |
||||
|
||||
ISehBiometricsFingerprint* SehBiometricsFingerprint::getInstance() { |
||||
if (!sInstance) { |
||||
sInstance = new SehBiometricsFingerprint(); |
||||
} |
||||
return sInstance; |
||||
} |
||||
|
||||
bool SehBiometricsFingerprint::openHal() { |
||||
void* handle = dlopen("libbauthserver.so", RTLD_NOW); |
||||
if (handle) { |
||||
int err; |
||||
|
||||
ss_fingerprint_close = |
||||
reinterpret_cast<typeof(ss_fingerprint_close)>(dlsym(handle, "ss_fingerprint_close")); |
||||
ss_fingerprint_open = |
||||
reinterpret_cast<typeof(ss_fingerprint_open)>(dlsym(handle, "ss_fingerprint_open")); |
||||
|
||||
ss_set_notify_callback = reinterpret_cast<typeof(ss_set_notify_callback)>( |
||||
dlsym(handle, "ss_set_notify_callback")); |
||||
ss_fingerprint_pre_enroll = reinterpret_cast<typeof(ss_fingerprint_pre_enroll)>( |
||||
dlsym(handle, "ss_fingerprint_pre_enroll")); |
||||
ss_fingerprint_enroll = |
||||
reinterpret_cast<typeof(ss_fingerprint_enroll)>(dlsym(handle, "ss_fingerprint_enroll")); |
||||
ss_fingerprint_post_enroll = reinterpret_cast<typeof(ss_fingerprint_post_enroll)>( |
||||
dlsym(handle, "ss_fingerprint_post_enroll")); |
||||
ss_fingerprint_get_auth_id = reinterpret_cast<typeof(ss_fingerprint_get_auth_id)>( |
||||
dlsym(handle, "ss_fingerprint_get_auth_id")); |
||||
ss_fingerprint_cancel = |
||||
reinterpret_cast<typeof(ss_fingerprint_cancel)>(dlsym(handle, "ss_fingerprint_cancel")); |
||||
ss_fingerprint_enumerate = reinterpret_cast<typeof(ss_fingerprint_enumerate)>( |
||||
dlsym(handle, "ss_fingerprint_enumerate")); |
||||
ss_fingerprint_remove = |
||||
reinterpret_cast<typeof(ss_fingerprint_remove)>(dlsym(handle, "ss_fingerprint_remove")); |
||||
ss_fingerprint_set_active_group = reinterpret_cast<typeof(ss_fingerprint_set_active_group)>( |
||||
dlsym(handle, "ss_fingerprint_set_active_group")); |
||||
ss_fingerprint_authenticate = reinterpret_cast<typeof(ss_fingerprint_authenticate)>( |
||||
dlsym(handle, "ss_fingerprint_authenticate")); |
||||
ss_fingerprint_request = reinterpret_cast<typeof(ss_fingerprint_request)>( |
||||
dlsym(handle, "ss_fingerprint_request")); |
||||
|
||||
if ((err = ss_fingerprint_open(nullptr)) != 0) { |
||||
LOG(ERROR) << "Can't open fingerprint, error: " << err; |
||||
return false; |
||||
} |
||||
|
||||
if ((err = ss_set_notify_callback(SehBiometricsFingerprint::notify)) != 0) { |
||||
LOG(ERROR) << "Can't register fingerprint module callback, error: " << err; |
||||
return false; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
void SehBiometricsFingerprint::notify(const fingerprint_msg_t* msg) { |
||||
SehBiometricsFingerprint* thisPtr = |
||||
static_cast<SehBiometricsFingerprint*>(SehBiometricsFingerprint::getInstance()); |
||||
std::lock_guard<std::mutex> lock(thisPtr->mClientCallbackMutex); |
||||
if (thisPtr == nullptr || thisPtr->mClientCallback == nullptr) { |
||||
LOG(ERROR) << "Receiving callbacks before the client callback is registered."; |
||||
return; |
||||
} |
||||
const uint64_t devId = 1; |
||||
switch (msg->type) { |
||||
case FINGERPRINT_ERROR: { |
||||
int32_t vendorCode = 0; |
||||
FingerprintError result = VendorErrorFilter(msg->data.error, &vendorCode); |
||||
LOG(DEBUG) << "onError(" << static_cast<int>(result) << ")"; |
||||
if (!thisPtr->mClientCallback->onError(devId, result, vendorCode).isOk()) { |
||||
LOG(ERROR) << "failed to invoke fingerprint onError callback"; |
||||
} |
||||
} break; |
||||
case FINGERPRINT_ACQUIRED: { |
||||
int32_t vendorCode = 0; |
||||
FingerprintAcquiredInfo result = |
||||
VendorAcquiredFilter(msg->data.acquired.acquired_info, &vendorCode); |
||||
LOG(DEBUG) << "onAcquired(" << static_cast<int>(result) << ")"; |
||||
if (!thisPtr->mClientCallback->onAcquired(devId, result, vendorCode).isOk()) { |
||||
LOG(ERROR) << "failed to invoke fingerprint onAcquired callback"; |
||||
} |
||||
} break; |
||||
case FINGERPRINT_TEMPLATE_ENROLLING: |
||||
LOG(DEBUG) << "onEnrollResult(fid=" << msg->data.enroll.finger.fid |
||||
<< ", gid=" << msg->data.enroll.finger.gid |
||||
<< ", rem=" << msg->data.enroll.samples_remaining << ")"; |
||||
if (thisPtr->mClientCallback |
||||
->onEnrollResult(devId, msg->data.enroll.finger.fid, |
||||
msg->data.enroll.finger.gid, msg->data.enroll.samples_remaining) |
||||
.isOk()) { |
||||
fingerprint_msg_t* newMsg = (fingerprint_msg_t*)msg; |
||||
newMsg->data.enroll.samples_remaining = 100 - msg->data.enroll.samples_remaining; |
||||
msg = newMsg; |
||||
} else { |
||||
LOG(ERROR) << "failed to invoke fingerprint onEnrollResult callback"; |
||||
} |
||||
break; |
||||
case FINGERPRINT_TEMPLATE_REMOVED: |
||||
LOG(DEBUG) << "onRemove(fid=" << msg->data.removed.finger.fid |
||||
<< ", gid=" << msg->data.removed.finger.gid |
||||
<< ", rem=" << msg->data.removed.remaining_templates << ")"; |
||||
if (!thisPtr->mClientCallback |
||||
->onRemoved(devId, msg->data.removed.finger.fid, msg->data.removed.finger.gid, |
||||
msg->data.removed.remaining_templates) |
||||
.isOk()) { |
||||
LOG(ERROR) << "failed to invoke fingerprint onRemoved callback"; |
||||
} |
||||
break; |
||||
case FINGERPRINT_AUTHENTICATED: |
||||
LOG(DEBUG) << "onAuthenticated(fid=" << msg->data.authenticated.finger.fid |
||||
<< ", gid=" << msg->data.authenticated.finger.gid << ")"; |
||||
if (msg->data.authenticated.finger.fid != 0) { |
||||
const uint8_t* hat = reinterpret_cast<const uint8_t*>(&msg->data.authenticated.hat); |
||||
const hidl_vec<uint8_t> token( |
||||
std::vector<uint8_t>(hat, hat + sizeof(msg->data.authenticated.hat))); |
||||
if (!thisPtr->mClientCallback |
||||
->onAuthenticated(devId, msg->data.authenticated.finger.fid, |
||||
msg->data.authenticated.finger.gid, token) |
||||
.isOk()) { |
||||
LOG(ERROR) << "failed to invoke fingerprint onAuthenticated callback"; |
||||
} |
||||
} else { |
||||
// Not a recognized fingerprint
|
||||
if (!thisPtr->mClientCallback |
||||
->onAuthenticated(devId, msg->data.authenticated.finger.fid, |
||||
msg->data.authenticated.finger.gid, hidl_vec<uint8_t>()) |
||||
.isOk()) { |
||||
LOG(ERROR) << "failed to invoke fingerprint onAuthenticated callback"; |
||||
} |
||||
} |
||||
break; |
||||
case FINGERPRINT_TEMPLATE_ENUMERATING: |
||||
LOG(DEBUG) << "onEnumerate(fid=" << msg->data.enumerated.finger.fid |
||||
<< ", gid=" << msg->data.enumerated.finger.gid |
||||
<< ", rem=" << msg->data.enumerated.remaining_templates << ")"; |
||||
if (!thisPtr->mClientCallback |
||||
->onEnumerate(devId, msg->data.enumerated.finger.fid, |
||||
msg->data.enumerated.finger.gid, |
||||
msg->data.enumerated.remaining_templates) |
||||
.isOk()) { |
||||
LOG(ERROR) << "failed to invoke fingerprint onEnumerate callback"; |
||||
} |
||||
break; |
||||
} |
||||
} |
||||
|
||||
} // namespace implementation
|
||||
} // namespace V3_0
|
||||
} // namespace fingerprint
|
||||
} // namespace biometrics
|
||||
} // namespace hardware
|
||||
} // namespace samsung
|
||||
} // namespace vendor
|
@ -1,114 +0,0 @@ |
||||
/*
|
||||
* Copyright (C) 2019 The LineageOS Project |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#ifndef ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_3_BIOMETRICSFINGERPRINT_H |
||||
#define ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_3_BIOMETRICSFINGERPRINT_H |
||||
|
||||
#include <vendor/samsung/hardware/biometrics/fingerprint/3.0/ISehBiometricsFingerprint.h> |
||||
#include <hardware/fingerprint.h> |
||||
#include <hardware/hardware.h> |
||||
#include <hidl/MQDescriptor.h> |
||||
#include <hidl/Status.h> |
||||
|
||||
namespace vendor { |
||||
namespace samsung { |
||||
namespace hardware { |
||||
namespace biometrics { |
||||
namespace fingerprint { |
||||
namespace V3_0 { |
||||
namespace implementation { |
||||
|
||||
using ::android::sp; |
||||
using ::android::hardware::hidl_string; |
||||
using ::android::hardware::hidl_vec; |
||||
using ::android::hardware::Return; |
||||
using ::android::hardware::Void; |
||||
using ::android::hardware::hidl_array; |
||||
using ::android::hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprintClientCallback; |
||||
using ::android::hardware::biometrics::fingerprint::V2_1::RequestStatus; |
||||
using ::android::hardware::biometrics::fingerprint::V2_1::FingerprintError; |
||||
using ::android::hardware::biometrics::fingerprint::V2_1::FingerprintAcquiredInfo; |
||||
|
||||
struct SehBiometricsFingerprint : public ISehBiometricsFingerprint { |
||||
public: |
||||
SehBiometricsFingerprint(); |
||||
~SehBiometricsFingerprint(); |
||||
|
||||
// Method to wrap legacy HAL with BiometricsFingerprint class
|
||||
static ISehBiometricsFingerprint* getInstance(); |
||||
|
||||
// Methods from ::android::hardware::biometrics::fingerprint::V2_3::IBiometricsFingerprint follow.
|
||||
Return<uint64_t> setNotify( |
||||
const sp<IBiometricsFingerprintClientCallback>& clientCallback) override; |
||||
Return<uint64_t> preEnroll() override; |
||||
Return<RequestStatus> enroll(const hidl_array<uint8_t, 69>& hat, uint32_t gid, |
||||
uint32_t timeoutSec) override; |
||||
Return<RequestStatus> postEnroll() override; |
||||
Return<uint64_t> getAuthenticatorId() override; |
||||
Return<RequestStatus> cancel() override; |
||||
Return<RequestStatus> enumerate() override; |
||||
Return<RequestStatus> remove(uint32_t gid, uint32_t fid) override; |
||||
Return<RequestStatus> setActiveGroup(uint32_t gid, const hidl_string& storePath) override; |
||||
Return<RequestStatus> authenticate(uint64_t operationId, uint32_t gid) override; |
||||
Return<bool> isUdfps(uint32_t sensorID) override; |
||||
Return<void> onFingerDown(uint32_t x, uint32_t y, float minor, float major) override; |
||||
Return<void> onFingerUp() override; |
||||
|
||||
// Methods from ::vendor::samsung::hardware::biometrics::fingerprint::V3_0::ISehBiometricsFingerprint follow.
|
||||
Return<void> sehRequest(int32_t cmd_id, int32_t inParam, const hidl_vec<int8_t>& inputBuf, sehRequest_cb _hidl_cb) override; |
||||
|
||||
private: |
||||
bool openHal(); |
||||
static void notify( |
||||
const fingerprint_msg_t* msg); /* Static callback for legacy HAL implementation */ |
||||
static Return<RequestStatus> ErrorFilter(int32_t error); |
||||
static FingerprintError VendorErrorFilter(int32_t error, int32_t* vendorCode); |
||||
static FingerprintAcquiredInfo VendorAcquiredFilter(int32_t error, int32_t* vendorCode); |
||||
static ISehBiometricsFingerprint* sInstance; |
||||
|
||||
std::mutex mClientCallbackMutex; |
||||
sp<IBiometricsFingerprintClientCallback> mClientCallback; |
||||
bool mIsUdfps; |
||||
|
||||
int (*ss_fingerprint_close)(); |
||||
int (*ss_fingerprint_open)(const char* id); |
||||
|
||||
int (*ss_set_notify_callback)(fingerprint_notify_t notify); |
||||
uint64_t (*ss_fingerprint_pre_enroll)(); |
||||
int (*ss_fingerprint_enroll)(const hw_auth_token_t* hat, uint32_t gid, uint32_t timeout_sec); |
||||
int (*ss_fingerprint_post_enroll)(); |
||||
uint64_t (*ss_fingerprint_get_auth_id)(); |
||||
int (*ss_fingerprint_cancel)(); |
||||
int (*ss_fingerprint_enumerate)(); |
||||
int (*ss_fingerprint_remove)(uint32_t gid, uint32_t fid); |
||||
int (*ss_fingerprint_set_active_group)(uint32_t gid, const char* store_path); |
||||
int (*ss_fingerprint_authenticate)(uint64_t operation_id, uint32_t gid); |
||||
int (*ss_fingerprint_request)(int32_t cmd_id, const int8_t* inputBuf, uint32_t value, int8_t* outBuf, uint32_t len, uint32_t inParam); |
||||
|
||||
static void requestResult(int retval, const hidl_vec<int8_t>& outBuf); |
||||
std::string mPreviousBrightness; |
||||
|
||||
}; |
||||
|
||||
} // namespace implementation
|
||||
} // namespace V3_0
|
||||
} // namespace fingerprint
|
||||
} // namespace biometrics
|
||||
} // namespace hardware
|
||||
} // namespace samsung
|
||||
} // namespace vendor
|
||||
|
||||
#endif // ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_3_BIOMETRICSFINGERPRINT_H
|
@ -1,51 +0,0 @@ |
||||
/*
|
||||
* Copyright (C) 2019 The LineageOS Project |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#define LOG_TAG "vendor.samsung.hardware.biometrics.fingerprint@3.0-service.sm7125" |
||||
|
||||
#include <android-base/logging.h> |
||||
#include <hidl/HidlTransportSupport.h> |
||||
#include <utils/Errors.h> |
||||
|
||||
#include "BiometricsFingerprint.h" |
||||
|
||||
using android::hardware::configureRpcThreadpool; |
||||
using android::hardware::joinRpcThreadpool; |
||||
|
||||
using vendor::samsung::hardware::biometrics::fingerprint::V3_0::ISehBiometricsFingerprint; |
||||
using vendor::samsung::hardware::biometrics::fingerprint::V3_0::implementation::SehBiometricsFingerprint; |
||||
|
||||
using android::OK; |
||||
using android::sp; |
||||
|
||||
int main() { |
||||
android::sp<ISehBiometricsFingerprint> bio = SehBiometricsFingerprint::getInstance(); |
||||
|
||||
configureRpcThreadpool(1, true); |
||||
|
||||
if (bio == nullptr || bio->registerAsService() != OK) { |
||||
LOG(ERROR) << "Could not register service for Fingerprint HAL"; |
||||
goto shutdown; |
||||
} |
||||
|
||||
LOG(INFO) << "Fingerprint HAL service is Ready."; |
||||
joinRpcThreadpool(); |
||||
|
||||
shutdown: |
||||
// In normal operation, we don't expect the thread pool to shutdown
|
||||
LOG(ERROR) << "Fingerprint HAL failed to join thread pool."; |
||||
return 1; |
||||
} |
@ -1,7 +0,0 @@ |
||||
service vendor.fps_hal /vendor/bin/hw/vendor.samsung.hardware.biometrics.fingerprint@3.0-service.sm7125 |
||||
# "class hal" causes a race condition on some devices due to files created |
||||
# in /data. As a workaround, postpone startup until later in boot once |
||||
# /data is mounted. |
||||
class late_start |
||||
user system |
||||
group system input |
@ -1,22 +0,0 @@ |
||||
<manifest version="1.0" type="device"> |
||||
<hal format="hidl" override="true"> |
||||
<name>android.hardware.biometrics.fingerprint</name> |
||||
<transport>hwbinder</transport> |
||||
<version>2.3</version> |
||||
<interface> |
||||
<name>IBiometricsFingerprint</name> |
||||
<instance>default</instance> |
||||
</interface> |
||||
<fqname>@2.3::IBiometricsFingerprint/default</fqname> |
||||
</hal> |
||||
<hal format="hidl" override="true"> |
||||
<name>vendor.samsung.hardware.biometrics.fingerprint</name> |
||||
<transport>hwbinder</transport> |
||||
<version>3.0</version> |
||||
<interface> |
||||
<name>ISehBiometricsFingerprint</name> |
||||
<instance>default</instance> |
||||
</interface> |
||||
<fqname>@3.0::ISehBiometricsFingerprint/default</fqname> |
||||
</hal> |
||||
</manifest> |
@ -1,4 +0,0 @@ |
||||
hidl_package_root { |
||||
name: "vendor.samsung.hardware", |
||||
path: "device/samsung/sm7125-common/interfaces", |
||||
} |
@ -1,16 +0,0 @@ |
||||
// This file is autogenerated by hidl-gen -Landroidbp. |
||||
|
||||
hidl_interface { |
||||
name: "vendor.samsung.hardware.biometrics.fingerprint@3.0", |
||||
root: "vendor.samsung.hardware", |
||||
srcs: [ |
||||
"ISehBiometricsFingerprint.hal", |
||||
], |
||||
interfaces: [ |
||||
"android.hardware.biometrics.fingerprint@2.1", |
||||
"android.hardware.biometrics.fingerprint@2.2", |
||||
"android.hardware.biometrics.fingerprint@2.3", |
||||
"android.hidl.base@1.0", |
||||
], |
||||
gen_java: true, |
||||
} |
@ -1,7 +0,0 @@ |
||||
package vendor.samsung.hardware.biometrics.fingerprint@3.0; |
||||
|
||||
import android.hardware.biometrics.fingerprint@2.3::IBiometricsFingerprint; |
||||
|
||||
interface ISehBiometricsFingerprint extends android.hardware.biometrics.fingerprint@2.3::IBiometricsFingerprint { |
||||
sehRequest(int32_t cmdId, int32_t inParam, vec<int8_t> inBuf) generates (int32_t retval, vec<int8_t> outBuf); |
||||
}; |
@ -0,0 +1,77 @@ |
||||
/*
|
||||
* Copyright (C) 2019 The LineageOS Project |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#include <android-base/file.h> |
||||
#include <android-base/strings.h> |
||||
|
||||
#include <fstream> |
||||
|
||||
#include "DisplayColorCalibration.h" |
||||
|
||||
using android::base::ReadFileToString; |
||||
using android::base::Split; |
||||
using android::base::Trim; |
||||
using android::base::WriteStringToFile; |
||||
|
||||
namespace vendor { |
||||
namespace lineage { |
||||
namespace livedisplay { |
||||
namespace V2_0 { |
||||
namespace samsung { |
||||
|
||||
static constexpr const char* kColorPath = "/sys/class/mdnie/mdnie/sensorRGB"; |
||||
|
||||
bool DisplayColorCalibration::isSupported() { |
||||
std::fstream rgb(kColorPath, rgb.in | rgb.out); |
||||
return rgb.good(); |
||||
} |
||||
|
||||
Return<int32_t> DisplayColorCalibration::getMaxValue() { |
||||
return 255; |
||||
} |
||||
|
||||
Return<int32_t> DisplayColorCalibration::getMinValue() { |
||||
return 1; |
||||
} |
||||
|
||||
Return<void> DisplayColorCalibration::getCalibration(getCalibration_cb resultCb) { |
||||
std::vector<int32_t> rgb; |
||||
std::string tmp; |
||||
|
||||
if (ReadFileToString(kColorPath, &tmp)) { |
||||
std::vector<std::string> colors = Split(Trim(tmp), " "); |
||||
for (const std::string& color : colors) { |
||||
rgb.push_back(std::stoi(color)); |
||||
} |
||||
} |
||||
|
||||
resultCb(rgb); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<bool> DisplayColorCalibration::setCalibration(const hidl_vec<int32_t>& rgb) { |
||||
std::string contents; |
||||
for (const int32_t& color : rgb) { |
||||
contents += std::to_string(color) + " "; |
||||
} |
||||
return WriteStringToFile(Trim(contents), kColorPath, true); |
||||
} |
||||
|
||||
} // namespace samsung
|
||||
} // namespace V2_0
|
||||
} // namespace livedisplay
|
||||
} // namespace lineage
|
||||
} // namespace vendor
|
@ -1,136 +0,0 @@ |
||||
/*
|
||||
* Copyright (C) 2019 The LineageOS Project |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#define LOG_TAG "DisplayModesService" |
||||
|
||||
#include "DisplayModes.h" |
||||
#include <android-base/logging.h> |
||||
#include <fstream> |
||||
|
||||
namespace vendor { |
||||
namespace lineage { |
||||
namespace livedisplay { |
||||
namespace V2_0 { |
||||
namespace samsung { |
||||
|
||||
static constexpr const char* kModePath = "/sys/class/mdnie/mdnie/mode"; |
||||
static constexpr const char* kModeMaxPath = "/sys/class/mdnie/mdnie/mode_max"; |
||||
#ifdef LIVES_IN_SYSTEM |
||||
static constexpr const char* kDefaultPath = "/data/misc/display/.displaymodedefault"; |
||||
#else |
||||
static constexpr const char* kDefaultPath = "/data/vendor/display/.displaymodedefault"; |
||||
#endif |
||||
|
||||
const std::map<int32_t, std::string> DisplayModes::kModeMap = { |
||||
// clang-format off
|
||||
{2, "Natural"}, |
||||
{4, "Vivid"}, |
||||
// clang-format on
|
||||
}; |
||||
|
||||
DisplayModes::DisplayModes() : mDefaultModeId(4) { |
||||
std::ifstream defaultFile(kDefaultPath); |
||||
int value; |
||||
|
||||
defaultFile >> value; |
||||
LOG(DEBUG) << "Default file read result " << value << " fail " << defaultFile.fail(); |
||||
if (defaultFile.fail()) { |
||||
return; |
||||
} |
||||
|
||||
for (const auto& entry : kModeMap) { |
||||
if (value == entry.first) { |
||||
mDefaultModeId = entry.first; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
setDisplayMode(mDefaultModeId, false); |
||||
} |
||||
|
||||
bool DisplayModes::isSupported() { |
||||
std::ofstream modeFile(kModePath); |
||||
return modeFile.good(); |
||||
} |
||||
|
||||
// Methods from ::vendor::lineage::livedisplay::V2_0::IDisplayModes follow.
|
||||
Return<void> DisplayModes::getDisplayModes(getDisplayModes_cb resultCb) { |
||||
std::ifstream maxModeFile(kModeMaxPath); |
||||
int value; |
||||
std::vector<DisplayMode> modes; |
||||
if (!maxModeFile.fail()) { |
||||
maxModeFile >> value; |
||||
} else { |
||||
value = kModeMap.size(); |
||||
} |
||||
for (const auto& entry : kModeMap) { |
||||
if (entry.first < value) modes.push_back({entry.first, entry.second}); |
||||
} |
||||
resultCb(modes); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<void> DisplayModes::getCurrentDisplayMode(getCurrentDisplayMode_cb resultCb) { |
||||
int32_t currentModeId = mDefaultModeId; |
||||
std::ifstream modeFile(kModePath); |
||||
int value; |
||||
modeFile >> value; |
||||
if (!modeFile.fail()) { |
||||
for (const auto& entry : kModeMap) { |
||||
if (value == entry.first) { |
||||
currentModeId = entry.first; |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
resultCb({currentModeId, kModeMap.at(currentModeId)}); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<void> DisplayModes::getDefaultDisplayMode(getDefaultDisplayMode_cb resultCb) { |
||||
resultCb({mDefaultModeId, kModeMap.at(mDefaultModeId)}); |
||||
return Void(); |
||||
} |
||||
|
||||
Return<bool> DisplayModes::setDisplayMode(int32_t modeID, bool makeDefault) { |
||||
const auto iter = kModeMap.find(modeID); |
||||
if (iter == kModeMap.end()) { |
||||
return false; |
||||
} |
||||
std::ofstream modeFile(kModePath); |
||||
modeFile << iter->first; |
||||
if (modeFile.fail()) { |
||||
return false; |
||||
} |
||||
|
||||
if (makeDefault) { |
||||
std::ofstream defaultFile(kDefaultPath); |
||||
defaultFile << iter->first; |
||||
if (defaultFile.fail()) { |
||||
return false; |
||||
} |
||||
mDefaultModeId = iter->first; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
// Methods from ::android::hidl::base::V1_0::IBase follow.
|
||||
|
||||
} // namespace samsung
|
||||
} // namespace V2_0
|
||||
} // namespace livedisplay
|
||||
} // namespace lineage
|
||||
} // namespace vendor
|
@ -0,0 +1,29 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<!-- |
||||
/* |
||||
** Copyright (C) 2023 The LineageOS Project |
||||
** |
||||
** Licensed under the Apache License, Version 2.0 (the "License"); |
||||
** you may not use this file except in compliance with the License. |
||||
** You may obtain a copy of the License at |
||||
** |
||||
** http://www.apache.org/licenses/LICENSE-2.0 |
||||
** |
||||
** Unless required by applicable law or agreed to in writing, software |
||||
** distributed under the License is distributed on an "AS IS" BASIS, |
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
** See the License for the specific language governing permissions and |
||||
** limitations under the License. |
||||
*/ |
||||
--> |
||||
<resources> |
||||
|
||||
<!-- Bottom margin size when fingerprint in display is active --> |
||||
<dimen name="keyguard_indication_margin_bottom">20dp</dimen> |
||||
|
||||
<!-- Location on the screen of the center of the physical power button. This is a reasonable |
||||
default that should be overridden by device-specific overlays. --> |
||||
<dimen name="physical_power_button_center_screen_location_y">980px</dimen> |
||||
|
||||
</resources> |
||||
|
@ -0,0 +1,48 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<!-- |
||||
Copyright (C) 2012-2014 The CyanogenMod Project |
||||
Copyright (C) 2018 The LineageOS Project |
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
||||
--> |
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> |
||||
<string-array name="mdnie_scenario_entries" translatable="false"> |
||||
<item>LineageOS (default)</item> |
||||
<item>Video</item> |
||||
<item>Video warm</item> |
||||
<item>Video cold</item> |
||||
<item>Camera</item> |
||||
<item>Navigation</item> |
||||
<item>Gallery</item> |
||||
<item>Video call</item> |
||||
<item>Browser</item> |
||||
<item>eBook</item> |
||||
<item>E-mail</item> |
||||
<item>Digital television</item> |
||||
</string-array> |
||||
|
||||
<string-array name="mdnie_scenario_entries_values" translatable="false"> |
||||
<item>0</item> |
||||
<item>1</item> |
||||
<item>2</item> |
||||
<item>3</item> |
||||
<item>4</item> |
||||
<item>5</item> |
||||
<item>6</item> |
||||
<item>7</item> |
||||
<item>8</item> |
||||
<item>9</item> |
||||
<item>10</item> |
||||
<item>16</item> |
||||
</string-array> |
||||
</resources> |
@ -0,0 +1,5 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<resources> |
||||
<!-- Enable auxiliary cameras selector. --> |
||||
<bool name="config_enableAuxCameras">true</bool> |
||||
</resources> |
@ -1,18 +0,0 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<!-- Copyright (C) 2009-2012 Broadcom Corporation |
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
||||
--> |
||||
<resources> |
||||
<!-- If true, SCO sample rate will be reported via g_sco_samplerate audio parameter --> |
||||
<bool name="sco_report_samplerate">true</bool> |
||||
</resources> |
@ -0,0 +1,18 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- |
||||
Copyright (C) 2021 The LineageOS Project |
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
http://www.apache.org/licenses/LICENSE-2.0 |
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
||||
--> |
||||
<resources> |
||||
<bool name="call_recording_enabled">true</bool> |
||||
<integer name="call_recording_audio_source">4</integer> |
||||
</resources> |
||||
|
@ -0,0 +1,23 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
|
||||
<!-- Copyright (c) 2021 The LineageOS Project |
||||
This program is free software; you can redistribute it and/or |
||||
modify it under the terms of the GNU General Public License |
||||
as published by the Free Software Foundation; either version 2 |
||||
of the License, or (at your option) any later version. |
||||
This program is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
You should have received a copy of the GNU General Public License |
||||
along with this program; if not, write to the Free Software |
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
Also add information on how to contact you by electronic and paper mail. |
||||
--> |
||||
|
||||
<resources> |
||||
<!-- override full colour to black --> |
||||
<color name="full_bat_bg">#000000</color> |
||||
<color name="low_bat_bg">#000000</color> |
||||
<color name="charge_bat_bg">#000000</color> |
||||
</resources> |
@ -0,0 +1,28 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
|
||||
<!-- Copyright (c) 2022 The LineageOS Project |
||||
This program is free software; you can redistribute it and/or |
||||
modify it under the terms of the GNU General Public License |
||||
as published by the Free Software Foundation; either version 2 |
||||
of the License, or (at your option) any later version. |
||||
This program is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
You should have received a copy of the GNU General Public License |
||||
along with this program; if not, write to the Free Software |
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
Also add information on how to contact you by electronic and paper mail. |
||||
--> |
||||
|
||||
<resources> |
||||
<!-- Define Device Lid Style |
||||
|
||||
1 HTC/Xiaomi Style Dotcase |
||||
2 Asus/LG Style Circle Window Cover |
||||
3 Rectangular window Cover |
||||
4 Iceview style case where the entire screen is visible |
||||
|
||||
For example, a device with Asus Circle Cover would set 2 --> |
||||
<integer name="config_deviceCoverType">3</integer> |
||||
</resources> |
@ -0,0 +1,24 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
|
||||
<!-- Copyright (c) 2017 The LineageOS Project |
||||
This program is free software; you can redistribute it and/or |
||||
modify it under the terms of the GNU General Public License |
||||
as published by the Free Software Foundation; either version 2 |
||||
of the License, or (at your option) any later version. |
||||
This program is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
You should have received a copy of the GNU General Public License |
||||
along with this program; if not, write to the Free Software |
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
Also add information on how to contact you by electronic and paper mail. |
||||
--> |
||||
|
||||
<resources> |
||||
<!-- Rectangular parameters (config_deviceCoverType == 3) --> |
||||
<dimen name="rectangular_window_top">0px</dimen> |
||||
<dimen name="rectangular_window_left">0px</dimen> |
||||
<dimen name="rectangular_window_width">1080px</dimen> |
||||
<dimen name="rectangular_window_height">400px</dimen> |
||||
</resources> |
@ -0,0 +1,26 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<!-- Copyright (C) 2016 The CyanogenMod Project |
||||
(C) 2022 The LineageOS Project |
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
||||
--> |
||||
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> |
||||
|
||||
<!-- Default action ids for a device's touchscreen gestures |
||||
The array should be sorted in the same order as the |
||||
touchscreen gestures advertised by the device's LineageHW impl. --> |
||||
<integer-array name="config_defaultTouchscreenGestureActions" > |
||||
<item>12</item> |
||||
</integer-array> |
||||
</resources> |
@ -0,0 +1,28 @@ |
||||
// |
||||
// Copyright (C) 2022 The LineageOS Project |
||||
// |
||||
// Licensed under the Apache License, Version 2.0 (the "License"); |
||||
// you may not use this file except in compliance with the License. |
||||
// You may obtain a copy of the License at |
||||
// |
||||
// http://www.apache.org/licenses/LICENSE-2.0 |
||||
// |
||||
// Unless required by applicable law or agreed to in writing, software |
||||
// distributed under the License is distributed on an "AS IS" BASIS, |
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
// See the License for the specific language governing permissions and |
||||
// limitations under the License. |
||||
// |
||||
|
||||
cc_library_static { |
||||
name: "librecovery_updater_samsung_sm7125", |
||||
srcs: [ |
||||
"recovery_updater.cpp", |
||||
], |
||||
include_dirs: [ |
||||
"system/libbase/include", |
||||
"bootable/recovery", |
||||
"bootable/recovery/edify/include", |
||||
"bootable/recovery/otautil/include" |
||||
], |
||||
} |
@ -0,0 +1,51 @@ |
||||
/*
|
||||
* Copyright (C) 2022, The LineageOS Project |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
#include <android-base/properties.h> |
||||
|
||||
#include "edify/expr.h" |
||||
#include "otautil/error_code.h" |
||||
|
||||
Value *VerifyBootloader(const char *name, State *state, |
||||
const std::vector<std::unique_ptr<Expr>> &argv) { |
||||
int ret = 0; |
||||
std::string bootloader = android::base::GetProperty("ro.boot.bootloader", ""); |
||||
if (bootloader.empty()) { |
||||
return ErrorAbort(state, kFileGetPropFailure, |
||||
"%s() failed to read current bootloader version", name); |
||||
} |
||||
|
||||
std::string min_supported_bootloader_arg; |
||||
if (argv.empty() || !Evaluate(state, argv[0], &min_supported_bootloader_arg)) { |
||||
return ErrorAbort(state, kArgsParsingFailure, |
||||
"%s() error parsing arguments", name); |
||||
} |
||||
int min_supported_bootloader = int(min_supported_bootloader_arg[0]); |
||||
|
||||
int version = 0; |
||||
if (bootloader.length() >= 4) |
||||
version = int(bootloader[bootloader.length() - 4]); |
||||
|
||||
if (version >= min_supported_bootloader) { |
||||
ret = 1; |
||||
} |
||||
|
||||
return StringValue(std::to_string(ret)); |
||||
} |
||||
|
||||
void Register_librecovery_updater_samsung_sm7125() { |
||||
RegisterFunction("samsung_sm7125.verify_bootloader_min", VerifyBootloader); |
||||
} |
@ -0,0 +1,61 @@ |
||||
# Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. |
||||
# |
||||
# Redistribution and use in source and binary forms, with or without |
||||
# modification, are permitted provided that the following conditions are |
||||
# met: |
||||
# * Redistributions of source code must retain the above copyright |
||||
# notice, this list of conditions and the following disclaimer. |
||||
# * Redistributions in binary form must reproduce the above |
||||
# copyright notice, this list of conditions and the following |
||||
# disclaimer in the documentation and/or other materials provided |
||||
# with the distribution. |
||||
# * Neither the name of The Linux Foundation nor the names of its |
||||
# contributors may be used to endorse or promote products derived |
||||
# from this software without specific prior written permission. |
||||
# |
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED |
||||
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT |
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS |
||||
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
||||
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
||||
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |
||||
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
# Android fstab file. |
||||
# The filesystem that contains the filesystem checker binary (typically /system) cannot |
||||
# specify MF_CHECK, and must come before any filesystems that do specify MF_CHECK |
||||
|
||||
#TODO: Add 'check' as fs_mgr_flags with data partition. |
||||
# Currently we dont have e2fsck compiled. So fs check would failed. |
||||
|
||||
#<src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags> |
||||
system /system ext4 ro wait,logical,first_stage_mount |
||||
system /system f2fs ro wait,logical,first_stage_mount |
||||
product /product ext4 ro wait,logical,first_stage_mount |
||||
vendor /vendor ext4 ro wait,logical,first_stage_mount |
||||
odm /odm ext4 ro wait,logical,first_stage_mount |
||||
/dev/block/bootdevice/by-name/boot /boot emmc defaults defaults |
||||
/dev/block/bootdevice/by-name/recovery /recovery emmc defaults defaults |
||||
/dev/block/bootdevice/by-name/cache /cache ext4 noatime,nosuid,nodev,noauto_da_alloc,discard,journal_checksum,data=ordered,errors=panic wait,check |
||||
/dev/block/by-name/metadata /metadata ext4 noatime,nosuid,nodev,noauto_da_alloc,discard,journal_checksum,data=ordered,errors=panic,sync wait,formattable,first_stage_mount,check |
||||
# Add fs_mgr flag - sysfs_path=/sys/devices/platform/soc/xxxx.[ufshc|sdhci] to userdata entry, based on UFS|eMMC device. |
||||
/dev/block/bootdevice/by-name/userdata /data f2fs noatime,nosuid,nodev,discard,usrquota,grpquota,fsync_mode=nobarrier,reserve_root=32768,resgid=5678,inlinecrypt latemount,wait,check,fileencryption=aes-256-xts:aes-256-cts:v2+inlinecrypt_optimized,quota,reservedsize=128M,checkpoint=fs |
||||
/dev/block/bootdevice/by-name/apnhlos /vendor/firmware_mnt vfat ro,shortname=lower,uid=0,gid=1000,dmask=227,fmask=337,context=u:object_r:firmware_file:s0 wait |
||||
/dev/block/bootdevice/by-name/modem /vendor/firmware-modem vfat ro,shortname=lower,uid=0,gid=1000,dmask=227,fmask=337,context=u:object_r:firmware_file:s0 wait |
||||
/dev/block/bootdevice/by-name/efs /mnt/vendor/efs ext4 noatime,nosuid,nodev,noauto_da_alloc,discard,journal_checksum,data=ordered,errors=panic wait,check |
||||
/dev/block/bootdevice/by-name/sec_efs /efs ext4 noatime,nosuid,nodev,noauto_da_alloc,discard,journal_checksum,data=ordered,errors=panic wait,check |
||||
/dev/block/bootdevice/by-name/dsp /vendor/dsp ext4 ro,nosuid,nodev,barrier=1 wait |
||||
/dev/block/bootdevice/by-name/persist /mnt/vendor/persist ext4 noatime,nosuid,nodev,noauto_da_alloc,discard,journal_checksum,data=ordered,errors=panic wait,check |
||||
|
||||
# Need to have this entry in here even though the mount point itself is no longer needed. |
||||
# The update_engine code looks for this entry in order to determine the boot device address |
||||
# and fails if it does not find it. |
||||
/dev/block/bootdevice/by-name/misc /misc emmc defaults defaults,first_stage_mount |
||||
|
||||
# VOLD:samsung/common_sm7125/fstab_dynamic_partition.samsung |
||||
/devices/platform/soc/8804000.sdhci/mmc_host* auto auto defaults wait,voldmanaged=sdcard:auto,encryptable=userdata |
||||
/devices/platform/soc/a600000.ssusb/a600000.dwc3/xhci-hcd.0.auto* auto auto defaults voldmanaged=usb:auto |
@ -0,0 +1,53 @@ |
||||
#!/bin/env python3 |
||||
# |
||||
# Copyright (C) 2021 The LineageOS Project |
||||
# |
||||
# Licensed under the Apache License, Version 2.0 (the "License"); |
||||
# you may not use this file except in compliance with the License. |
||||
# You may obtain a copy of the License at |
||||
# |
||||
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
# |
||||
# Unless required by applicable law or agreed to in writing, software |
||||
# distributed under the License is distributed on an "AS IS" BASIS, |
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
# See the License for the specific language governing permissions and |
||||
# limitations under the License. |
||||
|
||||
import common |
||||
import re |
||||
|
||||
def FullOTA_Assertions(info): |
||||
OTA_Assertions(info) |
||||
return |
||||
|
||||
def FullOTA_InstallEnd(info): |
||||
OTA_InstallEnd(info) |
||||
return |
||||
|
||||
def IncrementalOTA_Assertions(info): |
||||
OTA_Assertions(info) |
||||
return |
||||
|
||||
def IncrementalOTA_InstallEnd(info): |
||||
OTA_InstallEnd(info) |
||||
return |
||||
|
||||
def OTA_Assertions(info): |
||||
android_info = info.input_zip.read("OTA/android-info.txt") |
||||
m = re.search(r'require\s+version-bootloader-min\s*=\s*(\S+)', android_info.decode('utf-8')) |
||||
if m: |
||||
bootloader_version = m.group(1) |
||||
cmd = ('assert(samsung_sm7125.verify_bootloader_min("{}") == "1" || abort("ERROR: This package requires Android 13 based firmware. Please upgrade firmware and retry!"););').format(bootloader_version) |
||||
info.script.AppendExtra(cmd) |
||||
return |
||||
|
||||
def AddImage(info, basename, dest): |
||||
data = info.input_zip.read("IMAGES/" + basename) |
||||
common.ZipWriteStr(info.output_zip, basename, data) |
||||
info.script.Print("Patching {} image unconditionally...".format(dest.split('/')[-1])) |
||||
info.script.AppendExtra('package_extract_file("%s", "%s");' % (basename, dest)) |
||||
|
||||
def OTA_InstallEnd(info): |
||||
AddImage(info, "dtbo.img", "/dev/block/by-name/dtbo") |
||||
return |
@ -0,0 +1,518 @@ |
||||
#! /vendor/bin/sh |
||||
|
||||
# Copyright (c) 2012-2013,2016,2018-2020 The Linux Foundation. All rights reserved. |
||||
# |
||||
# Redistribution and use in source and binary forms, with or without |
||||
# modification, are permitted provided that the following conditions are met: |
||||
# * Redistributions of source code must retain the above copyright |
||||
# notice, this list of conditions and the following disclaimer. |
||||
# * Redistributions in binary form must reproduce the above copyright |
||||
# notice, this list of conditions and the following disclaimer in the |
||||
# documentation and/or other materials provided with the distribution. |
||||
# * Neither the name of The Linux Foundation nor |
||||
# the names of its contributors may be used to endorse or promote |
||||
# products derived from this software without specific prior written |
||||
# permission. |
||||
# |
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||||
# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
||||
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
# |
||||
|
||||
export PATH=/vendor/bin |
||||
|
||||
# Set platform variables |
||||
if [ -f /sys/devices/soc0/hw_platform ]; then |
||||
soc_hwplatform=`cat /sys/devices/soc0/hw_platform` 2> /dev/null |
||||
else |
||||
soc_hwplatform=`cat /sys/devices/system/soc/soc0/hw_platform` 2> /dev/null |
||||
fi |
||||
if [ -f /sys/devices/soc0/soc_id ]; then |
||||
soc_hwid=`cat /sys/devices/soc0/soc_id` 2> /dev/null |
||||
else |
||||
soc_hwid=`cat /sys/devices/system/soc/soc0/id` 2> /dev/null |
||||
fi |
||||
if [ -f /sys/devices/soc0/platform_version ]; then |
||||
soc_hwver=`cat /sys/devices/soc0/platform_version` 2> /dev/null |
||||
else |
||||
soc_hwver=`cat /sys/devices/system/soc/soc0/platform_version` 2> /dev/null |
||||
fi |
||||
|
||||
if [ -f /sys/class/drm/card0-DSI-1/modes ]; then |
||||
echo "detect" > /sys/class/drm/card0-DSI-1/status |
||||
mode_file=/sys/class/drm/card0-DSI-1/modes |
||||
while read line; do |
||||
fb_width=${line%%x*}; |
||||
break; |
||||
done < $mode_file |
||||
elif [ -f /sys/class/graphics/fb0/virtual_size ]; then |
||||
res=`cat /sys/class/graphics/fb0/virtual_size` 2> /dev/null |
||||
fb_width=${res%,*} |
||||
fi |
||||
|
||||
log -t BOOT -p i "MSM target '$1', SoC '$soc_hwplatform', HwID '$soc_hwid', SoC ver '$soc_hwver'" |
||||
|
||||
#For drm based display driver |
||||
vbfile=/sys/module/drm/parameters/vblankoffdelay |
||||
if [ -w $vbfile ]; then |
||||
echo -1 > $vbfile |
||||
else |
||||
log -t DRM_BOOT -p w "file: '$vbfile' or perms doesn't exist" |
||||
fi |
||||
|
||||
function set_density_by_fb() { |
||||
#put default density based on width |
||||
if [ -z $fb_width ]; then |
||||
setprop vendor.display.lcd_density 320 |
||||
else |
||||
if [ $fb_width -ge 1600 ]; then |
||||
setprop vendor.display.lcd_density 640 |
||||
elif [ $fb_width -ge 1440 ]; then |
||||
setprop vendor.display.lcd_density 560 |
||||
elif [ $fb_width -ge 1080 ]; then |
||||
setprop vendor.display.lcd_density 480 |
||||
elif [ $fb_width -ge 720 ]; then |
||||
setprop vendor.display.lcd_density 320 #for 720X1280 resolution |
||||
elif [ $fb_width -ge 480 ]; then |
||||
setprop vendor.display.lcd_density 240 #for 480X854 QRD resolution |
||||
else |
||||
setprop vendor.display.lcd_density 160 |
||||
fi |
||||
fi |
||||
} |
||||
|
||||
target=`getprop ro.board.platform` |
||||
case "$target" in |
||||
"msm7630_surf" | "msm7630_1x" | "msm7630_fusion") |
||||
case "$soc_hwplatform" in |
||||
"FFA" | "SVLTE_FFA") |
||||
# linking to surf_keypad_qwerty.kcm.bin instead of surf_keypad_numeric.kcm.bin so that |
||||
# the UI keyboard works fine. |
||||
ln -s /system/usr/keychars/surf_keypad_qwerty.kcm.bin /system/usr/keychars/surf_keypad.kcm.bin |
||||
;; |
||||
"Fluid") |
||||
setprop vendor.display.lcd_density 240 |
||||
setprop qcom.bt.dev_power_class 2 |
||||
;; |
||||
*) |
||||
ln -s /system/usr/keychars/surf_keypad_qwerty.kcm.bin /system/usr/keychars/surf_keypad.kcm.bin |
||||
;; |
||||
esac |
||||
;; |
||||
"sm6150") |
||||
case "$soc_hwplatform" in |
||||
"ADP") |
||||
setprop vendor.display.lcd_density 160 |
||||
;; |
||||
esac |
||||
case "$soc_hwid" in |
||||
365|366) |
||||
sku_ver=`cat /sys/devices/platform/soc/aa00000.qcom,vidc1/sku_version` 2> /dev/null |
||||
setprop vendor.media.target.version 1 |
||||
if [ $sku_ver -eq 1 ]; then |
||||
setprop vendor.media.target.version 2 |
||||
fi |
||||
;; |
||||
355|369|377|384) |
||||
setprop vendor.chre.enabled 0 |
||||
;; |
||||
*) |
||||
esac |
||||
;; |
||||
"msm8660") |
||||
case "$soc_hwplatform" in |
||||
"Fluid") |
||||
setprop vendor.display.lcd_density 240 |
||||
;; |
||||
"Dragon") |
||||
setprop ro.sound.alsa "WM8903" |
||||
;; |
||||
esac |
||||
;; |
||||
|
||||
"msm8960") |
||||
# lcd density is write-once. Hence the separate switch case |
||||
case "$soc_hwplatform" in |
||||
"Liquid") |
||||
if [ "$soc_hwver" == "196608" ]; then # version 0x30000 is 3D sku |
||||
setprop ro.sf.hwrotation 90 |
||||
fi |
||||
|
||||
setprop vendor.display.lcd_density 160 |
||||
;; |
||||
"MTP") |
||||
setprop vendor.display.lcd_density 240 |
||||
;; |
||||
*) |
||||
case "$soc_hwid" in |
||||
"109") |
||||
setprop vendor.display.lcd_density 160 |
||||
;; |
||||
*) |
||||
setprop vendor.display.lcd_density 240 |
||||
;; |
||||
esac |
||||
;; |
||||
esac |
||||
|
||||
#Set up composition type based on the target |
||||
case "$soc_hwid" in |
||||
87) |
||||
#8960 |
||||
setprop debug.composition.type dyn |
||||
;; |
||||
153|154|155|156|157|138) |
||||
#8064 V2 PRIME | 8930AB | 8630AB | 8230AB | 8030AB | 8960AB |
||||
setprop debug.composition.type c2d |
||||
;; |
||||
*) |
||||
esac |
||||
;; |
||||
|
||||
"msm8974") |
||||
case "$soc_hwplatform" in |
||||
"Liquid") |
||||
setprop vendor.display.lcd_density 160 |
||||
# Liquid do not have hardware navigation keys, so enable |
||||
# Android sw navigation bar |
||||
setprop ro.hw.nav_keys 0 |
||||
;; |
||||
"Dragon") |
||||
setprop vendor.display.lcd_density 240 |
||||
;; |
||||
*) |
||||
setprop vendor.display.lcd_density 320 |
||||
;; |
||||
esac |
||||
;; |
||||
|
||||
"msm8226") |
||||
case "$soc_hwplatform" in |
||||
*) |
||||
setprop vendor.display.lcd_density 320 |
||||
;; |
||||
esac |
||||
;; |
||||
|
||||
"msm8610" | "apq8084" | "mpq8092") |
||||
case "$soc_hwplatform" in |
||||
*) |
||||
setprop vendor.display.lcd_density 240 |
||||
;; |
||||
esac |
||||
;; |
||||
"apq8084") |
||||
case "$soc_hwplatform" in |
||||
"Liquid") |
||||
setprop vendor.display.lcd_density 320 |
||||
# Liquid do not have hardware navigation keys, so enable |
||||
# Android sw navigation bar |
||||
setprop ro.hw.nav_keys 0 |
||||
;; |
||||
"SBC") |
||||
setprop vendor.display.lcd_density 200 |
||||
# SBC do not have hardware navigation keys, so enable |
||||
# Android sw navigation bar |
||||
setprop qemu.hw.mainkeys 0 |
||||
;; |
||||
*) |
||||
setprop vendor.display.lcd_density 480 |
||||
;; |
||||
esac |
||||
;; |
||||
"msm8996") |
||||
case "$soc_hwplatform" in |
||||
"Dragon") |
||||
setprop vendor.display.lcd_density 240 |
||||
setprop qemu.hw.mainkeys 0 |
||||
;; |
||||
"ADP") |
||||
setprop vendor.display.lcd_density 160 |
||||
setprop qemu.hw.mainkeys 0 |
||||
;; |
||||
"SBC") |
||||
setprop vendor.display.lcd_density 240 |
||||
setprop qemu.hw.mainkeys 0 |
||||
;; |
||||
*) |
||||
setprop vendor.display.lcd_density 560 |
||||
;; |
||||
esac |
||||
;; |
||||
"msm8937" | "msm8940") |
||||
# Set vendor.opengles.version based on chip id. |
||||
# MSM8937 and MSM8940 variants supports OpenGLES 3.1 |
||||
# 196608 is decimal for 0x30000 to report version 3.0 |
||||
# 196609 is decimal for 0x30001 to report version 3.1 |
||||
# 196610 is decimal for 0x30002 to report version 3.2 |
||||
case "$soc_hwid" in |
||||
294|295|296|297|298|313|353|354|363|364) |
||||
setprop vendor.opengles.version 196610 |
||||
if [ $soc_hwid = 354 ] |
||||
then |
||||
setprop vendor.media.target.version 1 |
||||
log -t BOOT -p i "SDM429 early_boot prop set for: HwID '$soc_hwid'" |
||||
fi |
||||
;; |
||||
303|307|308|309|320) |
||||
# Vulkan is not supported for 8917 variants |
||||
setprop vendor.opengles.version 196608 |
||||
setprop persist.graphics.vulkan.disable true |
||||
;; |
||||
*) |
||||
setprop vendor.opengles.version 196608 |
||||
;; |
||||
esac |
||||
;; |
||||
"msm8909") |
||||
case "$soc_hwplatform" in |
||||
*) |
||||
setprop persist.graphics.vulkan.disable true |
||||
;; |
||||
esac |
||||
;; |
||||
"msm8998" | "apq8098_latv") |
||||
case "$soc_hwplatform" in |
||||
*) |
||||
setprop vendor.display.lcd_density 560 |
||||
;; |
||||
esac |
||||
;; |
||||
"sdm845") |
||||
case "$soc_hwplatform" in |
||||
*) |
||||
if [ $fb_width -le 1600 ]; then |
||||
setprop vendor.display.lcd_density 560 |
||||
else |
||||
setprop vendor.display.lcd_density 640 |
||||
fi |
||||
;; |
||||
esac |
||||
;; |
||||
"msmnile") |
||||
case "$soc_hwplatform" in |
||||
*) |
||||
if [ $fb_width -le 1600 ]; then |
||||
setprop vendor.display.lcd_density 560 |
||||
else |
||||
setprop vendor.display.lcd_density 640 |
||||
fi |
||||
;; |
||||
esac |
||||
;; |
||||
"kona") |
||||
case "$soc_hwplatform" in |
||||
*) |
||||
setprop vendor.media.target_variant "_kona" |
||||
if [ $fb_width -le 1600 ]; then |
||||
setprop vendor.display.lcd_density 560 |
||||
else |
||||
setprop vendor.display.lcd_density 640 |
||||
fi |
||||
;; |
||||
esac |
||||
;; |
||||
"lito") |
||||
case "$soc_hwid" in |
||||
400|440) |
||||
sku_ver=`cat /sys/devices/platform/soc/aa00000.qcom,vidc1/sku_version` 2> /dev/null |
||||
if [ $sku_ver -eq 1 ]; then |
||||
setprop vendor.media.target.version 1 |
||||
fi |
||||
;; |
||||
434|459) |
||||
sku_ver=`cat /sys/devices/platform/soc/aa00000.qcom,vidc1/sku_version` 2> /dev/null |
||||
setprop vendor.media.target.version 2 |
||||
if [ $sku_ver -eq 1 ]; then |
||||
setprop vendor.media.target.version 3 |
||||
fi |
||||
;; |
||||
esac |
||||
;; |
||||
"bengal") |
||||
case "$soc_hwid" in |
||||
441) |
||||
setprop vendor.fastrpc.disable.cdsprpcd.daemon 1 |
||||
setprop vendor.gralloc.disable_ubwc 1 |
||||
;; |
||||
471) |
||||
#scuba APQ |
||||
setprop vendor.gralloc.disable_ubwc 1 |
||||
;; |
||||
esac |
||||
;; |
||||
"sdm710" | "msmpeafowl") |
||||
case "$soc_hwplatform" in |
||||
*) |
||||
if [ $fb_width -le 1600 ]; then |
||||
setprop vendor.display.lcd_density 560 |
||||
else |
||||
setprop vendor.display.lcd_density 640 |
||||
fi |
||||
|
||||
sku_ver=`cat /sys/devices/platform/soc/aa00000.qcom,vidc1/sku_version` 2> /dev/null |
||||
if [ $sku_ver -eq 1 ]; then |
||||
setprop vendor.media.target.version 1 |
||||
fi |
||||
;; |
||||
esac |
||||
;; |
||||
"msm8953") |
||||
cap_ver = 1 |
||||
if [ -e "/sys/devices/platform/soc/1d00000.qcom,vidc/capability_version" ]; then |
||||
cap_ver=`cat /sys/devices/platform/soc/1d00000.qcom,vidc/capability_version` 2> /dev/null |
||||
else |
||||
cap_ver=`cat /sys/devices/soc/1d00000.qcom,vidc/capability_version` 2> /dev/null |
||||
fi |
||||
|
||||
if [ $cap_ver -eq 1 ]; then |
||||
setprop vendor.media.target.version 1 |
||||
fi |
||||
;; |
||||
#Set property to differentiate SDM660 & SDM455 |
||||
#SOC ID for SDM455 is 385 |
||||
"sdm660") |
||||
case "$soc_hwplatform" in |
||||
*) |
||||
if [ $fb_width -le 1600 ]; then |
||||
setprop vendor.display.lcd_density 560 |
||||
else |
||||
setprop vendor.display.lcd_density 640 |
||||
fi |
||||
|
||||
if [ $soc_hwid -eq 385 ]; then |
||||
setprop vendor.media.target.version 1 |
||||
fi |
||||
;; |
||||
esac |
||||
;; |
||||
"lahaina") |
||||
case "$soc_hwid" in |
||||
450) |
||||
setprop vendor.media.target_variant "_shima_v3" |
||||
sku_ver=`cat /sys/devices/platform/soc/aa00000.qcom,vidc/sku_version` 2> /dev/null |
||||
if [ $sku_ver -eq 1 ]; then |
||||
setprop vendor.media.target_variant "_shima_v1" |
||||
elif [ $sku_ver -eq 2 ]; then |
||||
setprop vendor.media.target_variant "_shima_v2" |
||||
fi |
||||
;; |
||||
*) |
||||
setprop vendor.media.target_variant "_lahaina" |
||||
;; |
||||
esac |
||||
;; |
||||
"holi") |
||||
setprop vendor.media.target_variant "_holi" |
||||
;; |
||||
esac |
||||
|
||||
baseband=`getprop ro.baseband` |
||||
#enable atfwd daemon all targets except sda, apq, qcs |
||||
case "$baseband" in |
||||
"apq" | "sda" | "qcs" ) |
||||
setprop persist.vendor.radio.atfwd.start false;; |
||||
*) |
||||
setprop persist.vendor.radio.atfwd.start true;; |
||||
esac |
||||
|
||||
#set default lcd density |
||||
#Since lcd density has read only |
||||
#property, it will not overwrite previous set |
||||
#property if any target is setting forcefully. |
||||
set_density_by_fb |
||||
|
||||
|
||||
# set Lilliput LCD density for ADP |
||||
product=`getprop ro.build.product` |
||||
|
||||
case "$product" in |
||||
"msmnile_au") |
||||
setprop vendor.display.lcd_density 160 |
||||
echo 902400000 > /sys/class/devfreq/soc:qcom,cpu0-cpu-l3-lat/min_freq |
||||
echo 1612800000 > /sys/class/devfreq/soc:qcom,cpu0-cpu-l3-lat/max_freq |
||||
echo 902400000 > /sys/class/devfreq/soc:qcom,cpu4-cpu-l3-lat/min_freq |
||||
echo 1612800000 > /sys/class/devfreq/soc:qcom,cpu4-cpu-l3-lat/max_freq |
||||
;; |
||||
*) |
||||
;; |
||||
esac |
||||
case "$product" in |
||||
"sm6150_au") |
||||
setprop vendor.display.lcd_density 160 |
||||
;; |
||||
*) |
||||
;; |
||||
esac |
||||
case "$product" in |
||||
"sdmshrike_au") |
||||
setprop vendor.display.lcd_density 160 |
||||
;; |
||||
*) |
||||
;; |
||||
esac |
||||
|
||||
case "$product" in |
||||
"msmnile_gvmq") |
||||
setprop vendor.display.lcd_density 160 |
||||
;; |
||||
*) |
||||
;; |
||||
esac |
||||
# Setup display nodes & permissions |
||||
# HDMI can be fb1 or fb2 |
||||
# Loop through the sysfs nodes and determine |
||||
# the HDMI(dtv panel) |
||||
|
||||
function set_perms() { |
||||
#Usage set_perms <filename> <ownership> <permission> |
||||
chown -h $2 $1 |
||||
chmod $3 $1 |
||||
} |
||||
|
||||
# check for the type of driver FB or DRM |
||||
fb_driver=/sys/class/graphics/fb0 |
||||
if [ -e "$fb_driver" ] |
||||
then |
||||
# check for mdp caps |
||||
file=/sys/class/graphics/fb0/mdp/caps |
||||
if [ -f "$file" ] |
||||
then |
||||
setprop vendor.gralloc.disable_ubwc 1 |
||||
cat $file | while read line; do |
||||
case "$line" in |
||||
*"ubwc"*) |
||||
setprop vendor.gralloc.enable_fb_ubwc 1 |
||||
setprop vendor.gralloc.disable_ubwc 0 |
||||
esac |
||||
done |
||||
fi |
||||
else |
||||
set_perms /sys/devices/virtual/hdcp/msm_hdcp/min_level_change system.graphics 0660 |
||||
fi |
||||
|
||||
# allow system_graphics group to access pmic secure_mode node |
||||
set_perms /sys/class/lcd_bias/secure_mode system.graphics 0660 |
||||
set_perms /sys/class/leds/wled/secure_mode system.graphics 0660 |
||||
|
||||
boot_reason=`cat /proc/sys/kernel/boot_reason` |
||||
reboot_reason=`getprop ro.boot.alarmboot` |
||||
if [ "$boot_reason" = "3" ] || [ "$reboot_reason" = "true" ]; then |
||||
setprop ro.vendor.alarm_boot true |
||||
else |
||||
setprop ro.vendor.alarm_boot false |
||||
fi |
||||
|
||||
# copy GPU frequencies to vendor property |
||||
if [ -f /sys/class/kgsl/kgsl-3d0/gpu_available_frequencies ]; then |
||||
gpu_freq=`cat /sys/class/kgsl/kgsl-3d0/gpu_available_frequencies` 2> /dev/null |
||||
setprop vendor.gpu.available_frequencies "$gpu_freq" |
||||
fi |
@ -1,48 +0,0 @@ |
||||
#! /vendor/bin/sh |
||||
|
||||
# |
||||
# Copyright (c) 2019-2020 Qualcomm Technologies, Inc. |
||||
# All Rights Reserved. |
||||
# Confidential and Proprietary - Qualcomm Technologies, Inc. |
||||
# |
||||
# Copyright (c) 2019 The Linux Foundation. All rights reserved. |
||||
# |
||||
|
||||
export PATH=/vendor/bin |
||||
|
||||
soc_id=`getprop ro.vendor.qti.soc_id` |
||||
if [ "$soc_id" -eq 415 ] || [ "$soc_id" -eq 439 ] || [ "$soc_id" -eq 450 ]; then |
||||
setprop persist.vendor.hvdcp_opti.start 2 |
||||
exit 0 |
||||
fi |
||||
|
||||
if [ "$soc_id" -eq 441 ] || [ "$soc_id" -eq 471 ]; then |
||||
#Scuba does not support usb-pd or charge pumps |
||||
find /sys/class/power_supply/battery/ -type f -maxdepth 1 | xargs chown system.system |
||||
find /sys/class/power_supply/bms/ -type f -maxdepth 1 | xargs chown system.system |
||||
find /sys/class/power_supply/main/ -type f -maxdepth 1 | xargs chown system.system |
||||
find /sys/class/power_supply/usb/ -type f -maxdepth 1 | xargs chown system.system |
||||
else |
||||
find /sys/class/power_supply/battery/ -type f -maxdepth 1 | xargs chown system.system |
||||
find /sys/class/power_supply/bms/ -type f -maxdepth 1 | xargs chown system.system |
||||
find /sys/class/power_supply/main/ -type f -maxdepth 1 | xargs chown system.system |
||||
find /sys/class/power_supply/usb/ -type f -maxdepth 1 | xargs chown system.system |
||||
find /sys/class/power_supply/charge_pump_master/ -type f -maxdepth 1 | xargs chown system.system |
||||
find /sys/class/power_supply/pc_port/ -type f -maxdepth 1 | xargs chown system.system |
||||
find /sys/class/power_supply/dc/ -type f -maxdepth 1 | xargs chown system.system |
||||
find /sys/class/power_supply/parallel/ -type f -maxdepth 1 | xargs chown system.system |
||||
find /sys/class/usbpd/usbpd0/ -type f -maxdepth 1 | xargs chown system.system |
||||
find /sys/class/qc-vdm/ -type f -maxdepth 1 | xargs chown system.system |
||||
find /sys/class/charge_pump/ -type f -maxdepth 1 | xargs chown system.system |
||||
find /sys/class/qcom-battery/ -type f -maxdepth 1 | xargs chown system.system |
||||
|
||||
for i in 0 1 2 3 4 5 6 7 8 9 |
||||
do |
||||
devname=`cat /sys/bus/iio/devices/iio:device$i/name` |
||||
if [[ "$devname" == *smb* ]] || [[ "$devname" == *qg* ]] || [[ "$devname" == *div2_cp* ]]; then |
||||
find /sys/bus/iio/devices/iio:device$i/ -type f -maxdepth 1 | xargs chown system.system |
||||
fi |
||||
done |
||||
fi |
||||
|
||||
setprop persist.vendor.hvdcp_opti.start 1 |
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue