Compare commits
184 Commits
Author | SHA1 | Date |
---|---|---|
Ruchit Marathe | 986937e5bf | 1 month 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 | 3 months ago |
Simon1511 | 690bd53e19 | 3 months ago |
Simon1511 | 445d3a0cf2 | 3 months ago |
Danny Baumann | 47732025b2 | 3 months ago |
Omkar Chandorkar | 4df4944c4b | 3 months ago |
Simon1511 | 584bfb3556 | 3 months ago |
Simon1511 | ad4ed687f7 | 4 months ago |
Simon1511 | b4602aea30 | 4 months ago |
Simon1511 | 06aca7e31b | 4 months ago |
Tim Zimmermann | 6526837b69 | 4 months ago |
Bruno Martins | 8a0da21487 | 4 months ago |
Bruno Martins | d799e2809f | 4 months ago |
Andy Hung | 5a7d061dca | 4 months ago |
LuK1337 | 26c9c2eab6 | 4 months ago |
LuK1337 | 45dfa77487 | 4 months ago |
LuK1337 | 4b915ce0da | 4 months ago |
Gabriel Biren | 98cce314c3 | 4 months ago |
Simon1511 | bde98b0bb8 | 5 months ago |
Simon1511 | d134d87a8b | 5 months ago |
Simon1511 | 65761014ad | 6 months ago |
Simon1511 | d15040a62a | 6 months ago |
Simon1511 | 30fc583a77 | 6 months ago |
Simon1511 | 64b507b1cf | 6 months ago |
Simon1511 | 93616b944c | 7 months ago |
Tim Zimmermann | f3fc0d615d | 7 months ago |
Ruchit | 66ba3b48ee | 7 months ago |
Ruchit | e1032754c4 | 7 months ago |
Simon1511 | 8798ac7cad | 7 months ago |
Simon1511 | bb83af7561 | 8 months ago |
Simon1511 | 4c38598d88 | 9 months ago |
Simon1511 | d9ac17a62e | 10 months ago |
Simon1511 | 5005f437cf | 10 months ago |
Simon1511 | 2a88cfa9ac | 10 months ago |
Simon1511 | 19005b2e9a | 10 months ago |
Tim Zimmermann | ea551ed57a | 10 months ago |
Alexander Martinz | f298f5b32d | 10 months ago |
Michael Bestas | 55bc3d36ea | 10 months ago |
Simon1511 | 220a5ee0bb | 12 months ago |
Simon1511 | f835fdde00 | 12 months ago |
Simon1511 | f2978af5cc | 12 months ago |
Simon1511 | 56257042ed | 12 months ago |
Bruno Martins | e6273e85a6 | 12 months ago |
Simon1511 | 2e4f5d511c | 12 months ago |
Tim Zimmermann | 62f0858f85 | 12 months ago |
Simon1511 | 5e735a2f3b | 12 months 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 | 1 year ago |
Simon1511 | 5d9f802e48 | 1 year ago |
LibXZR | f8e78c2fff | 1 year ago |
Simon1511 | 17125ac89d | 1 year ago |
Simon1511 | 96d068a98d | 1 year ago |
Simon1511 | 6906b52201 | 1 year ago |
Tim Zimmermann | f314d075f9 | 1 year ago |
Simon1511 | ef2932e0c8 | 1 year ago |
johnmart19 | abdd49f532 | 1 year ago |
Ruchit Marathe | 603a606f4c | 1 year ago |
LuK1337 | c5d4085e36 | 1 year ago |
LuK1337 | 07120f399f | 1 year ago |
Danny Lin | 25ea01056f | 1 year ago |
Simon1511 | da8a1faa28 | 1 year ago |
Simon1511 | c240c60951 | 1 year 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,165 @@ |
||||
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", |
||||
], |
||||
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", |
||||
], |
||||
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", |
||||
], |
||||
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", |
||||
], |
||||
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", |
||||
], |
||||
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", |
||||
], |
||||
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,355 @@ |
||||
/*
|
||||
* 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" |
||||
|
||||
#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) { |
||||
// 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,203 @@ |
||||
/*
|
||||
* 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; } |
||||
|
||||
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; |
||||
int halSetParameters(const char* keysAndValues) 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,30 @@ |
||||
// |
||||
// Copyright (C) 2023 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. |
||||
|
||||
cc_binary { |
||||
name: "audio_parameter_service.samsung_sm7125", |
||||
init_rc: ["audio_parameter_service.rc"], |
||||
system_ext_specific: true, |
||||
srcs: [ |
||||
"audio_parameter_service.cpp", |
||||
], |
||||
shared_libs: [ |
||||
"libbase", |
||||
"libutils", |
||||
"libhidlbase", |
||||
"liblog", |
||||
"android.hardware.audio@7.0", |
||||
], |
||||
} |
@ -0,0 +1,55 @@ |
||||
/*
|
||||
* 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. |
||||
*/ |
||||
|
||||
#include <android-base/properties.h> |
||||
#include <android-base/logging.h> |
||||
#include <android/hardware/audio/7.0/IDevicesFactory.h> |
||||
|
||||
using android::base::GetProperty; |
||||
using android::base::SetProperty; |
||||
using android::sp; |
||||
using ::android::hardware::hidl_string; |
||||
|
||||
int main() { |
||||
sp<::android::hardware::audio::V7_0::IDevice> audioDevice; |
||||
|
||||
LOG(DEBUG) << "Passing g_call_sim_slot parameter"; |
||||
|
||||
if (!audioDevice) { |
||||
::android::hardware::audio::V7_0::IDevicesFactory::getService()->openDevice( |
||||
"primary", [&](::android::hardware::audio::V7_0::Result, const sp<::android::hardware::audio::V7_0::IDevice>& result) { |
||||
audioDevice = result; |
||||
}); |
||||
} |
||||
|
||||
if (audioDevice != nullptr) { |
||||
std::string value = ""; |
||||
|
||||
if (strcmp(GetProperty("vendor.calls.slotid", "-1").c_str(), "1") == 0) { |
||||
// SIM 2
|
||||
value = "0x02"; |
||||
} |
||||
|
||||
audioDevice->setParameters({}, {{"g_call_sim_slot", value}}); |
||||
} |
||||
|
||||
if (audioDevice != nullptr) |
||||
audioDevice->close(); |
||||
|
||||
SetProperty("vendor.calls.parameter_state", "1"); |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,16 @@ |
||||
service audio_parameter_service /system_ext/bin/audio_parameter_service.samsung_sm7125 |
||||
oneshot |
||||
disabled |
||||
|
||||
on boot |
||||
setprop vendor.calls.parameter_state 0 |
||||
|
||||
on property:vendor.calls.slotid=1 && property:vendor.calls.parameter_state=0 |
||||
stop audioserver |
||||
start audioserver |
||||
start audio_parameter_service |
||||
|
||||
on property:vendor.calls.slotid=-1 && property:vendor.calls.parameter_state=1 |
||||
setprop vendor.calls.parameter_state 0 |
||||
stop audioserver |
||||
start audioserver |
@ -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,25 @@ |
||||
<?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> |
||||
|
||||
</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 |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue