diff --git a/Android.mk b/Android.mk
index 55c4d1f..2d364f9 100755
--- a/Android.mk
+++ b/Android.mk
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2016 The CyanogenMod Project
+# Copyright (C) 2019-2020 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.
@@ -12,35 +12,105 @@
# 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.
+#
-# WARNING: Everything listed here will be built on ALL platforms,
-# including x86, the emulator, and the SDK. Modules must be uniquely
-# named (liblights.tuna), and must build everywhere, or limit themselves
-# to only building on ARM if they include assembly. Individual makefiles
-# are responsible for having their own logic, for fine-grained control.
+# This contains the module build definitions for the hardware-specific
+# components for this device.
+#
+# As much as possible, those components should be built unconditionally,
+# with device-specific names to avoid collisions, to avoid device-specific
+# bitrot and build breakages. Building a component unconditionally does
+# *not* include it on all devices, so it is safe even with hardware-specific
+# components.
LOCAL_PATH := $(call my-dir)
-ifeq ($(TARGET_DEVICE),gts3llte)
+ifneq ($(filter gts3llte gts3lwifi,$(TARGET_DEVICE)),)
include $(call all-makefiles-under,$(LOCAL_PATH))
-include $(CLEAR_VARS)
-
-MODEM_IMAGES := \
- modem.b00 modem.b01 modem.b02 modem.b03 modem.b04 modem.b05 \
- modem.b06 modem.b07 modem.b08 modem.b09 modem.b10 modem.b11 \
- modem.b12 modem.b13 modem.b15 modem.b16 modem.b17 modem.b18 \
- modem.b19 modem.b20 modem.mdt
-
-MODEM_SYMLINKS := $(addprefix $(TARGET_OUT_ETC)/firmware/,$(notdir $(MODEM_IMAGES)))
-$(MODEM_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "MODEM firmware link: $@"
- @mkdir -p $(dir $@)
+DSP_SYMLINK := $(TARGET_OUT_VENDOR)/lib/dsp
+$(DSP_SYMLINK): $(LOCAL_INSTALLED_MODULE)
+ @echo "Creating DSP folder symlink: $@"
@rm -rf $@
- $(hide) ln -sf /firmware-modem/image/$(notdir $@) $@
+ @mkdir -p $(TARGET_OUT_VENDOR)/lib/dsp
-ALL_DEFAULT_INSTALLED_MODULES += $(MODEM_SYMLINKS)
+ALL_DEFAULT_INSTALLED_MODULES += $(DSP_SYMLINK)
+
+FIRMWARE_MODEM_MOUNT_POINT := $(TARGET_OUT_VENDOR)/firmware-modem
+FIRMWARE_MOUNT_POINT := $(TARGET_OUT_VENDOR)/firmware_mnt
+DSP_MOUNT_POINT := $(TARGET_OUT_VENDOR)/dsp
+
+$(FIRMWARE_MODEM_MOUNT_POINT):
+ @echo "Creating $(FIRMWARE_MODEM_MOUNT_POINT)"
+ @mkdir -p $(TARGET_OUT_VENDOR)/firmware-modem
+
+$(FIRMWARE_MOUNT_POINT):
+ @echo "Creating $(FIRMWARE_MOUNT_POINT)"
+ @mkdir -p $(TARGET_OUT_VENDOR)/firmware_mnt
+
+$(DSP_MOUNT_POINT):
+ @echo "Creating $(DSP_MOUNT_POINT)"
+ @mkdir -p $(TARGET_OUT_VENDOR)/dsp
+
+ALL_DEFAULT_INSTALLED_MODULES += \
+ $(FIRMWARE_MODEM_MOUNT_POINT) \
+ $(FIRMWARE_MOUNT_POINT) \
+ $(DSP_MOUNT_POINT)
+
+RFS_MSM_ADSP_SYMLINKS := $(TARGET_OUT_VENDOR)/rfs/msm/adsp/
+$(RFS_MSM_ADSP_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
+ @echo "Creating RFS MSM ADSP folder structure: $@"
+ @rm -rf $@/*
+ @mkdir -p $(dir $@)/readonly/vendor
+ $(hide) ln -sf /data/vendor/tombstones/rfs/lpass $@/ramdumps
+ $(hide) ln -sf /mnt/vendor/persist/rfs/msm/adsp $@/readwrite
+ $(hide) ln -sf /mnt/vendor/persist/rfs/shared $@/shared
+ $(hide) ln -sf /mnt/vendor/persist/hlos_rfs/shared $@/hlos
+ $(hide) ln -sf /vendor/firmware_mnt $@/readonly/firmware
+ $(hide) ln -sf /vendor/firmware $@/readonly/vendor/firmware
+
+RFS_MSM_CDSP_SYMLINKS := $(TARGET_OUT_VENDOR)/rfs/msm/cdsp/
+$(RFS_MSM_CDSP_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
+ @echo "Creating RFS MSM CDSP folder structure: $@"
+ @rm -rf $@/*
+ @mkdir -p $(dir $@)/readonly/vendor
+ $(hide) ln -sf /data/vendor/tombstones/rfs/cdsp $@/ramdumps
+ $(hide) ln -sf /mnt/vendor/persist/rfs/msm/cdsp $@/readwrite
+ $(hide) ln -sf /mnt/vendor/persist/rfs/shared $@/shared
+ $(hide) ln -sf /mnt/vendor/persist/hlos_rfs/shared $@/hlos
+ $(hide) ln -sf /vendor/firmware_mnt $@/readonly/firmware
+ $(hide) ln -sf /vendor/firmware $@/readonly/vendor/firmware
+
+RFS_MSM_MPSS_SYMLINKS := $(TARGET_OUT_VENDOR)/rfs/msm/mpss/
+$(RFS_MSM_MPSS_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
+ @echo "Creating RFS MSM MPSS folder structure: $@"
+ @rm -rf $@/*
+ @mkdir -p $(dir $@)/readonly/vendor
+ $(hide) ln -sf /data/vendor/tombstones/rfs/modem $@/ramdumps
+ $(hide) ln -sf /mnt/vendor/persist/rfs/msm/mpss $@/readwrite
+ $(hide) ln -sf /mnt/vendor/persist/rfs/shared $@/shared
+ $(hide) ln -sf /mnt/vendor/persist/hlos_rfs/shared $@/hlos
+ $(hide) ln -sf /vendor/firmware-modem $@/readonly/firmware
+ $(hide) ln -sf /vendor/firmware $@/readonly/vendor/firmware
+
+RFS_MSM_SLPI_SYMLINKS := $(TARGET_OUT_VENDOR)/rfs/msm/slpi/
+$(RFS_MSM_SLPI_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
+ @echo "Creating RFS MSM SLPI folder structure: $@"
+ @rm -rf $@/*
+ @mkdir -p $(dir $@)/readonly/vendor
+ $(hide) ln -sf /data/vendor/tombstones/rfs/slpi $@/ramdumps
+ $(hide) ln -sf /mnt/vendor/persist/rfs/msm/slpi $@/readwrite
+ $(hide) ln -sf /mnt/vendor/persist/rfs/shared $@/shared
+ $(hide) ln -sf /mnt/vendor/persist/hlos_rfs/shared $@/hlos
+ $(hide) ln -sf /vendor/firmware_mnt $@/readonly/firmware
+ $(hide) ln -sf /vendor/firmware $@/readonly/vendor/firmware
+
+ALL_DEFAULT_INSTALLED_MODULES += \
+ $(RFS_MSM_ADSP_SYMLINKS) \
+ $(RFS_MSM_CDSP_SYMLINKS) \
+ $(RFS_MSM_MPSS_SYMLINKS) \
+ $(RFS_MSM_SLPI_SYMLINKS)
WCNSS_INI_SYMLINK := $(TARGET_OUT_VENDOR)/firmware/wlan/qca_cld/WCNSS_qcom_cfg.ini
$(WCNSS_INI_SYMLINK): $(LOCAL_INSTALLED_MODULE)
@@ -49,369 +119,6 @@ $(WCNSS_INI_SYMLINK): $(LOCAL_INSTALLED_MODULE)
@rm -rf $@
$(hide) ln -sf /vendor/etc/wifi/$(notdir $@) $@
-WCNSS_MAC_SYMLINK := $(TARGET_OUT_VENDOR)/firmware/wlan/qca_cld/wlan_mac.bin
-$(WCNSS_MAC_SYMLINK): $(LOCAL_INSTALLED_MODULE)
- @echo "WCNSS MAC bin link: $@"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf /persist/$(notdir $@) $@
+ALL_DEFAULT_INSTALLED_MODULES += $(WCNSS_INI_SYMLINK)
-ALL_DEFAULT_INSTALLED_MODULES += $(WCNSS_INI_SYMLINK) $(WCNSS_MAC_SYMLINK)
-
-# Create links for audcal data files
-$(shell mkdir -p $(TARGET_OUT)/etc/firmware/wcd9320; \
- ln -sf /data/misc/audio/wcd9320_anc.bin \
- $(TARGET_OUT)/etc/firmware/wcd9320/wcd9320_anc.bin;\
- ln -sf /data/misc/audio/mbhc.bin \
- $(TARGET_OUT)/etc/firmware/wcd9320/wcd9320_mbhc.bin; \
- ln -sf /data/misc/audio/wcd9320_mad_audio.bin \
- $(TARGET_OUT)/etc/firmware/wcd9320/wcd9320_mad_audio.bin)
-
-RFS_MSM_ADSP_SYMLINKS := $(TARGET_OUT_VENDOR)/rfs/msm/adsp/
-$(RFS_MSM_ADSP_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "Creating RFS MSM ADSP folder structure: $@"
- @rm -rf $@/*
- @mkdir -p $(dir $@)/readonly/vendor
- $(hide) ln -sf /data/vendor/tombstones/rfs/lpass $@/ramdumps
- $(hide) ln -sf /persist/rfs/msm/adsp $@/readwrite
- $(hide) ln -sf /persist/rfs/shared $@/shared
- $(hide) ln -sf /persist/hlos_rfs/shared $@/hlos
- $(hide) ln -sf /firmware $@/readonly/firmware
- $(hide) ln -sf /vendor/firmware $@/readonly/vendor/firmware
-
-RFS_MSM_MPSS_SYMLINKS := $(TARGET_OUT_VENDOR)/rfs/msm/mpss/
-$(RFS_MSM_MPSS_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "Creating RFS MSM MPSS folder structure: $@"
- @rm -rf $@/*
- @mkdir -p $(dir $@)/readonly/vendor
- $(hide) ln -sf /data/vendor/tombstones/rfs/modem $@/ramdumps
- $(hide) ln -sf /persist/rfs/msm/mpss $@/readwrite
- $(hide) ln -sf /persist/rfs/shared $@/shared
- $(hide) ln -sf /persist/hlos_rfs/shared $@/hlos
- $(hide) ln -sf /firmware $@/readonly/firmware
- $(hide) ln -sf /vendor/firmware $@/readonly/vendor/firmware
-
-RFS_MSM_SLPI_SYMLINKS := $(TARGET_OUT_VENDOR)/rfs/msm/slpi/
-$(RFS_MSM_SLPI_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "Creating RFS MSM SLPI folder structure: $@"
- @rm -rf $@/*
- @mkdir -p $(dir $@)/readonly/vendor
- $(hide) ln -sf /data/vendor/tombstones/rfs/modem $@/ramdumps
- $(hide) ln -sf /persist/rfs/msm/slpi $@/readwrite
- $(hide) ln -sf /persist/rfs/shared $@/shared
- $(hide) ln -sf /persist/hlos_rfs/shared $@/hlos
- $(hide) ln -sf /firmware $@/readonly/firmware
- $(hide) ln -sf /vendor/firmware $@/readonly/vendor/firmware
-
-RFS_MDM_SPARROW_SYMLINKS := $(TARGET_OUT_VENDOR)/rfs/mdm/sparrow/
-$(RFS_MDM_SPARROW_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "Creating RFS MDM SPARROW folder structure: $@"
- @rm -rf $@/*
- @mkdir -p $(dir $@)/readonly/vendor
- $(hide) ln -sf /data/vendor/tombstones/sparrow $@/ramdumps
- $(hide) ln -sf /persist/rfs/mdm/sparrow $@/readwrite
- $(hide) ln -sf /persist/rfs/shared $@/shared
- $(hide) ln -sf /persist/hlos_rfs/shared $@/hlos
- $(hide) ln -sf /firmware $@/readonly/firmware
- $(hide) ln -sf /vendor/firmware $@/readonly/vendor/firmware
-
-RFS_APQ_GNSS_SYMLINKS := $(TARGET_OUT_VENDOR)/rfs/apq/gnss/
-$(RFS_APQ_GNSS_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "Creating RFS APQ GNSS folder structure: $@"
- @rm -rf $@/*
- @mkdir -p $(dir $@)/readonly/vendor
- $(hide) ln -sf /data/vendor/tombstones/modem $@/ramdumps
- $(hide) ln -sf /persist/rfs/apq/gnss $@/readwrite
- $(hide) ln -sf /persist/rfs/shared $@/shared
- $(hide) ln -sf /persist/hlos_rfs/shared $@/hlos
- $(hide) ln -sf /firmware $@/readonly/firmware
- $(hide) ln -sf /vendor/firmware $@/readonly/vendor/firmware
-
-ALL_DEFAULT_INSTALLED_MODULES += \
- $(RFS_MSM_ADSP_SYMLINKS) \
- $(RFS_MSM_MPSS_SYMLINKS) \
- $(RFS_MSM_SLPI_SYMLINKS) \
- $(RFS_MDM_SPARROW_SYMLINKS) \
- $(RFS_APQ_GNSS_SYMLINKS)
-
-ADSP_IMAGES := \
- adsp.b00 adsp.b01 adsp.b02 adsp.b03 adsp.b04 \
- adsp.b05 adsp.b06 adsp.b08 adsp.b09 adsp.mdt
-
-ADSP_SYMLINKS := $(addprefix $(TARGET_OUT_VENDOR)/firmware/,$(notdir $(ADSP_IMAGES)))
-$(ADSP_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "ADSP firmware link: $@"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf /firmware-modem/image/$(notdir $@) $@
-
-ALL_DEFAULT_INSTALLED_MODULES += $(ADSP_SYMLINKS)
-
-MBA_IMAGES := mba.mbn
-
-MBA_SYMLINKS := $(addprefix $(TARGET_OUT_VENDOR)/firmware/,$(notdir $(MBA_IMAGES)))
-$(MBA_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "MBA firmware link: $@"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf /firmware-modem/image/$(notdir $@) $@
-
-ALL_DEFAULT_INSTALLED_MODULES += $(MBA_SYMLINKS)
-
-
-AUTHHAT_IMAGES := authhat.b00 authhat.b01 authhat.b02 authhat.b03 authhat.b04 authhat.b05 authhat.b06 authhat.mdt
-
-AUTHHAT_SYMLINKS := $(addprefix $(TARGET_OUT_VENDOR)/firmware/,$(notdir $(AUTHHAT_IMAGES)))
-$(AUTHHAT_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "AUTHHAT firmware link: $@"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf /firmware/image/$(notdir $@) $@
-
-ALL_DEFAULT_INSTALLED_MODULES += $(AUTHHAT_SYMLINKS)
-
-AUTHHAT_SYMLINKS1 := $(addprefix $(TARGET_OUT_VENDOR)/firmware_mnt/image/,$(notdir $(AUTHHAT_IMAGES)))
-$(AUTHHAT_SYMLINKS1): $(LOCAL_INSTALLED_MODULE)
- @echo "AUTHHAT firmware link: $@"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf /firmware/image/$(notdir $@) $@
-
-ALL_DEFAULT_INSTALLED_MODULES += $(AUTHHAT_SYMLINKS1)
-
-BDWLAN_IMAGES := \
- bdwlan30.b01 bdwlan30.b02 bdwlan30.b03 bdwlan30.b04 bdwlan30.b05 bdwlan30.b06 bdwlan30.b07 \
- bdwlan30.b08 bdwlan30.b09 bdwlan30.b0a bdwlan30.b0b bdwlan30.b0c bdwlan30.b0d bdwlan30.b0e \
- bdwlan30.b11 bdwlan30.b15 bdwlan30.b18 bdwlan30.b1c bdwlan30.bin
-
-BDWLAN_SYMLINKS := $(addprefix $(TARGET_OUT_VENDOR)/firmware/,$(notdir $(BDWLAN_IMAGES)))
-$(BDWLAN_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "BDWLAN firmware link: $@"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf /firmware/image/$(notdir $@) $@
-
-ALL_DEFAULT_INSTALLED_MODULES += $(BDWLAN_SYMLINKS)
-
-BDWLAN_SYMLINKS1 := $(addprefix $(TARGET_OUT_VENDOR)/firmware_mnt/image/,$(notdir $(BDWLAN_IMAGES)))
-$(BDWLAN_SYMLINKS1): $(LOCAL_INSTALLED_MODULE)
- @echo "BDWLAN firmware link: $@"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf /firmware/image/$(notdir $@) $@
-
-ALL_DEFAULT_INSTALLED_MODULES += $(BDWLAN_SYMLINKS1)
-
-CPE_IMAGES := \
- cpe_9335.b08 cpe_9335.b09 cpe_9335.b11 cpe_9335.b14 cpe_9335.b16 \
- cpe_9335.b18 cpe_9335.b19 cpe_9335.b20 cpe_9335.b22 cpe_9335.b24 \
- cpe_9335.b26 cpe_9335.b28 cpe_9335.b29 cpe_9335.mdt
-
-CPE_SYMLINKS := $(addprefix $(TARGET_OUT_VENDOR)/firmware/,$(notdir $(CPE_IMAGES)))
-$(CPE_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "CPE firmware link: $@"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf /firmware/image/$(notdir $@) $@
-
-ALL_DEFAULT_INSTALLED_MODULES += $(CPE_SYMLINKS)
-
-CPPF_IMAGES := cppf.b00 cppf.b01 cppf.b02 cppf.b03 cppf.b04 cppf.b05 cppf.b06 cppf.mdt
-
-CPPF_SYMLINKS := $(addprefix $(TARGET_OUT_VENDOR)/firmware/,$(notdir $(CPPF_IMAGES)))
-$(CPPF_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "CPPF firmware link: $@"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf /firmware/image/$(notdir $@) $@
-
-ALL_DEFAULT_INSTALLED_MODULES += $(CPPF_SYMLINKS)
-
-DATA_IMAGES := data.msc
-
-DATA_SYMLINKS := $(addprefix $(TARGET_OUT_VENDOR)/firmware/,$(notdir $(DATA_IMAGES)))
-$(DATA_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "DATA firmware link: $@"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf /firmware/image/$(notdir $@) $@
-
-ALL_DEFAULT_INSTALLED_MODULES += $(DATA_SYMLINKS)
-
-ADD_IMAGES := \
- dhsecapp.b00 dhsecapp.b01 dhsecapp.b02 dhsecapp.b03 dhsecapp.b04 dhsecapp.b05 dhsecapp.b06 dhsecapp.mdt \
- dmverity.b00 dmverity.b01 dmverity.b02 dmverity.b03 dmverity.b04 dmverity.b05 dmverity.b06 dmverity.mdt \
- dualfp.b00 dualfp.b01 dualfp.b02 dualfp.b03 dualfp.b04 dualfp.b05 dualfp.b06 dualfp.mdt \
- dxprdy.b00 dxprdy.b01 dxprdy.b02 dxprdy.b03 dxprdy.b04 dxprdy.b05 dxprdy.b06 dxprdy.mdt \
- esecomm.b00 esecomm.b01 esecomm.b02 esecomm.b03 esecomm.b04 esecomm.b05 esecomm.b06 esecomm.mdt \
- isdbtmm.b00 isdbtmm.b01 isdbtmm.b02 isdbtmm.b03 isdbtmm.b04 isdbtmm.b05 isdbtmm.b06 isdbtmm.mdt \
- lksecapp.b00 lksecapp.b01 lksecapp.b02 lksecapp.b03 lksecapp.b04 lksecapp.b05 lksecapp.b06 lksecapp.mdt \
- mldap.b00 mldap.b01 mldap.b02 mldap.b03 mldap.b04 mldap.b05 mldap.b06 mldap.mdt \
- mst.b00 mst.b01 mst.b02 mst.b03 mst.b04 mst.b05 mst.b06 mst.mdt \
- otp30.bin \
- prov.b00 prov.b01 prov.b02 prov.b03 prov.b04 prov.b05 prov.b06 prov.mdt \
- qmpsecap.b00 qmpsecap.b01 qmpsecap.b02 qmpsecap.b03 qmpsecap.b04 qmpsecap.b05 qmpsecap.b06 qmpsecap.mdt \
- qwlan30.bin \
- sdtvrmp.b00 sdtvrmp.b01 sdtvrmp.b02 sdtvrmp.b03 sdtvrmp.b04 sdtvrmp.b05 sdtvrmp.b06 sdtvrmp.mdt \
- securemm.b00 securemm.b01 securemm.b02 securemm.b03 securemm.b04 securemm.b05 securemm.b06 securemm.mdt \
- sem.b00 sem.b01 sem.b02 sem.b03 sem.b04 sem.b05 sem.b06 sem.mdt \
- skeymast.b00 skeymast.b01 skeymast.b02 skeymast.b03 skeymast.b04 skeymast.b05 skeymast.b06 skeymast.mdt \
- slpi.b00 slpi.b01 slpi.b02 slpi.b03 slpi.b04 slpi.b05 slpi.b06 slpi.b07 \
- slpi.b08 slpi.b09 slpi.b10 slpi.b11 slpi.b12 slpi.b13 slpi.b14 slpi.mdt \
- smplap32.b00 smplap32.b01 smplap32.b02 smplap32.b03 smplap32.b04 smplap32.b05 smplap32.b06 smplap32.mdt \
- smplap64.b00 smplap64.b01 smplap64.b02 smplap64.b03 smplap64.b04 smplap64.b05 smplap64.b06 smplap64.mdt \
- softsim.b00 softsim.b01 softsim.b02 softsim.b03 softsim.b04 softsim.b05 softsim.b06 softsim.mdt \
- tbase.b00 tbase.b01 tbase.b02 tbase.b03 tbase.b04 tbase.b05 tbase.b06 tbase.mdt \
- utf30.bin
-
-ADD_SYMLINKS := $(addprefix $(TARGET_OUT_VENDOR)/firmware/,$(notdir $(ADD_IMAGES)))
-$(ADD_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "Additional firmware link: $@"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf /firmware/image/$(notdir $@) $@
-
-ALL_DEFAULT_INSTALLED_MODULES += $(ADD_SYMLINKS)
-
-ADD_SYMLINKS1 := $(addprefix $(TARGET_OUT_VENDOR)/firmware_mnt/image/,$(notdir $(ADD_IMAGES)))
-$(ADD_SYMLINKS1): $(LOCAL_INSTALLED_MODULE)
- @echo "Additional firmware link: $@"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf /firmware/image/$(notdir $@) $@
-
-ALL_DEFAULT_INSTALLED_MODULES += $(ADD_SYMLINKS1)
-
-FINGERPR_IMAGES := fingerpr.b00 fingerpr.b01 fingerpr.b02 fingerpr.b03 fingerpr.b04 fingerpr.b05 fingerpr.b06 fingerpr.mdt
-
-FINGERPR_SYMLINKS := $(addprefix $(TARGET_OUT_VENDOR)/firmware/,$(notdir $(FINGERPR_IMAGES)))
-$(FINGERPR_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "FINGERPR firmware link: $@"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf /firmware/image/$(notdir $@) $@
-
-ALL_DEFAULT_INSTALLED_MODULES += $(FINGERPR_SYMLINKS)
-
-FINGERPR_SYMLINKS1 := $(addprefix $(TARGET_OUT_VENDOR)/firmware/,$(notdir $(FINGERPR_IMAGES)))
-$(FINGERPR_SYMLINKS1): $(LOCAL_INSTALLED_MODULE)
- @echo "FINGERPR firmware link: $@"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf /firmware/image/$(notdir $@) $@
-
-ALL_DEFAULT_INSTALLED_MODULES += $(FINGERPR_SYMLINKS1)
-
-GPSTEST_IMAGES := gptest.b00 gptest.b01 gptest.b02 gptest.b03 gptest.b04 gptest.b05 gptest.b06 gptest.mdt
-
-GPSTEST_SYMLINKS := $(addprefix $(TARGET_OUT_VENDOR)/firmware/,$(notdir $(GPSTEST_IMAGES)))
-$(GPSTEST_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "GPSTEST firmware link: $@"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf /firmware/image/$(notdir $@) $@
-
-ALL_DEFAULT_INSTALLED_MODULES += $(GPSTEST_SYMLINKS)
-
-SKM_IMAGES := \
- skm.b00 skm.b01 skm.b02 skm.b03 skm.b04 skm.b05 skm.b06 skm.mdt \
-
-SKM_SYMLINKS := $(addprefix $(TARGET_OUT_VENDOR)/firmware/,$(notdir $(SKM_IMAGES)))
-$(SKM_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "SKM firmware link: $@"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf /firmware/image/$(notdir $@) $@
-
-ALL_DEFAULT_INSTALLED_MODULES += $(SKM_SYMLINKS)
-
-SKMM_TA_IMAGES := \
- skmm_ta.b00 skmm_ta.b01 skmm_ta.b02 skmm_ta.b03 skmm_ta.b04 skmm_ta.b05 skmm_ta.b06 skmm_ta.mdt \
-
-SKMM_TA_SYMLINKS := $(addprefix $(TARGET_OUT_VENDOR)/firmware/,$(notdir $(SKMM_TA_IMAGES)))
-$(SKMM_TA_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "SKMM firmware link: $@"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf /firmware/image/$(notdir $@) $@
-
-ALL_DEFAULT_INSTALLED_MODULES += $(SKMM_TA_SYMLINKS)
-
-SSHDCPAP_IMAGES := \
- sshdcpap.b00 sshdcpap.b01 sshdcpap.b02 sshdcpap.b03 sshdcpap.b04 sshdcpap.b05 sshdcpap.b06 sshdcpap.mdt \
-
-SSHDCPAP_SYMLINKS := $(addprefix $(TARGET_OUT_VENDOR)/firmware/,$(notdir $(SSHDCPAP_IMAGES)))
-$(SSHDCPAP_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "SSHDCPAP firmware link: $@"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf /firmware/image/$(notdir $@) $@
-
-ALL_DEFAULT_INSTALLED_MODULES += $(SSHDCPAP_SYMLINKS)
-
-TIMA_IMAGES := \
- tima_atn.b00 tima_atn.b01 tima_atn.b02 tima_atn.b03 tima_atn.b04 tima_atn.b05 tima_atn.b06 tima_atn.mdt \
- tima_key.b00 tima_key.b01 tima_key.b02 tima_key.b03 tima_key.b04 tima_key.b05 tima_key.b06 tima_key.mdt \
- tima_lkm.b00 tima_lkm.b01 tima_lkm.b02 tima_lkm.b03 tima_lkm.b04 tima_lkm.b05 tima_lkm.b06 tima_lkm.mdt \
- tima_pkm.b00 tima_pkm.b01 tima_pkm.b02 tima_pkm.b03 tima_pkm.b04 tima_pkm.b05 tima_pkm.b06 tima_pkm.mdt
-
-TIMA_SYMLINKS := $(addprefix $(TARGET_OUT_VENDOR)/firmware/,$(notdir $(TIMA_IMAGES)))
-$(TIMA_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "TIMA firmware link: $@"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf /firmware/image/$(notdir $@) $@
-
-ALL_DEFAULT_INSTALLED_MODULES += $(TIMA_SYMLINKS)
-
-TZ_IMAGES := \
- tz_ccm.b00 tz_ccm.b01 tz_ccm.b02 tz_ccm.b03 tz_ccm.b04 tz_ccm.b05 tz_ccm.b06 tz_ccm.mdt \
- tz_iccc.b00 tz_iccc.b01 tz_iccc.b02 tz_iccc.b03 tz_iccc.b04 tz_iccc.b05 tz_iccc.b06 tz_iccc.mdt \
- tz_otp.b00 tz_otp.b01 tz_otp.b02 tz_otp.b03 tz_otp.b04 tz_otp.b05 tz_otp.b06 tz_otp.mdt
-
-TZ_SYMLINKS := $(addprefix $(TARGET_OUT_VENDOR)/firmware/,$(notdir $(TZ_IMAGES)))
-$(TZ_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "TZ firmware link: $@"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf /firmware/image/$(notdir $@) $@
-
-ALL_DEFAULT_INSTALLED_MODULES += $(TZ_SYMLINKS)
-
-VENUS_IMAGES := venus.b00 venus.b01 venus.b02 venus.b03 venus.b04 venus.mdt
-
-VENUS_SYMLINKS := $(addprefix $(TARGET_OUT_VENDOR)/firmware/,$(notdir $(VENUS_IMAGES)))
-$(VENUS_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "Venus firmware link: $@"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf /firmware/image/$(notdir $@) $@
-
-ALL_DEFAULT_INSTALLED_MODULES += $(VENUS_SYMLINKS)
-
-WV_IMAGES := \
- cmnlib.b00 cmnlib.b01 cmnlib.b02 cmnlib.b03 cmnlib.b04 cmnlib.b05 cmnlib.mdt \
- cmnlib64.b00 cmnlib64.b01 cmnlib64.b02 cmnlib64.b03 cmnlib64.b04 cmnlib64.b05 cmnlib64.mdt \
- widevine.b00 widevine.b01 widevine.b02 widevine.b03 widevine.b04 widevine.b05 widevine.b06 widevine.mdt
-
-WV_SYMLINKS := $(addprefix $(TARGET_OUT_VENDOR)/firmware/,$(notdir $(WV_IMAGES)))
-$(WV_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "Widevine firmware link: $@"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf /firmware/image/$(notdir $@) $@
-
-ALL_DEFAULT_INSTALLED_MODULES += $(WV_SYMLINKS)
-
-WSM_IMAGES := wsm.b00 wsm.b01 wsm.b02 wsm.b03 wsm.b04 wsm.b05 wsm.b06 wsm.mdt
-
-WSM_SYMLINKS := $(addprefix $(TARGET_OUT_VENDOR)/firmware/,$(notdir $(WSM_IMAGES)))
-$(WSM_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
- @echo "WSM firmware link: $@"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf /firmware/image/$(notdir $@) $@
-
-ALL_DEFAULT_INSTALLED_MODULES += $(WSM_SYMLINKS)
-
-endif
\ No newline at end of file
+endif
diff --git a/BoardConfig.mk b/BoardConfig.mk
index 43e2401..7669fde 100755
--- a/BoardConfig.mk
+++ b/BoardConfig.mk
@@ -15,9 +15,6 @@
# limitations under the License.
#
-# temporary
-BUILD_BROKEN_DUP_RULES := true
-
BOARD_VENDOR := samsung
DEVICE_PATH := device/samsung/gts3llte
@@ -51,17 +48,16 @@ TARGET_NO_BOOTLOADER := true
# Kernel
BOARD_KERNEL_BASE := 0x80000000
BOARD_KERNEL_CMDLINE := androidboot.hardware=qcom msm_rtb.filter=0x237 ehci-hcd.park=3 androidboot.bootdevice=7464900.sdhci lpm_levels.sleep_disabled=1 rcupdate.rcu_expedited=1 cma=32M@0-0xffffffff
-BOARD_KERNEL_CMDLINE += androidboot.selinux=permissive
+BOARD_KERNEL_CMDLINE += androidboot.selinux=disabled
BOARD_KERNEL_IMAGE_NAME := Image.gz
BOARD_KERNEL_PAGESIZE := 4096
BOARD_KERNEL_SEPARATED_DT := true
BOARD_MKBOOTIMG_ARGS := --kernel_offset 0x00008000 --ramdisk_offset 0x02200000 --tags_offset 0x02000000
-TARGET_KERNEL_SOURCE := kernel/samsung/msm8996
BOARD_CUSTOM_BOOTIMG := true
BOARD_CUSTOM_BOOTIMG_MK := hardware/samsung/mkbootimg.mk
-#TARGET_KERNEL_CROSS_COMPILE_PREFIX := aarch64-linux-android-
+TARGET_KERNEL_ARCH := arm64
+TARGET_KERNEL_SOURCE := kernel/samsung/msm8996
TARGET_KERNEL_CONFIG := lineage_gts3llte_defconfig
-
TARGET_COMPILE_WITH_MSM_KERNEL := true
# Platform
@@ -103,9 +99,7 @@ BOARD_HAVE_BLUETOOTH_QCOM := true
QCOM_BT_USE_BTNV := true
# Camera
-USE_CAMERA_STUB := true
-USE_DEVICE_SPECIFIC_CAMERA := true
-TARGET_USES_MEDIA_EXTENSIONS := true
+TARGET_USES_QTI_CAMERA_DEVICE := true
# Charger
BOARD_CHARGER_ENABLE_SUSPEND := true
@@ -141,9 +135,9 @@ TARGET_HW_DISK_ENCRYPTION := true
TARGET_FS_CONFIG_GEN := $(DEVICE_PATH)/config.fs
# HIDL
-DEVICE_FRAMEWORK_MANIFEST_FILE := $(DEVICE_PATH)/configs/framework_manifest.xml
-DEVICE_MANIFEST_FILE := $(DEVICE_PATH)/configs/manifest.xml
-DEVICE_MATRIX_FILE := $(DEVICE_PATH)/configs/compatibility_matrix.xml
+DEVICE_FRAMEWORK_MANIFEST_FILE := $(DEVICE_PATH)/framework_manifest.xml
+DEVICE_MANIFEST_FILE := $(DEVICE_PATH)/manifest.xml
+DEVICE_MATRIX_FILE := $(DEVICE_PATH)/compatibility_matrix.xml
# Partitions
BOARD_BOOTIMAGE_PARTITION_SIZE := 79691776
@@ -151,7 +145,7 @@ BOARD_CACHEIMAGE_PARTITION_SIZE := 209715200
BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := f2fs
BOARD_PERSISTIMAGE_PARTITION_SIZE := 33554432
BOARD_RECOVERYIMAGE_PARTITION_SIZE := 79691776
-BOARD_SYSTEMIMAGE_PARTITION_SIZE := 3072000000
+BOARD_SYSTEMIMAGE_PARTITION_SIZE := 3072000000
#BOARD_SYSTEMIMAGE_PARTITION_SIZE := 4194304000
BOARD_USERDATAIMAGE_PARTITION_SIZE := 26226982912
BOARD_FLASH_BLOCK_SIZE := 131072
@@ -160,21 +154,24 @@ TARGET_USES_MKE2FS := true
# Fingerprint
TARGET_SEC_FP_HAL_VARIANT := bauth
-# Init
-TARGET_PLATFORM_DEVICE_BASE := /devices/soc/
-
# Keymaster
TARGET_PROVIDES_KEYMASTER := true
# Power
+TARGET_TAP_TO_WAKE_NODE := "/proc/touchpanel/double_tap_enable"
TARGET_USES_INTERACTION_BOOST := true
# QCOM
BOARD_USES_QCOM_HARDWARE := true
# Ramdisk
-BOARD_ROOT_EXTRA_FOLDERS := efs firmware firmware-modem persist
-BOARD_ROOT_EXTRA_SYMLINKS := /system/vendor/firmware/btfw32.tlv:/bt_firmware/image/btfw32.tlv
+BOARD_ROOT_EXTRA_FOLDERS := efs omr firmware firmware-modem persist
+BOARD_ROOT_EXTRA_SYMLINKS := \
+ /mnt/vendor/persist:/persist \
+ /vendor/dsp:/dsp \
+ /vendor/firmware_mnt:/firmware \
+ /vendor/bt_firmware:/bt_firmware
+BOARD_ROOT_EXTRA_SYMLINKS += /system/vendor/firmware/btfw32.tlv:/bt_firmware/image/btfw32.tlv
BOARD_ROOT_EXTRA_SYMLINKS += /system/vendor/firmware/btnv32.bin:/bt_firmware/image/btnv32.bin
# Recovery
@@ -189,11 +186,10 @@ ENABLE_VENDOR_RIL_SERVICE := true
# Security patch level - T825N0KOU3CTD1
VENDOR_SECURITY_PATCH := 2020-03-01
-SELINUX_IGNORE_NEVERALLOWS := true
-
# SELinux
include device/qcom/sepolicy/sepolicy.mk
BOARD_SEPOLICY_DIRS += $(DEVICE_PATH)/sepolicy
+SELINUX_IGNORE_NEVERALLOWS := true
# Wifi
BOARD_HAS_QCOM_WLAN := true
diff --git a/configs/compatibility_matrix.xml b/compatibility_matrix.xml
similarity index 54%
rename from configs/compatibility_matrix.xml
rename to compatibility_matrix.xml
index e549136..24b2761 100644
--- a/configs/compatibility_matrix.xml
+++ b/compatibility_matrix.xml
@@ -1,30 +1,3 @@
-
android.frameworks.schedulerservice
@@ -82,5 +55,17 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
default
-
+
+ netutils-wrapper
+
+ 1.0
+
diff --git a/configs/audio/impl/Android.bp b/configs/audio/impl/Android.bp
new file mode 100644
index 0000000..29558a2
--- /dev/null
+++ b/configs/audio/impl/Android.bp
@@ -0,0 +1,96 @@
+cc_defaults {
+ name: "android.hardware.audio-impl_gts3l",
+ relative_install_path: "hw",
+ proprietary: true,
+ vendor: true,
+ srcs: [
+ "Conversions.cpp",
+ "Device.cpp",
+ "DevicesFactory.cpp",
+ "ParametersUtil.cpp",
+ "PrimaryDevice.cpp",
+ "Stream.cpp",
+ "StreamIn.cpp",
+ "StreamOut.cpp",
+ ],
+
+ defaults: ["hidl_defaults"],
+
+ export_include_dirs: ["include"],
+
+ shared_libs: [
+ "libbase",
+ "libcutils",
+ "libfmq",
+ "libhardware",
+ "libhidlbase",
+ "libhidltransport",
+ "liblog",
+ "libtinyalsa",
+ "libutils",
+ "android.hardware.audio.common-util",
+ ],
+
+ header_libs: [
+ "android.hardware.audio.common.util@all-versions",
+ "libaudioclient_headers",
+ "libaudio_system_headers",
+ "libhardware_headers",
+ "libmedia_headers",
+ ],
+
+ whole_static_libs: [
+ "libmedia_helper",
+ ],
+}
+
+cc_library_shared {
+ name: "android.hardware.audio@2.0-impl.gts3l",
+ defaults: ["android.hardware.audio-impl_gts3l"],
+
+ shared_libs: [
+ "android.hardware.audio@2.0",
+ "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.gts3l",
+ defaults: ["android.hardware.audio-impl_gts3l"],
+
+ shared_libs: [
+ "android.hardware.audio@4.0",
+ "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.gts3l",
+ defaults: ["android.hardware.audio-impl_gts3l"],
+
+ shared_libs: [
+ "android.hardware.audio@5.0",
+ "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",
+ ]
+}
diff --git a/configs/audio/impl/Conversions.cpp b/configs/audio/impl/Conversions.cpp
new file mode 100644
index 0000000..11872c0
--- /dev/null
+++ b/configs/audio/impl/Conversions.cpp
@@ -0,0 +1,192 @@
+/*
+ * 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/Conversions.h"
+
+#include
+
+#include
+
+namespace android {
+namespace hardware {
+namespace audio {
+namespace CPP_VERSION {
+namespace implementation {
+
+std::string deviceAddressToHal(const DeviceAddress& address) {
+ // HAL assumes that the address is NUL-terminated.
+ char halAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN];
+ memset(halAddress, 0, sizeof(halAddress));
+ uint32_t halDevice = static_cast(address.device);
+ const bool isInput = (halDevice & AUDIO_DEVICE_BIT_IN) != 0;
+ if (isInput) halDevice &= ~AUDIO_DEVICE_BIT_IN;
+ if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != 0) ||
+ (isInput && (halDevice & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) {
+ snprintf(halAddress, sizeof(halAddress), "%02X:%02X:%02X:%02X:%02X:%02X",
+ address.address.mac[0], address.address.mac[1], address.address.mac[2],
+ address.address.mac[3], address.address.mac[4], address.address.mac[5]);
+ } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_IP) != 0) ||
+ (isInput && (halDevice & AUDIO_DEVICE_IN_IP) != 0)) {
+ snprintf(halAddress, sizeof(halAddress), "%d.%d.%d.%d", address.address.ipv4[0],
+ address.address.ipv4[1], address.address.ipv4[2], address.address.ipv4[3]);
+ } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_ALL_USB) != 0) ||
+ (isInput && (halDevice & AUDIO_DEVICE_IN_ALL_USB) != 0)) {
+ snprintf(halAddress, sizeof(halAddress), "card=%d;device=%d", address.address.alsa.card,
+ address.address.alsa.device);
+ } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_BUS) != 0) ||
+ (isInput && (halDevice & AUDIO_DEVICE_IN_BUS) != 0)) {
+ snprintf(halAddress, sizeof(halAddress), "%s", address.busAddress.c_str());
+ } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0 ||
+ (isInput && (halDevice & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) {
+ snprintf(halAddress, sizeof(halAddress), "%s", address.rSubmixAddress.c_str());
+ }
+ return halAddress;
+}
+
+#if MAJOR_VERSION >= 4
+status_t deviceAddressFromHal(audio_devices_t device, const char* halAddress,
+ DeviceAddress* address) {
+ if (address == nullptr) {
+ return BAD_VALUE;
+ }
+ address->device = AudioDevice(device);
+ if (halAddress == nullptr || strnlen(halAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
+ return OK;
+ }
+
+ const bool isInput = (device & AUDIO_DEVICE_BIT_IN) != 0;
+ if (isInput) device &= ~AUDIO_DEVICE_BIT_IN;
+ if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_A2DP) != 0) ||
+ (isInput && (device & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) {
+ int status =
+ sscanf(halAddress, "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX", &address->address.mac[0],
+ &address->address.mac[1], &address->address.mac[2], &address->address.mac[3],
+ &address->address.mac[4], &address->address.mac[5]);
+ return status == 6 ? OK : BAD_VALUE;
+ } else if ((!isInput && (device & AUDIO_DEVICE_OUT_IP) != 0) ||
+ (isInput && (device & AUDIO_DEVICE_IN_IP) != 0)) {
+ int status =
+ sscanf(halAddress, "%hhu.%hhu.%hhu.%hhu", &address->address.ipv4[0],
+ &address->address.ipv4[1], &address->address.ipv4[2], &address->address.ipv4[3]);
+ return status == 4 ? OK : BAD_VALUE;
+ } else if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_USB)) != 0 ||
+ (isInput && (device & AUDIO_DEVICE_IN_ALL_USB)) != 0) {
+ int status = sscanf(halAddress, "card=%d;device=%d", &address->address.alsa.card,
+ &address->address.alsa.device);
+ return status == 2 ? OK : BAD_VALUE;
+ } else if ((!isInput && (device & AUDIO_DEVICE_OUT_BUS) != 0) ||
+ (isInput && (device & AUDIO_DEVICE_IN_BUS) != 0)) {
+ address->busAddress = halAddress;
+ return OK;
+ } else if ((!isInput && (device & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0 ||
+ (isInput && (device & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) {
+ address->rSubmixAddress = halAddress;
+ return OK;
+ }
+ address->busAddress = halAddress;
+ return OK;
+}
+
+AudioMicrophoneChannelMapping halToChannelMapping(audio_microphone_channel_mapping_t mapping) {
+ switch (mapping) {
+ case AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED:
+ return AudioMicrophoneChannelMapping::UNUSED;
+ case AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT:
+ return AudioMicrophoneChannelMapping::DIRECT;
+ case AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED:
+ return AudioMicrophoneChannelMapping::PROCESSED;
+ default:
+ ALOGE("Invalid channel mapping type: %d", mapping);
+ return AudioMicrophoneChannelMapping::UNUSED;
+ }
+}
+
+AudioMicrophoneLocation halToLocation(audio_microphone_location_t location) {
+ switch (location) {
+ default:
+ case AUDIO_MICROPHONE_LOCATION_UNKNOWN:
+ return AudioMicrophoneLocation::UNKNOWN;
+ case AUDIO_MICROPHONE_LOCATION_MAINBODY:
+ return AudioMicrophoneLocation::MAINBODY;
+ case AUDIO_MICROPHONE_LOCATION_MAINBODY_MOVABLE:
+ return AudioMicrophoneLocation::MAINBODY_MOVABLE;
+ case AUDIO_MICROPHONE_LOCATION_PERIPHERAL:
+ return AudioMicrophoneLocation::PERIPHERAL;
+ }
+}
+
+AudioMicrophoneDirectionality halToDirectionality(audio_microphone_directionality_t dir) {
+ switch (dir) {
+ default:
+ case AUDIO_MICROPHONE_DIRECTIONALITY_UNKNOWN:
+ return AudioMicrophoneDirectionality::UNKNOWN;
+ case AUDIO_MICROPHONE_DIRECTIONALITY_OMNI:
+ return AudioMicrophoneDirectionality::OMNI;
+ case AUDIO_MICROPHONE_DIRECTIONALITY_BI_DIRECTIONAL:
+ return AudioMicrophoneDirectionality::BI_DIRECTIONAL;
+ case AUDIO_MICROPHONE_DIRECTIONALITY_CARDIOID:
+ return AudioMicrophoneDirectionality::CARDIOID;
+ case AUDIO_MICROPHONE_DIRECTIONALITY_HYPER_CARDIOID:
+ return AudioMicrophoneDirectionality::HYPER_CARDIOID;
+ case AUDIO_MICROPHONE_DIRECTIONALITY_SUPER_CARDIOID:
+ return AudioMicrophoneDirectionality::SUPER_CARDIOID;
+ }
+}
+
+bool halToMicrophoneCharacteristics(MicrophoneInfo* pDst,
+ const struct audio_microphone_characteristic_t& src) {
+ bool status = false;
+ if (pDst != NULL) {
+ pDst->deviceId = src.device_id;
+
+ if (deviceAddressFromHal(src.device, src.address, &pDst->deviceAddress) != OK) {
+ return false;
+ }
+ pDst->channelMapping.resize(AUDIO_CHANNEL_COUNT_MAX);
+ for (size_t ch = 0; ch < pDst->channelMapping.size(); ch++) {
+ pDst->channelMapping[ch] = halToChannelMapping(src.channel_mapping[ch]);
+ }
+ pDst->location = halToLocation(src.location);
+ pDst->group = (AudioMicrophoneGroup)src.group;
+ pDst->indexInTheGroup = (uint32_t)src.index_in_the_group;
+ pDst->sensitivity = src.sensitivity;
+ pDst->maxSpl = src.max_spl;
+ pDst->minSpl = src.min_spl;
+ pDst->directionality = halToDirectionality(src.directionality);
+ pDst->frequencyResponse.resize(src.num_frequency_responses);
+ for (size_t k = 0; k < src.num_frequency_responses; k++) {
+ pDst->frequencyResponse[k].frequency = src.frequency_responses[0][k];
+ pDst->frequencyResponse[k].level = src.frequency_responses[1][k];
+ }
+ pDst->position.x = src.geometric_location.x;
+ pDst->position.y = src.geometric_location.y;
+ pDst->position.z = src.geometric_location.z;
+
+ pDst->orientation.x = src.orientation.x;
+ pDst->orientation.y = src.orientation.y;
+ pDst->orientation.z = src.orientation.z;
+
+ status = true;
+ }
+ return status;
+}
+#endif
+
+} // namespace implementation
+} // namespace CPP_VERSION
+} // namespace audio
+} // namespace hardware
+} // namespace android
diff --git a/configs/audio/impl/Device.cpp b/configs/audio/impl/Device.cpp
new file mode 100644
index 0000000..bec22df
--- /dev/null
+++ b/configs/audio/impl/Device.cpp
@@ -0,0 +1,390 @@
+/*
+ * 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
+#include "core/default/Conversions.h"
+#include "core/default/StreamIn.h"
+#include "core/default/StreamOut.h"
+#include "core/default/Util.h"
+
+//#define LOG_NDEBUG 0
+
+#include
+#include
+#include
+
+#include
+
+namespace android {
+namespace hardware {
+namespace audio {
+namespace CPP_VERSION {
+namespace implementation {
+
+using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+
+Device::Device(audio_hw_device_t* device) : mDevice(device) {}
+
+Device::~Device() {
+ int status = audio_hw_device_close(mDevice);
+ ALOGW_IF(status, "Error closing audio hw device %p: %s", mDevice, strerror(-status));
+ mDevice = nullptr;
+}
+
+Result Device::analyzeStatus(const char* funcName, int status,
+ const std::vector& ignoreErrors) {
+ return util::analyzeStatus("Device", funcName, status, ignoreErrors);
+}
+
+void Device::closeInputStream(audio_stream_in_t* stream) {
+ mDevice->close_input_stream(mDevice, stream);
+}
+
+void Device::closeOutputStream(audio_stream_out_t* stream) {
+ mDevice->close_output_stream(mDevice, stream);
+}
+
+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 Device::initCheck() {
+ return analyzeStatus("init_check", mDevice->init_check(mDevice));
+}
+
+Return Device::setMasterVolume(float volume) {
+ if (mDevice->set_master_volume == NULL) {
+ return Result::NOT_SUPPORTED;
+ }
+ if (!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));
+}
+
+Return 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));
+ }
+ _hidl_cb(retval, volume);
+ return Void();
+}
+
+Return Device::setMicMute(bool mute) {
+ return analyzeStatus("set_mic_mute", mDevice->set_mic_mute(mDevice, mute));
+}
+
+Return Device::getMicMute(getMicMute_cb _hidl_cb) {
+ bool mute = false;
+ Result retval = analyzeStatus("get_mic_mute", mDevice->get_mic_mute(mDevice, &mute));
+ _hidl_cb(retval, mute);
+ return Void();
+}
+
+Return 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));
+ }
+ return retval;
+}
+
+Return 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));
+ }
+ _hidl_cb(retval, mute);
+ return Void();
+}
+
+Return Device::getInputBufferSize(const AudioConfig& config, getInputBufferSize_cb _hidl_cb) {
+ audio_config_t halConfig;
+ HidlUtils::audioConfigToHal(config, &halConfig);
+ size_t halBufferSize = mDevice->get_input_buffer_size(mDevice, &halConfig);
+ Result retval(Result::INVALID_ARGUMENTS);
+ uint64_t bufferSize = 0;
+ if (halBufferSize != 0) {
+ retval = Result::OK;
+ bufferSize = halBufferSize;
+ }
+ _hidl_cb(retval, bufferSize);
+ return Void();
+}
+
+std::tuple> Device::openOutputStreamImpl(int32_t ioHandle,
+ const DeviceAddress& device,
+ const AudioConfig& config,
+ AudioOutputFlagBitfield flags,
+ AudioConfig* suggestedConfig) {
+ audio_config_t halConfig;
+ HidlUtils::audioConfigToHal(config, &halConfig);
+ audio_stream_out_t* halStream;
+ ALOGV(
+ "open_output_stream handle: %d devices: %x flags: %#x "
+ "srate: %d format %#x channels %x address %s",
+ ioHandle, static_cast(device.device),
+ static_cast(flags), halConfig.sample_rate, halConfig.format,
+ halConfig.channel_mask, deviceAddressToHal(device).c_str());
+ int status =
+ mDevice->open_output_stream(mDevice, ioHandle, static_cast(device.device),
+ static_cast(flags), &halConfig,
+ &halStream, deviceAddressToHal(device).c_str());
+ ALOGV("open_output_stream status %d stream %p", status, halStream);
+ sp streamOut;
+ if (status == OK) {
+ streamOut = new StreamOut(this, halStream);
+ }
+ HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
+ return {analyzeStatus("open_output_stream", status, {EINVAL} /*ignore*/), streamOut};
+}
+
+std::tuple> Device::openInputStreamImpl(
+ int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config,
+ AudioInputFlagBitfield flags, AudioSource source, AudioConfig* suggestedConfig) {
+ audio_config_t halConfig;
+ HidlUtils::audioConfigToHal(config, &halConfig);
+ audio_stream_in_t* halStream;
+ ALOGV(
+ "open_input_stream handle: %d devices: %x flags: %#x "
+ "srate: %d format %#x channels %x address %s source %d",
+ ioHandle, static_cast(device.device),
+ static_cast(flags), halConfig.sample_rate, halConfig.format,
+ halConfig.channel_mask, deviceAddressToHal(device).c_str(),
+ static_cast(source));
+ int status = mDevice->open_input_stream(
+ mDevice, ioHandle, static_cast(device.device), &halConfig, &halStream,
+ static_cast(flags), deviceAddressToHal(device).c_str(),
+ static_cast(source));
+ ALOGV("open_input_stream status %d stream %p", status, halStream);
+ sp streamIn;
+ if (status == OK) {
+ streamIn = new StreamIn(this, halStream);
+ }
+ HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
+ return {analyzeStatus("open_input_stream", status, {EINVAL} /*ignore*/), streamIn};
+}
+
+#if MAJOR_VERSION == 2
+Return Device::openOutputStream(int32_t ioHandle, const DeviceAddress& device,
+ const AudioConfig& config, AudioOutputFlagBitfield flags,
+ openOutputStream_cb _hidl_cb) {
+ AudioConfig suggestedConfig;
+ auto [result, streamOut] =
+ openOutputStreamImpl(ioHandle, device, config, flags, &suggestedConfig);
+ _hidl_cb(result, streamOut, suggestedConfig);
+ return Void();
+}
+
+Return Device::openInputStream(int32_t ioHandle, const DeviceAddress& device,
+ const AudioConfig& config, AudioInputFlagBitfield flags,
+ AudioSource source, openInputStream_cb _hidl_cb) {
+ AudioConfig suggestedConfig;
+ auto [result, streamIn] =
+ openInputStreamImpl(ioHandle, device, config, flags, source, &suggestedConfig);
+ _hidl_cb(result, streamIn, suggestedConfig);
+ return Void();
+}
+
+#elif MAJOR_VERSION >= 4
+Return Device::openOutputStream(int32_t ioHandle, const DeviceAddress& device,
+ const AudioConfig& config, AudioOutputFlagBitfield flags,
+ const SourceMetadata& sourceMetadata,
+ openOutputStream_cb _hidl_cb) {
+ AudioConfig suggestedConfig;
+ auto [result, streamOut] =
+ openOutputStreamImpl(ioHandle, device, config, flags, &suggestedConfig);
+ if (streamOut) {
+ streamOut->updateSourceMetadata(sourceMetadata);
+ }
+ _hidl_cb(result, streamOut, suggestedConfig);
+ return Void();
+}
+
+Return Device::openInputStream(int32_t ioHandle, const DeviceAddress& device,
+ const AudioConfig& config, AudioInputFlagBitfield flags,
+ const SinkMetadata& sinkMetadata,
+ openInputStream_cb _hidl_cb) {
+ 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");
+ _hidl_cb(Result::INVALID_ARGUMENTS, nullptr, AudioConfig());
+ return Void();
+ }
+ // Pick the first one as the main.
+ AudioSource source = sinkMetadata.tracks[0].source;
+ AudioConfig suggestedConfig;
+ auto [result, streamIn] =
+ openInputStreamImpl(ioHandle, device, config, flags, source, &suggestedConfig);
+ if (streamIn) {
+ streamIn->updateSinkMetadata(sinkMetadata);
+ }
+ _hidl_cb(result, streamIn, suggestedConfig);
+ return Void();
+}
+#endif /* MAJOR_VERSION */
+
+Return Device::supportsAudioPatches() {
+ return version() >= AUDIO_DEVICE_API_VERSION_3_0;
+}
+
+Return Device::createAudioPatch(const hidl_vec& sources,
+ const hidl_vec& sinks,
+ createAudioPatch_cb _hidl_cb) {
+ Result retval(Result::NOT_SUPPORTED);
+ AudioPatchHandle patch = 0;
+ if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
+ std::unique_ptr halSources(HidlUtils::audioPortConfigsToHal(sources));
+ std::unique_ptr halSinks(HidlUtils::audioPortConfigsToHal(sinks));
+ audio_patch_handle_t halPatch = AUDIO_PATCH_HANDLE_NONE;
+ 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(halPatch);
+ }
+ }
+ _hidl_cb(retval, patch);
+ return Void();
+}
+
+Return 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(patch)));
+ }
+ return Result::NOT_SUPPORTED;
+}
+
+Return Device::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) {
+ audio_port halPort;
+ HidlUtils::audioPortToHal(port, &halPort);
+ Result retval = analyzeStatus("get_audio_port", mDevice->get_audio_port(mDevice, &halPort));
+ AudioPort resultPort = port;
+ if (retval == Result::OK) {
+ HidlUtils::audioPortFromHal(halPort, &resultPort);
+ }
+ _hidl_cb(retval, resultPort);
+ return Void();
+}
+
+Return Device::setAudioPortConfig(const AudioPortConfig& config) {
+ if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
+ struct audio_port_config halPortConfig;
+ HidlUtils::audioPortConfigToHal(config, &halPortConfig);
+ return analyzeStatus("set_audio_port_config",
+ mDevice->set_audio_port_config(mDevice, &halPortConfig));
+ }
+ return Result::NOT_SUPPORTED;
+}
+
+#if MAJOR_VERSION == 2
+Return Device::getHwAvSync() {
+ int halHwAvSync;
+ Result retval = getParam(AudioParameter::keyHwAvSync, &halHwAvSync);
+ return retval == Result::OK ? halHwAvSync : AUDIO_HW_SYNC_INVALID;
+}
+#elif MAJOR_VERSION >= 4
+Return Device::getHwAvSync(getHwAvSync_cb _hidl_cb) {
+ int halHwAvSync;
+ Result retval = getParam(AudioParameter::keyHwAvSync, &halHwAvSync);
+ _hidl_cb(retval, halHwAvSync);
+ return Void();
+}
+#endif
+
+Return Device::setScreenState(bool turnedOn) {
+ return setParam(AudioParameter::keyScreenState, turnedOn);
+}
+
+#if MAJOR_VERSION == 2
+Return Device::getParameters(const hidl_vec& keys, getParameters_cb _hidl_cb) {
+ getParametersImpl({}, keys, _hidl_cb);
+ return Void();
+}
+
+Return Device::setParameters(const hidl_vec& parameters) {
+ return setParametersImpl({} /* context */, parameters);
+}
+#elif MAJOR_VERSION >= 4
+Return Device::getParameters(const hidl_vec& context,
+ const hidl_vec& keys, getParameters_cb _hidl_cb) {
+ getParametersImpl(context, keys, _hidl_cb);
+ return Void();
+}
+Return Device::setParameters(const hidl_vec& context,
+ const hidl_vec& parameters) {
+ return setParametersImpl(context, parameters);
+}
+#endif
+
+#if MAJOR_VERSION == 2
+Return Device::debugDump(const hidl_handle& fd) {
+ return debug(fd, {});
+}
+#endif
+
+Return Device::debug(const hidl_handle& fd, const hidl_vec& /* options */) {
+ if (fd.getNativeHandle() != nullptr && fd->numFds == 1) {
+ analyzeStatus("dump", mDevice->dump(mDevice, fd->data[0]));
+ }
+ return Void();
+}
+
+#if MAJOR_VERSION >= 4
+Return 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 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) {
+ halToMicrophoneCharacteristics(µphones[i], mic_array[i]);
+ }
+ retval = Result::OK;
+ }
+ _hidl_cb(retval, microphones);
+ return Void();
+}
+
+Return Device::setConnectedState(const DeviceAddress& address, bool connected) {
+ auto key = connected ? AudioParameter::keyStreamConnect : AudioParameter::keyStreamDisconnect;
+ return setParam(key, address);
+}
+#endif
+
+} // namespace implementation
+} // namespace CPP_VERSION
+} // namespace audio
+} // namespace hardware
+} // namespace android
diff --git a/configs/audio/impl/DevicesFactory.cpp b/configs/audio/impl/DevicesFactory.cpp
new file mode 100644
index 0000000..729f18c
--- /dev/null
+++ b/configs/audio/impl/DevicesFactory.cpp
@@ -0,0 +1,120 @@
+/*
+ * 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
+
+#include
+
+namespace android {
+namespace hardware {
+namespace audio {
+namespace CPP_VERSION {
+namespace implementation {
+
+#if MAJOR_VERSION == 2
+Return DevicesFactory::openDevice(IDevicesFactory::Device device, openDevice_cb _hidl_cb) {
+ switch (device) {
+ case IDevicesFactory::Device::PRIMARY:
+ return openDevice(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();
+}
+#elif MAJOR_VERSION >= 4
+Return DevicesFactory::openDevice(const hidl_string& moduleName, openDevice_cb _hidl_cb) {
+ if (moduleName == AUDIO_HARDWARE_MODULE_ID_PRIMARY) {
+ return openDevice(moduleName.c_str(), _hidl_cb);
+ }
+ return openDevice(moduleName.c_str(), _hidl_cb);
+}
+Return DevicesFactory::openPrimaryDevice(openPrimaryDevice_cb _hidl_cb) {
+ return openDevice(AUDIO_HARDWARE_MODULE_ID_PRIMARY, _hidl_cb);
+}
+#endif
+
+Return DevicesFactory::openDevice(const char* moduleName, openDevice_cb _hidl_cb) {
+ return openDevice(moduleName, _hidl_cb);
+}
+
+template
+Return DevicesFactory::openDevice(const char* moduleName, Callback _hidl_cb) {
+ audio_hw_device_t* halDevice;
+ Result retval(Result::INVALID_ARGUMENTS);
+ sp result;
+ int halStatus = loadAudioInterface(moduleName, &halDevice);
+ if (halStatus == OK) {
+ result = new DeviceShim(halDevice);
+ 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
diff --git a/configs/audio/impl/ParametersUtil.cpp b/configs/audio/impl/ParametersUtil.cpp
new file mode 100644
index 0000000..d49180b
--- /dev/null
+++ b/configs/audio/impl/ParametersUtil.cpp
@@ -0,0 +1,215 @@
+/*
+ * 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/Conversions.h"
+#include "core/default/Util.h"
+
+#include
+#include
+
+namespace android {
+namespace hardware {
+namespace audio {
+namespace CPP_VERSION {
+namespace implementation {
+
+constexpr int SLOT_POSITIONS_0[] = { 0, 1, 0, 1 };
+constexpr int SLOT_POSITIONS_90[] = { 1, 1, 0, 0 };
+constexpr int SLOT_POSITIONS_180[] = { 1, 0, 1, 0 };
+constexpr int SLOT_POSITIONS_270[] = { 0, 0, 1, 1 };
+
+void setMixerValueByName(mixer *mixer, const char *name, int value) {
+ const auto ctl = mixer_get_ctl_by_name(mixer, name);
+
+ if (ctl == nullptr) {
+ ALOGE("Failed to find mixer ctl for %s", name);
+ return;
+ }
+
+ if (mixer_ctl_set_value(ctl, 0, value) < 0) {
+ ALOGE("Failed to set ctl value %d for %s", value, name);
+ return;
+ }
+}
+
+void setSlotPositions(const int *values) {
+ const auto mixer = mixer_open(0);
+
+ if (mixer == nullptr) {
+ ALOGE("Failed to open mixer");
+ return;
+ }
+
+ setMixerValueByName(mixer, "FL ASPRX1 Slot Position", values[0]);
+ setMixerValueByName(mixer, "FR ASPRX1 Slot Position", values[1]);
+ setMixerValueByName(mixer, "RL ASPRX1 Slot Position", values[2]);
+ setMixerValueByName(mixer, "RR ASPRX1 Slot Position", values[3]);
+
+ mixer_close(mixer);
+};
+
+/** 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 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 params = getParams(context);
+ return getHalStatusToResult(params->get(halName, *value));
+}
+
+void ParametersUtil::getParametersImpl(
+ const hidl_vec& context, const hidl_vec& keys,
+ std::function& 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 halValues = getParams(halKeys);
+ Result retval =
+ (keys.size() == 0 || halValues->size() != 0) ? Result::OK : Result::NOT_SUPPORTED;
+ hidl_vec 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.string();
+ result[i].value = halValue.string();
+ }
+ cb(retval, result);
+}
+
+std::unique_ptr ParametersUtil::getParams(const AudioParameter& keys) {
+ String8 paramsAndValues;
+ char* halValues = halGetParameters(keys.keysToString().string());
+ if (halValues != NULL) {
+ paramsAndValues.setTo(halValues);
+ free(halValues);
+ } else {
+ paramsAndValues.clear();
+ }
+ return std::unique_ptr(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& context,
+ const hidl_vec& 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 == "rotation") {
+ if (parameters[i].value == "0") {
+ setSlotPositions(SLOT_POSITIONS_0);
+ } else if (parameters[i].value == "90") {
+ setSlotPositions(SLOT_POSITIONS_90);
+ } else if (parameters[i].value == "180") {
+ setSlotPositions(SLOT_POSITIONS_180);
+ } else if (parameters[i].value == "270") {
+ setSlotPositions(SLOT_POSITIONS_270);
+ }
+ continue;
+ }
+ 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) {
+ AudioParameter params(String8(deviceAddressToHal(address).c_str()));
+ params.addInt(String8(name), int(address.device));
+ return setParams(params);
+}
+
+Result ParametersUtil::setParams(const AudioParameter& param) {
+ int halStatus = halSetParameters(param.toString().string());
+ return util::analyzeStatus(halStatus);
+}
+
+} // namespace implementation
+} // namespace CPP_VERSION
+} // namespace audio
+} // namespace hardware
+} // namespace android
diff --git a/configs/audio/impl/PrimaryDevice.cpp b/configs/audio/impl/PrimaryDevice.cpp
new file mode 100644
index 0000000..b4fe200
--- /dev/null
+++ b/configs/audio/impl/PrimaryDevice.cpp
@@ -0,0 +1,326 @@
+/*
+ * 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
+#endif
+
+namespace android {
+namespace hardware {
+namespace audio {
+namespace CPP_VERSION {
+namespace implementation {
+
+PrimaryDevice::PrimaryDevice(audio_hw_device_t* device) : mDevice(new Device(device)) {}
+
+PrimaryDevice::~PrimaryDevice() {}
+
+// Methods from ::android::hardware::audio::CPP_VERSION::IDevice follow.
+Return PrimaryDevice::initCheck() {
+ return mDevice->initCheck();
+}
+
+Return PrimaryDevice::setMasterVolume(float volume) {
+ return mDevice->setMasterVolume(volume);
+}
+
+Return PrimaryDevice::getMasterVolume(getMasterVolume_cb _hidl_cb) {
+ return mDevice->getMasterVolume(_hidl_cb);
+}
+
+Return PrimaryDevice::setMicMute(bool mute) {
+ return mDevice->setMicMute(mute);
+}
+
+Return PrimaryDevice::getMicMute(getMicMute_cb _hidl_cb) {
+ return mDevice->getMicMute(_hidl_cb);
+}
+
+Return PrimaryDevice::setMasterMute(bool mute) {
+ return mDevice->setMasterMute(mute);
+}
+
+Return PrimaryDevice::getMasterMute(getMasterMute_cb _hidl_cb) {
+ return mDevice->getMasterMute(_hidl_cb);
+}
+
+Return PrimaryDevice::getInputBufferSize(const AudioConfig& config,
+ getInputBufferSize_cb _hidl_cb) {
+ return mDevice->getInputBufferSize(config, _hidl_cb);
+}
+
+#if MAJOR_VERSION == 2
+Return PrimaryDevice::openOutputStream(int32_t ioHandle, const DeviceAddress& device,
+ const AudioConfig& config,
+ AudioOutputFlagBitfield flags,
+ openOutputStream_cb _hidl_cb) {
+ return mDevice->openOutputStream(ioHandle, device, config, flags, _hidl_cb);
+}
+
+Return PrimaryDevice::openInputStream(int32_t ioHandle, const DeviceAddress& device,
+ const AudioConfig& config, AudioInputFlagBitfield flags,
+ AudioSource source, openInputStream_cb _hidl_cb) {
+ return mDevice->openInputStream(ioHandle, device, config, flags, source, _hidl_cb);
+}
+#elif MAJOR_VERSION >= 4
+Return PrimaryDevice::openOutputStream(int32_t ioHandle, const DeviceAddress& device,
+ const AudioConfig& config,
+ AudioOutputFlagBitfield flags,
+ const SourceMetadata& sourceMetadata,
+ openOutputStream_cb _hidl_cb) {
+ return mDevice->openOutputStream(ioHandle, device, config, flags, sourceMetadata, _hidl_cb);
+}
+
+Return PrimaryDevice::openInputStream(int32_t ioHandle, const DeviceAddress& device,
+ const AudioConfig& config, AudioInputFlagBitfield flags,
+ const SinkMetadata& sinkMetadata,
+ openInputStream_cb _hidl_cb) {
+ return mDevice->openInputStream(ioHandle, device, config, flags, sinkMetadata, _hidl_cb);
+}
+#endif
+
+Return PrimaryDevice::supportsAudioPatches() {
+ return mDevice->supportsAudioPatches();
+}
+
+Return PrimaryDevice::createAudioPatch(const hidl_vec& sources,
+ const hidl_vec& sinks,
+ createAudioPatch_cb _hidl_cb) {
+ return mDevice->createAudioPatch(sources, sinks, _hidl_cb);
+}
+
+Return PrimaryDevice::releaseAudioPatch(int32_t patch) {
+ return mDevice->releaseAudioPatch(patch);
+}
+
+Return PrimaryDevice::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) {
+ return mDevice->getAudioPort(port, _hidl_cb);
+}
+
+Return PrimaryDevice::setAudioPortConfig(const AudioPortConfig& config) {
+ return mDevice->setAudioPortConfig(config);
+}
+
+Return PrimaryDevice::setScreenState(bool turnedOn) {
+ return mDevice->setScreenState(turnedOn);
+}
+
+#if MAJOR_VERSION == 2
+Return PrimaryDevice::getHwAvSync() {
+ return mDevice->getHwAvSync();
+}
+
+Return PrimaryDevice::getParameters(const hidl_vec& keys,
+ getParameters_cb _hidl_cb) {
+ return mDevice->getParameters(keys, _hidl_cb);
+}
+
+Return PrimaryDevice::setParameters(const hidl_vec& parameters) {
+ return mDevice->setParameters(parameters);
+}
+
+Return PrimaryDevice::debugDump(const hidl_handle& fd) {
+ return mDevice->debugDump(fd);
+}
+#elif MAJOR_VERSION >= 4
+Return PrimaryDevice::getHwAvSync(getHwAvSync_cb _hidl_cb) {
+ return mDevice->getHwAvSync(_hidl_cb);
+}
+Return PrimaryDevice::getParameters(const hidl_vec& context,
+ const hidl_vec& keys,
+ getParameters_cb _hidl_cb) {
+ return mDevice->getParameters(context, keys, _hidl_cb);
+}
+Return PrimaryDevice::setParameters(const hidl_vec& context,
+ const hidl_vec& parameters) {
+ return mDevice->setParameters(context, parameters);
+}
+Return PrimaryDevice::getMicrophones(getMicrophones_cb _hidl_cb) {
+ return mDevice->getMicrophones(_hidl_cb);
+}
+Return PrimaryDevice::setConnectedState(const DeviceAddress& address, bool connected) {
+ return mDevice->setConnectedState(address, connected);
+}
+#endif
+
+// Methods from ::android::hardware::audio::CPP_VERSION::IPrimaryDevice follow.
+Return PrimaryDevice::setVoiceVolume(float volume) {
+ if (!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 PrimaryDevice::setMode(AudioMode mode) {
+ // On regular QCOM devices, these parameters are set by QtiTelephonyService,
+ // which basically listens to vendor.qti.hardware.radio.am callbacks.
+ // The hardcoded vsid value here is decimal VOICEMMODE1_VSID which one can find
+ // in {QC_AUDIO_HAL}/hal/voice_extn/voice_extn.c. The current code doesn't
+ // handle VOICEMMODE2_VSID, but since we don't have any MSIM variants it's totally fine.
+ // Audio param call_state 2 corresponds to CALL_ACTIVE and 1 to CALL_INACTIVE respectively,
+ // both of which can be found in {QC_AUDIO_HAL}/hal/voice.h.
+ mDevice->halSetParameters(mode == AudioMode::IN_CALL ? "call_state=2;vsid=297816064"
+ : "call_state=1;vsid=297816064");
+
+ // 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:
+ break; // Valid values
+ default:
+ return Result::INVALID_ARGUMENTS;
+ };
+
+ return mDevice->analyzeStatus(
+ "set_mode",
+ mDevice->device()->set_mode(mDevice->device(), static_cast(mode)));
+}
+
+Return PrimaryDevice::getBtScoNrecEnabled(getBtScoNrecEnabled_cb _hidl_cb) {
+ bool enabled;
+ Result retval = mDevice->getParam(AudioParameter::keyBtNrec, &enabled);
+ _hidl_cb(retval, enabled);
+ return Void();
+}
+
+Return PrimaryDevice::setBtScoNrecEnabled(bool enabled) {
+ return mDevice->setParam(AudioParameter::keyBtNrec, enabled);
+}
+
+Return 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 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 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);
+ 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 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 PrimaryDevice::getHacEnabled(getHacEnabled_cb _hidl_cb) {
+ bool enabled;
+ Result retval = mDevice->getParam(AUDIO_PARAMETER_KEY_HAC, &enabled);
+ _hidl_cb(retval, enabled);
+ return Void();
+}
+
+Return PrimaryDevice::setHacEnabled(bool enabled) {
+ return mDevice->setParam(AUDIO_PARAMETER_KEY_HAC, enabled);
+}
+
+#if MAJOR_VERSION >= 4
+Return PrimaryDevice::setBtScoHeadsetDebugName(const hidl_string& name) {
+ return mDevice->setParam(AUDIO_PARAMETER_KEY_BT_SCO_HEADSET_NAME, name.c_str());
+}
+Return 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 PrimaryDevice::setBtHfpEnabled(bool enabled) {
+ return mDevice->setParam(AUDIO_PARAMETER_KEY_HFP_ENABLE, enabled);
+}
+Return PrimaryDevice::setBtHfpSampleRate(uint32_t sampleRateHz) {
+ return mDevice->setParam(AUDIO_PARAMETER_KEY_HFP_SET_SAMPLING_RATE, int(sampleRateHz));
+}
+Return PrimaryDevice::setBtHfpVolume(float volume) {
+ if (!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(std::round(volume * 15)));
+}
+Return PrimaryDevice::updateRotation(IPrimaryDevice::Rotation rotation) {
+ // legacy API expects the rotation in degree
+ return mDevice->setParam(AUDIO_PARAMETER_KEY_ROTATION, int(rotation) * 90);
+}
+#endif
+
+Return PrimaryDevice::debug(const hidl_handle& fd, const hidl_vec& options) {
+ return mDevice->debug(fd, options);
+}
+
+} // namespace implementation
+} // namespace CPP_VERSION
+} // namespace audio
+} // namespace hardware
+} // namespace android
diff --git a/configs/audio/impl/Stream.cpp b/configs/audio/impl/Stream.cpp
new file mode 100644
index 0000000..b995657
--- /dev/null
+++ b/configs/audio/impl/Stream.cpp
@@ -0,0 +1,331 @@
+/*
+ * 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/default/EffectMap.h"
+#include "core/default/Conversions.h"
+#include "core/default/Util.h"
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace android {
+namespace hardware {
+namespace audio {
+namespace CPP_VERSION {
+namespace implementation {
+
+Stream::Stream(audio_stream_t* stream) : mStream(stream) {}
+
+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& 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 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 Stream::getFrameCount() {
+ int halFrameCount;
+ Result retval = getParam(AudioParameter::keyFrameCount, &halFrameCount);
+ return retval == Result::OK ? halFrameCount : 0;
+}
+
+Return Stream::getBufferSize() {
+ return mStream->get_buffer_size(mStream);
+}
+
+Return Stream::getSampleRate() {
+ return mStream->get_sample_rate(mStream);
+}
+
+#if MAJOR_VERSION == 2
+Return Stream::getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) {
+ return getSupportedSampleRates(getFormat(), _hidl_cb);
+}
+Return Stream::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) {
+ return getSupportedChannelMasks(getFormat(), _hidl_cb);
+}
+#endif
+
+Return 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 sampleRates;
+ SortedVector halSampleRates;
+ if (result == Result::OK) {
+ halSampleRates =
+ samplingRatesFromString(halListValue.string(), AudioParameter::valueListSeparator);
+ sampleRates.setToExternal(halSampleRates.editArray(), halSampleRates.size());
+ // 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 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 channelMasks;
+ SortedVector halChannelMasks;
+ if (result == Result::OK) {
+ halChannelMasks =
+ channelMasksFromString(halListValue.string(), AudioParameter::valueListSeparator);
+ channelMasks.resize(halChannelMasks.size());
+ for (size_t i = 0; i < halChannelMasks.size(); ++i) {
+ channelMasks[i] = AudioChannelBitfield(halChannelMasks[i]);
+ }
+ // 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 Stream::setSampleRate(uint32_t sampleRateHz) {
+ return setParam(AudioParameter::keySamplingRate, static_cast(sampleRateHz));
+}
+
+Return Stream::getChannelMask() {
+ return AudioChannelBitfield(mStream->get_channels(mStream));
+}
+
+Return Stream::setChannelMask(AudioChannelBitfield mask) {
+ return setParam(AudioParameter::keyChannels, static_cast(mask));
+}
+
+Return Stream::getFormat() {
+ return AudioFormat(mStream->get_format(mStream));
+}
+
+Return Stream::getSupportedFormats(getSupportedFormats_cb _hidl_cb) {
+ String8 halListValue;
+ Result result = getParam(AudioParameter::keyStreamSupportedFormats, &halListValue);
+ hidl_vec formats;
+ Vector halFormats;
+ if (result == Result::OK) {
+ halFormats = formatsFromString(halListValue.string(), AudioParameter::valueListSeparator);
+ formats.resize(halFormats.size());
+ for (size_t i = 0; i < halFormats.size(); ++i) {
+ formats[i] = AudioFormat(halFormats[i]);
+ }
+ }
+ _hidl_cb(formats);
+ return Void();
+}
+
+Return Stream::setFormat(AudioFormat format) {
+ return setParam(AudioParameter::keyFormat, static_cast(format));
+}
+
+Return 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();
+}
+
+Return 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 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 Stream::standby() {
+ return analyzeStatus("standby", mStream->standby(mStream));
+}
+
+Return Stream::setHwAvSync(uint32_t hwAvSync) {
+ return setParam(AudioParameter::keyStreamHwAvSync, static_cast(hwAvSync));
+}
+
+#if MAJOR_VERSION == 2
+Return Stream::getDevice() {
+ int device = 0;
+ Result retval = getParam(AudioParameter::keyRouting, &device);
+ return retval == Result::OK ? static_cast(device) : AudioDevice::NONE;
+}
+
+Return Stream::setDevice(const DeviceAddress& address) {
+ return setParam(AudioParameter::keyRouting, address);
+}
+
+Return Stream::getParameters(const hidl_vec& keys, getParameters_cb _hidl_cb) {
+ getParametersImpl({} /* context */, keys, _hidl_cb);
+ return Void();
+}
+
+Return Stream::setParameters(const hidl_vec& parameters) {
+ return setParametersImpl({} /* context */, parameters);
+}
+
+Return Stream::setConnectedState(const DeviceAddress& address, bool connected) {
+ return setParam(
+ connected ? AudioParameter::keyStreamConnect : AudioParameter::keyStreamDisconnect,
+ address);
+}
+#elif MAJOR_VERSION >= 4
+Return Stream::getDevices(getDevices_cb _hidl_cb) {
+ int device = 0;
+ Result retval = getParam(AudioParameter::keyRouting, &device);
+ hidl_vec devices;
+ if (retval == Result::OK) {
+ devices.resize(1);
+ devices[0].device = static_cast(device);
+ }
+ _hidl_cb(retval, devices);
+ return Void();
+}
+
+Return Stream::setDevices(const hidl_vec& 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];
+ } else {
+ address.device = AudioDevice::NONE;
+ }
+ return setParam(AudioParameter::keyRouting, address);
+}
+Return Stream::getParameters(const hidl_vec& context,
+ const hidl_vec& keys, getParameters_cb _hidl_cb) {
+ getParametersImpl(context, keys, _hidl_cb);
+ return Void();
+}
+
+Return Stream::setParameters(const hidl_vec& context,
+ const hidl_vec& parameters) {
+ return setParametersImpl(context, parameters);
+}
+#endif
+
+Return Stream::start() {
+ return Result::NOT_SUPPORTED;
+}
+
+Return Stream::stop() {
+ return Result::NOT_SUPPORTED;
+}
+
+Return Stream::createMmapBuffer(int32_t minSizeFrames __unused,
+ createMmapBuffer_cb _hidl_cb) {
+ Result retval(Result::NOT_SUPPORTED);
+ MmapBufferInfo info;
+ _hidl_cb(retval, info);
+ return Void();
+}
+
+Return Stream::getMmapPosition(getMmapPosition_cb _hidl_cb) {
+ Result retval(Result::NOT_SUPPORTED);
+ MmapPosition position;
+ _hidl_cb(retval, position);
+ return Void();
+}
+
+Return Stream::close() {
+ return Result::NOT_SUPPORTED;
+}
+
+Return Stream::debug(const hidl_handle& fd, const hidl_vec& /* options */) {
+ if (fd.getNativeHandle() != nullptr && fd->numFds == 1) {
+ analyzeStatus("dump", mStream->dump(mStream, fd->data[0]));
+ }
+ return Void();
+}
+
+#if MAJOR_VERSION == 2
+Return Stream::debugDump(const hidl_handle& fd) {
+ return debug(fd, {} /* options */);
+}
+#endif
+
+} // namespace implementation
+} // namespace CPP_VERSION
+} // namespace audio
+} // namespace hardware
+} // namespace android
diff --git a/configs/audio/impl/StreamIn.cpp b/configs/audio/impl/StreamIn.cpp
new file mode 100644
index 0000000..d316f83
--- /dev/null
+++ b/configs/audio/impl/StreamIn.cpp
@@ -0,0 +1,534 @@
+/*
+ * 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/Conversions.h"
+#include "core/default/Util.h"
+#include "common/all-versions/HidlSupport.h"
+
+//#define LOG_NDEBUG 0
+#define ATRACE_TAG ATRACE_TAG_AUDIO
+
+#include
+#include
+#include
+#include
+#include
+
+namespace android {
+namespace hardware {
+namespace audio {
+namespace CPP_VERSION {
+namespace implementation {
+
+namespace {
+
+class ReadThread : public Thread {
+ public:
+ // ReadThread's lifespan never exceeds StreamIn's lifespan.
+ ReadThread(std::atomic* 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* mStop;
+ audio_stream_in_t* mStream;
+ StreamIn::CommandMQ* mCommandMQ;
+ StreamIn::DataMQ* mDataMQ;
+ StreamIn::StatusMQ* mStatusMQ;
+ EventFlag* mEfGroup;
+ std::unique_ptr 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(MessageQueueFlagBits::NOT_FULL), &efState);
+ if (!(efState & static_cast(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(MessageQueueFlagBits::NOT_EMPTY));
+ }
+
+ return false;
+}
+
+} // namespace
+
+StreamIn::StreamIn(const sp& device, audio_stream_in_t* stream)
+ : mIsClosed(false),
+ mDevice(device),
+ mStream(stream),
+ mStreamCommon(new Stream(&stream->common)),
+ mStreamMmap(new StreamMmap(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));
+ }
+ mDevice->closeInputStream(mStream);
+ mStream = nullptr;
+}
+
+// Methods from ::android::hardware::audio::CPP_VERSION::IStream follow.
+Return StreamIn::getFrameSize() {
+ return audio_stream_in_frame_size(mStream);
+}
+
+Return StreamIn::getFrameCount() {
+ return mStreamCommon->getFrameCount();
+}
+
+Return StreamIn::getBufferSize() {
+ return mStreamCommon->getBufferSize();
+}
+
+Return StreamIn::getSampleRate() {
+ return mStreamCommon->getSampleRate();
+}
+
+#if MAJOR_VERSION == 2
+Return StreamIn::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) {
+ return mStreamCommon->getSupportedChannelMasks(_hidl_cb);
+}
+Return StreamIn::getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) {
+ return mStreamCommon->getSupportedSampleRates(_hidl_cb);
+}
+#endif
+
+Return StreamIn::getSupportedChannelMasks(AudioFormat format,
+ getSupportedChannelMasks_cb _hidl_cb) {
+ return mStreamCommon->getSupportedChannelMasks(format, _hidl_cb);
+}
+Return StreamIn::getSupportedSampleRates(AudioFormat format,
+ getSupportedSampleRates_cb _hidl_cb) {
+ return mStreamCommon->getSupportedSampleRates(format, _hidl_cb);
+}
+
+Return StreamIn::setSampleRate(uint32_t sampleRateHz) {
+ return mStreamCommon->setSampleRate(sampleRateHz);
+}
+
+Return StreamIn::getChannelMask() {
+ return mStreamCommon->getChannelMask();
+}
+
+Return StreamIn::setChannelMask(AudioChannelBitfield mask) {
+ return mStreamCommon->setChannelMask(mask);
+}
+
+Return StreamIn::getFormat() {
+ return mStreamCommon->getFormat();
+}
+
+Return StreamIn::getSupportedFormats(getSupportedFormats_cb _hidl_cb) {
+ return mStreamCommon->getSupportedFormats(_hidl_cb);
+}
+
+Return StreamIn::setFormat(AudioFormat format) {
+ return mStreamCommon->setFormat(format);
+}
+
+Return StreamIn::getAudioProperties(getAudioProperties_cb _hidl_cb) {
+ return mStreamCommon->getAudioProperties(_hidl_cb);
+}
+
+Return StreamIn::addEffect(uint64_t effectId) {
+ return mStreamCommon->addEffect(effectId);
+}
+
+Return StreamIn::removeEffect(uint64_t effectId) {
+ return mStreamCommon->removeEffect(effectId);
+}
+
+Return StreamIn::standby() {
+ return mStreamCommon->standby();
+}
+
+Return StreamIn::setHwAvSync(uint32_t hwAvSync) {
+ return mStreamCommon->setHwAvSync(hwAvSync);
+}
+
+#if MAJOR_VERSION == 2
+Return StreamIn::setConnectedState(const DeviceAddress& address, bool connected) {
+ return mStreamCommon->setConnectedState(address, connected);
+}
+
+Return StreamIn::getDevice() {
+ return mStreamCommon->getDevice();
+}
+
+Return StreamIn::setDevice(const DeviceAddress& address) {
+ return mStreamCommon->setDevice(address);
+}
+
+Return StreamIn::getParameters(const hidl_vec& keys, getParameters_cb _hidl_cb) {
+ return mStreamCommon->getParameters(keys, _hidl_cb);
+}
+
+Return StreamIn::setParameters(const hidl_vec& parameters) {
+ return mStreamCommon->setParameters(parameters);
+}
+
+Return StreamIn::debugDump(const hidl_handle& fd) {
+ return mStreamCommon->debugDump(fd);
+}
+#elif MAJOR_VERSION >= 4
+Return StreamIn::getDevices(getDevices_cb _hidl_cb) {
+ return mStreamCommon->getDevices(_hidl_cb);
+}
+
+Return StreamIn::setDevices(const hidl_vec& devices) {
+ return mStreamCommon->setDevices(devices);
+}
+Return